問題來源:
http://www.cnblogs.com/del/archive/2009/10/16/1584488.html#1727205
// EnumWindows 的功能是遍歷所有頂層窗口
function EnumWindows(
lpEnumFunc: TFNWndEnumProc; {回調(diào)函數(shù)指針}
lParam: LPARAM {給回調(diào)函數(shù)的參數(shù), 它對(duì)應(yīng)回調(diào)函數(shù)的第二個(gè)參數(shù)}
): BOOL; stdcall; //成功與否, 其實(shí)是返回了回調(diào)函數(shù)的返回值
// EnumWindows 專用的回調(diào)函數(shù)的格式:
function EnumWindowsProc(
hwnd: HWND; {找到的窗口句柄}
lParam: LPARAM {EnumWindows 傳給的參數(shù); 因?yàn)樗侵羔? 可傳入, 但一般用作傳出數(shù)據(jù)}
): Boolean; stdcall; {函數(shù)返回 False 時(shí), 調(diào)用它的 EnumWindows 將停止遍歷并返回 False}
例一: 獲取所有頂層窗口的句柄
//需要個(gè) TListBox 顯示數(shù)據(jù)
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;
例二: 獲取所有頂層窗口的標(biāo)題(排除無標(biāo)題窗口)
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;
例三: 查找第一個(gè)記事本的句柄
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; //如果不需要繼續(xù)找, 找到第一個(gè)就結(jié)束
end
else
begin
Result := True;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
EnumWindows(@EnumWindowsProc_3, 0);
end;
例四: 獲取所有頂層窗口的句柄與類名數(shù)組:
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))); //總數(shù)
ShowMessageFmt('%d - %s', [Arr[0].hwnd, Arr[0].ClassName]); //第一個(gè)元素
end;
例五: 重復(fù)上一個(gè)例子, 如果數(shù)組是全局遍歷并不靠參數(shù)傳遞, 代碼會(huì)簡單些
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))); //總數(shù)
ShowMessageFmt('%d - %s', [Arr[0].hwnd, Arr[0].ClassName]); //第一個(gè)元素
end;
SplendourChiang 的目的是獲取進(jìn)程 ID 和窗口句柄的數(shù)組, 按 "例四" 的方法給修改如下:
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))); //總數(shù)
ShowMessageFmt('%d - %d', [CC[0].PID, CC[0].WinHWND]); //第一個(gè)元素
end;