详解 EnumWindows 与 EnumWindowsProc - 回复 "SplendourChiang" 的问题


问题来源: http://www.cnblogs.com/del/archive/2009/10/16/1584488.html#1727205


// 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;


 
   

你可能感兴趣的:(windows)