如何使用EnumWindows的回调函数? [英] How to use the EnumWindows call back function?

查看:138
本文介绍了如何使用EnumWindows的回调函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想有一个整洁的(密切,自包含)功能(让我们称之为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.aspx

Would 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆