【问题标题】:Creating a function to dig for Windows Handle by Classname(s) Only创建仅按类名挖掘 Windows 句柄的函数
【发布时间】:2011-04-25 16:08:26
【问题描述】:

所以我刚刚得到了关于getting the Skype Chatbox handle 的问题的答案。

我现在正在尝试创建一个简单的函数,用于挖掘句柄。以下是我希望能够使用它的方式:

MyHWND := DigForHandle(['Notepad','Edit'],['Untitled - Notepad','']);

参数:

1) 字符串数组:保存类层次结构。

2) 字符串数组:保存窗口标题层次结构。

如您所见,第二个参数中的第二个条目是空的,因为 Edit 类没有窗口标题。

是否可以创建这样的功能? :)

【问题讨论】:

  • 您不能按原样使用此代码来查找记事本,因为它似乎包含特定于 Skype 的逻辑(例如,与“TConversationForm”进行比较)。你用 Skype 试过这个吗?如果是这样,它在哪里失败?它找到PID了吗?它是否找到顶层窗口?
  • @500 - 是的,我在考虑时意识到了这一点。不过,我一直在寻找的是一种在我知道它是类层次结构时挖掘任何句柄的方法,如果有多个相同的类,请根据 Window Caption 找到正确的句柄。我回家后会测试下面的答案

标签: windows delphi window-handles


【解决方案1】:

试试这个

uses
  Windows, Messages, TlHelp32, SysUtils;

type
  PGetWindowParam = ^TGetWindowParam;
  TGetWindowParam = record
    ProcID: DWORD;
    WindowCaption: string;
    Result: HWND;
  end;

function DigForHandle(const ProcName, Caption: string; const Hierachy: array of string): HWND;
function FindPID(const ExeFileName: string): DWORD;

implementation

function FindPID(const ExeFileName: string): DWORD;
var
  ContinueLoop: BOOL;
  ProcessEntry32: TProcessEntry32;
  SnapshotHandle: THandle;
  TempExeFileName: string;
begin
  Result := 0;
  SnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  if SnapshotHandle <> 0 then
  begin
    FillChar(ProcessEntry32, SizeOf(ProcessEntry32), 0);
    ProcessEntry32.dwSize := Sizeof(ProcessEntry32);
    ContinueLoop := Process32First(SnapshotHandle, ProcessEntry32);
    while ContinueLoop do
    begin
      TempExeFileName := ExtractFileName(ProcessEntry32.szExeFile);
      if SameText(TempExeFileName, ExeFileName) then
      begin
        Result := ProcessEntry32.th32ProcessID;
        Break;
      end;

      ContinueLoop := Process32Next(SnapshotHandle, ProcessEntry32);
    end;
    CloseHandle(SnapshotHandle);
  end;
end;

function GetWindow(Wnd: HWND; P: LParam): BOOL; stdcall;
var
  Param: PGetWindowParam;
  ProcID: DWORD;
  WindowTitle: array[0..256] of Char;
begin
  Result := True; // assume it doesn't match; keep searching
  Param := PGetWindowParam(P);

  ProcID := 0;
  GetWindowThreadProcessID(Wnd, @ProcID);
  if ProcID <> Param^.ProcID then
    Exit;

  FillChar(WindowTitle, SizeOf(WindowTitle), 0);
  if SendMessage(Wnd, WM_GETTEXT, SizeOf(WindowTitle) - SizeOf(Char), LPARAM(@WindowTitle[0])) <= 0 then
    Exit;

  if AnsiSameStr(WindowTitle, Param^.WindowCaption) then
  begin
    Param^.Result := Wnd;
    Result := False;
  end;
end;

function DigForHandle(const ProcName, Caption: string; const Hierachy: array of string): HWND;
var
  Param: TGetWindowParam;
  I: Integer;
  ParentWnd: HWND;
begin
  Result := 0;

  FillChar(Param, SizeOf(Param), 0);
  Param.ProcID := FindPID(ProcName);
  if Param.ProcID = 0 then
    Exit;

  Param.Result := 0;
  Param.WindowCaption := Caption;
  EnumWindows(@GetWindow, LPARAM(@Param));
  if Param.Result = 0 then
    Exit;

  I := 0;
  ParentWnd := Param.Result;
  while (ParentWnd <> 0) and (I < Length(Hierachy)) do
  begin
    Param.Result := 0;
    Param.WindowCaption := Hierachy[I];
    EnumChildWindows(ParentWnd, @GetWindow, LPARAM(@Param));
    if Param.Result = 0 then
      Break;
    ParentWnd := Param.Result;
    Inc(I);
  end;

  if I >= Length(Hierachy) then
    Result := Param.Result;
end;

【讨论】:

  • 我回家后会测试这个。由于我不完全了解这段代码的工作原理(因为我是新手):当我指定 Caption 时,它是否是它检查的最终句柄的标题?
【解决方案2】:

当我想到它时,我意识到它实际上相当简单 - 虽然我的代码对我来说“令人困惑”,这就是我在这里提出问题的原因。在尝试之后,我发现这样做,它更容易阅读,并且没有那么复杂(IMO)。

Function DigForHandle(ClassHierachy, TextHierachy : Array of String):HWND;
Var
 Handle : HWND;
 I : Integer;
 PClass,PText : PChar;

Begin

 Result := 0;

 I := 0;
 while (I <= Length(ClassHierachy)-1) do
 begin
   PClass := PChar(ClassHierachy[I]);
   PText  := PChar(TextHierachy[I]);

   if PClass = '' then PClass := Nil;
   if PText = '' then PText := Nil;


   Result := FindWindowEx(Result,0,PClass,PText);

   Inc(I);
 end;



End;

【讨论】:

    猜你喜欢
    • 2019-06-08
    • 1970-01-01
    • 1970-01-01
    • 2016-03-17
    • 2014-02-02
    • 2011-02-07
    • 1970-01-01
    • 2019-05-16
    • 1970-01-01
    相关资源
    最近更新 更多