读取外部程序的标题和内容(转)
2012-03-21 16:56
190 查看
http://www.cnblogs.com/findumars/archive/2011/11/05/2236944.html
很好很强到,所以转了
Delphi 为我们提供了三个方便的函数:
GlobalAllocPtr {简化自 API 的 GlobalAlloc} GlobalReAllocPtr {简化自 API 的 GlobalReAlloc} GlobalFreePtr {简化自 API 的 GlobalFree}
读写本程序以外的数据时可以使用它们, 很方便, 譬如:
p := GlobalAllocPtr(0, Len); {分配} p := GlobalReAllocPtr(p, Len, 0); {重分配} GlobalFreePtr(p); {释放}
注意 GlobalAllocPtr 的第一个参数和 GlobalReAllocPtr 的最后一个参数, 上面给的都是 0; 这两个参数的意义是一样的, 规范一点应该写成 GMEM_FIXED (表示分配固定内存), 常用的参数还有:
GMEM_MOVEABLE {分配可移动内存} GMEM_ZEROINIT {同时清空内存} GHND {分配可移动内存同时清空} GPTR {分配固定内存同时清空}
procedure TForm1.Button2Click(Sender: TObject); var p: Pointer; Len: Integer; begin Len := 6+1; {假如想要读出 6 个字符, 要流出结束的空字符} p := GlobalAllocPtr(0, Len*2); {分配内存 Len*2 是针对双字节字符} SendMessage(Memo1.Handle, WM_GETTEXT, Len, Cardinal(p)); ShowMessage(PChar(p)); {CodeGe} {在上一例的基础上继续, 先获取实际长度} Len := SendMessage(Memo1.Handle, WM_GETTEXTLENGTH, 0, 0); Len := (Len + 1) * 2; p := GlobalReAllocPtr(p, Len, GHND); {重新分配内存} SendMessage(Memo1.Handle, WM_GETTEXT, Len, Cardinal(p)); ShowMessage(PChar(p)); {CodeGear Delphi 2009}
GlobalFreePtr(p); end;
{获取已打开的所有记事本的标题} procedure TForm1.Button1Click(Sender: TObject); var h: HWnd; p: array[0..254] of char; begin Memo1.Clear; h := GetWindow(Handle, GW_HWNDFIRST); while h <> 0 do begin GetClassName(h, p, Length(p)); if p = 'Notepad' then begin GetWindowText(h, p, Length(p)); Memo1.Lines.Add(p); end; h := GetWindow(h, GW_HWNDNEXT); end; end;
--------------- 读取记事本的标题 ---------------------------------- procedure TForm1.Button1Click(Sender: TObject); var p: Pointer; Len: Integer; h:hwnd; begin h:=findwindow('notepad',nil); Len := 6+1; {假如想要读出 6 个字符, 要留出结束的空字符} p := GlobalAllocPtr(0, Len*2); {分配内存 Len*2 是针对双字节字符} SendMessage(h, WM_GETTEXT, Len, Cardinal(p)); ShowMessage(PChar(p)); {CodeGe} GlobalFreePtr(p); end;
--------------- 读取记事本的内容 ----------------------------------procedure TForm1.Button1Click(Sender: TObject);
var h: HWND; p: Pointer; Len: Integer; begin h := FindWindow('Notepad', nil); if h = 0 then Exit; h := GetWindow(h, GW_CHILD); if h = 0 then Exit; Len := SendMessage(h, WM_GETTEXTLENGTH, 0, 0) + 1; p := GlobalAllocPtr(0, Len * SizeOf(Char)); SendMessage(h, WM_GETTEXT, Len, Cardinal(p)); ShowMessage(PChar(p)); GlobalFreePtr(p); end;
WinAPI: GetWindow - 获取与指定窗口具有指定关系的窗口的句柄
//声明: GetWindow( hWnd: HWND; {指定的窗口句柄} uCmd: UINT {指定的关系选项} ): HWND; {失败返回0; 成功返回符合的窗口句柄} //uCmd 可选值: GW_HWNDFIRST = 0; {同级别第一个} GW_HWNDLAST = 1; {同级别最后一个} GW_HWNDNEXT = 2; {同级别下一个} GW_HWNDPREV = 3; {同级别上一个} GW_OWNER = 4; {属主窗口} GW_CHILD = 5; {子窗口}
枚举当前所有窗口
{要有个 Memo 接受数据} procedure TForm1.Button1Click(Sender: TObject); var h: HWnd; p: array[0..254] of char; begin h := GetWindow(Handle, GW_HWNDFIRST); while h <> 0 do begin if GetWindowText(h, p, 255) > 0 then Memo1.Lines.Add(p); h := GetWindow(h, GW_HWNDNEXT); end; end;
{用 API 实现的获取文本容器中选择的文本的函数}function GetEditSeleteText(h: HWND): string;varlen,sx,ex: Integer; {文本总长度, 选择的开始位置, 选择的结束位置}buf: PChar; {所有文本}begin{获取文本总长度}len := SendMessage(h, WM_GETTEXTLENGTH, 0, 0) + 1;{为接受所有文本的缓冲区分配内存}buf := GlobalAllocPtr(0, len); {这里没有使用 GetMem, 因为需要全局的, 不然无法面对其他程序}{获取所有文本}SendMessage(h, WM_GETTEXT, len, Longint(buf));{获取选择的开始位置和结束位置}SendMessage(h, EM_GETSEL, Longint(@sx), Longint(@ex));{截取选择的文本}Result := Copy(buf, sx+1, ex-sx);{释放内存}GlobalFreePtr(buf);end;{测试 TEdit, 同时与 VCL 的获取方法对比}procedure TForm1.Button1Click(Sender: TObject);beginShowMessage(GetEditSeleteText(Edit1.Handle) + ' - ' + Edit1.SelText);end;
WinAPI: WindowFromPoint- 获取指定点所在窗口的句柄
varh: HWND;procedure TForm1.Timer1Timer(Sender: TObject);varpt: TPoint;arr: array[0..254] of Char;beginif GetCursorPos(pt) then {如果能获取点}beginh := WindowFromPoint(pt); {返回句柄}GetClassName(h, arr, Length(arr)); {获取该句柄窗口的类名}Text := arr; {显示在标题}end;end;end.
WinAPI: GetClassName - 获取指定窗口的类名
//声明:GetClassName(hWnd: HWND; {指定窗口句柄}lpClassName: PChar; {缓冲区}nMaxCount: Integer {缓冲区大小}): Integer; {返回类名大小; 失败返回 0}
//测试1: 新建一个工程, 主窗口的类名默认是 TForm1, 用程序获取一下看看varps: array[0..254] of Char;beginGetClassName(Handle, ps, 255);ShowMessage(ps); {TForm1}end;
//测试2: 看看 "计算器" 窗口的类名(先启动计算器)varh: HWND;ps: array[0..254] of Char;beginh := FindWindow(nil, '计算器'); {这句是获取计算器窗口的句柄}GetClassName(h, ps, 255);ShowMessage(ps); {SciCalc}end;
//测试3: 看看记事本窗口的类名(先重新启动记事本):varh: HWND;ps: array[0..254] of Char;beginh := FindWindow(nil, '无标题 - 记事本'); {这句是获取记事本窗口的句柄}GetClassName(h, ps, 255);ShowMessage(ps); {Notepad}end;
WinAPI: FindWindow、FindWindowEx - 查找窗口
FindWindow(lpClassName, {窗口的类名}lpWindowName: PChar {窗口的标题}): HWND; {返回窗口的句柄; 失败返回 0}//FindWindowEx 比 FindWindow 多出两个句柄参数:FindWindowEx(Parent: HWND; {要查找子窗口的父窗口句柄}Child: HWND; {子窗口句柄}ClassName: PChar; {}WindowName: PChar {}): HWND;{如果 Parent 是 0, 则函数以桌面窗口为父窗口, 查找桌面窗口的所有子窗口;如果 是 HWND_MESSAGE, 函数仅查找所有消息窗口;子窗口必须是 Parent 窗口的直接子窗口;如果 Child 是 0, 查找从 Parent 的第一个子窗口开始;如果 Parent 和 Child 同时是 0, 则函数查找所有的顶层窗口及消息窗口.}
//测试1: 试着找找新建程序主窗口的句柄varh: HWND;begin{现在我们知道窗口的标题是: Form1、窗口的类名是: TForm1}h := FindWindow('TForm1', 'Form1');ShowMessage(IntToStr(h)); {656180; 这是随机, 每次启动窗口肯定不一样}{假如不知道类名}h := FindWindow(nil, 'Form1');ShowMessage(IntToStr(h)); {656180}{假如不知道标题名}h := FindWindow('TForm1', nil);ShowMessage(IntToStr(h)); {656180}{其实这个窗口的句柄不就是 Self.Handle 吗}ShowMessage(IntToStr(Handle)); {656180}end;
//测试2: 找计算器窗口的句柄(先打开计算器)varh: HWND;begin{如果不是简体中文系统, 这样可能不灵}h := FindWindow(nil, '计算器');ShowMessage(IntToStr(h)); {1508334}{最好这样, 但你得提前知道计算器窗口的类名是: SciCalc}h := FindWindow('SciCalc', nil);ShowMessage(IntToStr(h)); {1508334}end;
procedure TForm1.Button1Click(Sender: TObject);constclassName = 'IEFrame'; {这是 IE 浏览器的类名}varh: HWnd;buf: array[Byte] of Char;beginh := GetWindow(Handle, GW_HWNDFIRST);while h <> 0 dobeginGetClassName(h, buf, Length(buf));if buf = className then {找到咋处理? 显示它的标题吧}beginGetWindowText(h, buf, Length(buf));Memo1.Lines.Add(buf)end;h := GetWindow(h, GW_HWNDNEXT);end;end;
枚举当前所有的 IE 窗口
procedure TForm1.Button1Click(Sender: TObject);constclassName = 'IEFrame'; {这是 IE 浏览器的类名}varh: HWnd;buf: array[Byte] of Char;beginh := GetWindow(Handle, GW_HWNDFIRST);while h <> 0 dobeginGetClassName(h, buf, Length(buf));if buf = className then {找到咋处理? 显示它的标题吧}beginGetWindowText(h, buf, Length(buf));Memo1.Lines.Add(buf)end;h := GetWindow(h, GW_HWNDNEXT);end;end;如果有个按钮,是disabled那种效果,就是灰掉,不能点的那种,怎么获取这样按钮句柄呢?可以从母体中遍历控件找到它.如果是使用鼠标探测的话, 可以通过判断鼠标指针是否在控件范围内来确认.怎么判断鼠标指针是否在控件范围内?可以通过控件的事件:OnMouseEnter (进入控件范围)OnMouseLeave (离开控件范围)也可以用函数: PtInRect
相关文章推荐
- 关于MFC读取外部程序的ListControl内容
- 外部程序关联我们的app,打开并读取txt内容
- 读取excel标题、内容
- Java 读取xml文件内容程序小结
- CGI程序学习(3)-CGI程序中读取文本内容后显示在浏览器上
- mfc根据句柄获得外部程序标题类
- 002_010 Python 处理字符串中的Zip文件 你的程序收到了一个字符串,内容是一个ZIP文件,需要读取zip文件的信息
- 编写IoDemo.java的Java应用程序,程序完成的功能是:首先读取text.txt文件内容,再通过键盘输入文件的名称为iodemo.txt,把text.txt的内容存入iodemo.txt
- 程序读取Excel,单元格内容超过255被截断解决方法
- 编写一个程序,首先用opendir函数打开用户指定的目录,然后调用readdir函数读取该目录内容
- 编写一个程序,从标准输入一行一行地读取文本,并完成如下任务:如果文件中有两行或更多行相邻的文本内容相同,那么就打印其中一行,其余行不打印。
- 使用PropertyPlaceholderConfigurer类读取外部属性文件内容到XML
- jar包读取资源、引用外部JAR包后打包、制作可执行程序
- 大三软件工程小项目-小技术集合-读取XML文件及运行外部程序
- VC程序读取配置文件内容
- spark streaming 的wordcount程序,从hdfs上读取文件中的内容并计数
- java 读取文件,内容方置Person 序列化到磁盘,在读入程序并写到另外地址
- java程序读取文件内容打印控制台
- 例子程序1:读取文件内容并打印到屏幕上
- Spring读取外部的.properties文件内容并设置给bean的两种方法