如何使用EnumWindows的回调函数? [英] How to use the EnumWindows call back function?
问题描述
我想有一个整洁的(密切,自包含)功能(让我们称之为GetDesktopHandle)返回的句柄桌面窗口。我用下面的code。但它仅适用于DeskHandle是一个全局变量。
如何摆脱这个全局变量的?如果我让本地I得到getDesktopWnd的AV,当我尝试DeskHandle:= hChild
VAR DeskHandle:HWND;功能GetDesktopHandle:HWND; 功能getDesktopWnd(手柄:HWND; NOTUSED:Longint型):BOOL; STDCALL; {回调函数}
VAR hChild:HWND;
开始
如果手柄<> 0,则
开始
hChild:= FindWindowEx(手柄,0,'SHELLDLL_DefView',无);
如果hChild<> 0,则
开始
hChild:= FindWindowEx(hChild,0,'SysListView32',无);
如果hChild<> 0
然后DeskHandle:= hChild;
结束;
结束;
结果:= TRUE;
结束;开始
DeskHandle:= 0;
EnumWindows的(@getDesktopWnd,0);
结果:= DeskHandle;
结束;
在主要问题是:我可以这样写code作为一个单一的功能,或者至少,我可以摆脱外部/全局变量的
可能的解决办法:结果
该文件说,第二个参数只是一个IN参数。
lParam的[输入]
类型:LPARAM
应用程序定义的值传递给回调函数。结果
的https://msdn.microsoft.com/en-us/library/windows/desktop/ms633497%28v=vs.85%29.aspx
块引用>难道是错用它来传递,结果回来?
解决方案类型
TMyData =记录
处理:HWND;
PID:DWORD;
图片说明:字符串;
产品类别:字符串;
结束;
PMyData = ^ TMyData;功能GetWindowClass(常量手柄:HWND):字符串;
开始
SetLength函数(结果,MAX_PATH);
SetLength函数(结果,GetClassName(手柄,PChar类型(结果),长(结果)));
结束;功能GetWindowCaption(常量手柄:HWND):字符串;
开始
SetLength函数(结果,MAX_PATH);
SetLength函数(结果,GetWindowText函数(手柄,PChar类型(结果),长(结果)));
结束;功能EnumChildWindowsProc(手柄:THandle;迈德特:PMyData):BOOL; STDCALL;
VAR
产品类别:字符串;
图片说明:字符串;
PID:DWORD;
开始
产品类别:= GetWindowClass(手柄);
图片说明:= GetWindowCaption(手柄); 结果:=(类名='SysListView32')和(标题='文件夹视图');
如果结果则
开始
MyData.Handle:=句柄;
GetWindowThreadProcessId(手柄,MyData.Pid);
MyData.Caption:=标题;
MyData.ClassName:=类名;
结束; //要继续枚举,回调函数必须返回TRUE;
//停止枚举,它必须返回FALSE
结果:=没有结果;
结束;过程TForm1.Button1Click(发件人:TObject的);
VAR
迈德特:TMyData;
开始
ZeroMemory(@MyData,一下SizeOf(迈德特));
EnumChildWindows(GetDesktopWindow,@EnumChildWindowsProc,NativeInt(@MyData));
如果MyData.Handle> 0,则
开始
ShowMessageFmt('PID调节找到%d窗口,[MyData.Pid]);
结束
别人开始
ShowMessage('窗口不存在!');
结束;
结束;I would like to have a single neat (close and self contained) function (let's call it GetDesktopHandle) that returns a handle to the Desktop window. I use the code below. But it only works in the DeskHandle is a global var.
How to get rid of this global variable? If I make it local I get an AV in getDesktopWnd when I try to DeskHandle := hChild
VAR DeskHandle : HWND; function GetDesktopHandle: HWND; function getDesktopWnd (Handle: HWND; NotUsed: Longint): bool; stdcall; { Callback function } VAR hChild : HWND; begin if handle <> 0 then begin hChild := FindWindowEx(handle, 0, 'SHELLDLL_DefView', nil); if hChild <> 0 then begin hChild := FindWindowEx(hChild, 0, 'SysListView32', nil); if hChild <> 0 then DeskHandle := hChild; end; end; Result:= TRUE; end; begin DeskHandle := 0; EnumWindows(@getDesktopWnd, 0); Result:= DeskHandle; end;
The main question is: can I write this code as a single function or AT LEAST, can I get rid of the external/global var?
Possible solution:
The documentation says that the second parameter is only a IN parameter.lParam [in] Type: LPARAM An application-defined value to be passed to the callback function.
https://msdn.microsoft.com/en-us/library/windows/desktop/ms633497%28v=vs.85%29.aspxWould it be wrong to use it to pass the result back?
解决方案type TMyData = record Handle: HWND; Pid: DWORD; Caption: String; ClassName: String; end; PMyData = ^TMyData; function GetWindowClass(const Handle: HWND): String; begin SetLength(Result, MAX_PATH); SetLength(Result, GetClassName(Handle, PChar(Result), Length(Result))); end; function GetWindowCaption(const Handle: HWND): String; begin SetLength(Result, MAX_PATH); SetLength(Result, GetWindowText(Handle, PChar(Result), Length(Result))); end; function EnumChildWindowsProc(Handle: THandle; MyData: PMyData): BOOL; stdcall; var ClassName: String; Caption: String; Pid: DWORD; begin ClassName := GetWindowClass(Handle); Caption := GetWindowCaption(Handle); Result := (ClassName = 'SysListView32') and (Caption = 'FolderView'); if Result then begin MyData.Handle := Handle; GetWindowThreadProcessId(Handle, MyData.Pid); MyData.Caption := Caption; MyData.ClassName := ClassName; end; // To continue enumeration, the callback function must return TRUE; // to stop enumeration, it must return FALSE Result := not Result; end; procedure TForm1.Button1Click(Sender: TObject); var MyData: TMyData; begin ZeroMemory(@MyData, SizeOf(MyData)); EnumChildWindows(GetDesktopWindow, @EnumChildWindowsProc, NativeInt(@MyData)); if MyData.Handle > 0 then begin ShowMessageFmt('Found Window in Pid %d', [MyData.Pid]); end else begin ShowMessage('Window not found!'); end; end;
这篇关于如何使用EnumWindows的回调函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!