本文整理自网络,侵删。
// EnumWindows 的功能是遍历所有顶层窗口function EnumWindows( lpEnumFunc: TFNWndEnumProc; {回调函数指针} lParam: LPARAM {给回调函数的参数, 它对应回调函数的第二个参数}): BOOL; stdcall; //成功与否, 其实是返回了回调函数的返回值
// EnumWindows 专用的回调函数的格式:function EnumWindowsProc( hwnd: HWND; {找到的窗口句柄} lParam: LPARAM {EnumWindows 传给的参数; 因为它是指针, 可传入, 但一般用作传出数据}): Boolean; stdcall; {函数返回 False 时, 调用它的 EnumWindows 将停止遍历并返回 False}
例一: 获取所有顶层窗口的句柄
//需要个 TListBox 显示数据function EnumWindowsProc_1(hwnd: HWND; lParam: LPARAM): Boolean; stdcall;begin Form1.ListBox1.Items.Add(IntToStr(hwnd)); Result := True;end;
procedure TForm1.Button1Click(Sender: TObject);begin EnumWindows(@EnumWindowsProc_1, 0);end;
例二: 获取所有顶层窗口的标题(排除无标题窗口)
function EnumWindowsProc_2(hwnd: HWND; lParam: LPARAM): Boolean; stdcall;var buf: array[Byte] of Char;begin GetWindowText(hwnd, buf, SizeOf(buf)); if buf <> '' then Form1.ListBox1.Items.Add(buf); Result := True;end;
procedure TForm1.Button1Click(Sender: TObject);begin EnumWindows(@EnumWindowsProc_2, 0);end;
例三: 查找第一个记事本的句柄
function EnumWindowsProc_3(hwnd: HWND; lParam: LPARAM): Boolean; stdcall;var buf: array[Byte] of Char;begin GetClassName(hwnd, buf, SizeOf(buf)); if buf = 'Notepad' then begin Form1.ListBox1.Items.Add(Format('记事本句柄: %d', [hwnd])); Result := False; //如果不需要继续找, 找到第一个就结束 end else begin Result := True; end;end;
procedure TForm1.Button1Click(Sender: TObject);begin EnumWindows(@EnumWindowsProc_3, 0);end;
例四: 获取所有顶层窗口的句柄与类名数组:
type TMyStruct = record hwnd: HWND; ClassName: string; end; TMyStructArray = array of TMyStruct; PMyStructArray = ^TMyStructArray;
function EnumWindowsProc_4(hwnd: HWND; lParam: LPARAM): Boolean; stdcall;var buf: array[Byte] of Char; p: PMyStructArray;begin GetClassName(hwnd, buf, SizeOf(buf)); p := PMyStructArray(lParam); SetLength(p^, Length(p^) + 1); p^[High(p^)].hwnd := hwnd; p^[High(p^)].ClassName := buf; Result := True;end;
procedure TForm1.Button1Click(Sender: TObject);var Arr: TMyStructArray;begin EnumWindows(@EnumWindowsProc_4, Integer(@Arr)); ShowMessage(IntToStr(Length(Arr))); //总数 ShowMessageFmt('%d - %s', [Arr[0].hwnd, Arr[0].ClassName]); //第一个元素end;
例五: 重复上一个例子, 如果数组是全局遍历并不靠参数传递, 代码会简单些
type TMyStruct = record hwnd: HWND; ClassName: string; end;var Arr: array of TMyStruct;
function EnumWindowsProc_5(hwnd: HWND; lParam: LPARAM): Boolean; stdcall;var buf: array[Byte] of Char;begin GetClassName(hwnd, buf, SizeOf(buf)); SetLength(Arr, Length(Arr) + 1); Arr[High(Arr)].hwnd := hwnd; Arr[High(Arr)].ClassName := buf; Result := True;end;
procedure TForm1.Button1Click(Sender: TObject);begin SetLength(Arr, 0); EnumWindows(@EnumWindowsProc_5, Integer(Arr)); ShowMessage(IntToStr(Length(Arr))); //总数 ShowMessageFmt('%d - %s', [Arr[0].hwnd, Arr[0].ClassName]); //第一个元素end;
SplendourChiang 的目的是获取进程 ID 和窗口句柄的数组, 按 "例四" 的方法给修改如下:
type MyProcessInfo = record PID, WinHWND : DWORD; end; TMyProcessInfoArray = array of MyProcessInfo; PMyProcessInfoArray = ^TMyProcessInfoArray;
function MyEnumWindowsProc(Wnd: DWORD; lParam: LPARAM): Bool; stdcall;var PID : DWORD; p: PMyProcessInfoArray;begin GetWindowThreadProcessID(Wnd, @PID); p := PMyProcessInfoArray(lParam); SetLength(p^, Length(p^) + 1); p^[High(p^)].PID := PID; p^[High(p^)].WinHWND := Wnd; Result := True;end;
procedure TForm1.Button1Click(Sender: TObject);var CC: TMyProcessInfoArray;begin SetLength(CC, 0); EnumWindows(@MyEnumWindowsProc, Integer(@CC)); ShowMessage(IntToStr(Length(CC))); //总数 ShowMessageFmt('%d - %d', [CC[0].PID, CC[0].WinHWND]); //第一个元素end;
相关阅读 >>
Delphi (vcl及fmx[firemonkey])启动时的欢迎窗口实现代码
更多相关阅读请进入《Delphi》频道 >>