您的位置:首页 > 其它

读取外部程序的标题和内容(转)

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
                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐