所以我刚刚得到了关于获取 Skype Chatbox 句柄的问题的答案。
我现在正在尝试创建一个简单的函数,用于挖掘句柄。这是我希望能够使用它的方式:
MyHWND := DigForHandle(['Notepad','Edit'],['Untitled - Notepad','']);
参数:
1) 字符串数组:保存类层次结构。
2) 字符串数组:保存窗口标题层次结构。
如您所见,第二个参数中的第二个条目是空的,因为Edit该类没有窗口标题。
是否可以创建这样的功能?:)
所以我刚刚得到了关于获取 Skype Chatbox 句柄的问题的答案。
我现在正在尝试创建一个简单的函数,用于挖掘句柄。这是我希望能够使用它的方式:
MyHWND := DigForHandle(['Notepad','Edit'],['Untitled - Notepad','']);
参数:
1) 字符串数组:保存类层次结构。
2) 字符串数组:保存窗口标题层次结构。
如您所见,第二个参数中的第二个条目是空的,因为Edit该类没有窗口标题。
是否可以创建这样的功能?:)
试试这个
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;
当我想到它时,我意识到它实际上相当简单——虽然我拥有的代码对我来说“令人困惑”,这就是我在这里提出问题的原因。在尝试之后,我发现这样做,它更容易阅读,而且没有那么复杂(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;