Delphi Xe,Win7x64
如何从进程名称(exe文件的完整路径)获取主窗口句柄,或至少一个类或窗口名称(如果该进程只有一个窗口).
例:
function MyGetWinHandle(path:String):HWND;
...
handle := MyGetWinHandle('c:\windows\system32\notepad.exe');
Run Code Online (Sandbox Code Playgroud)
我同意Petesh你需要枚举顶级窗口并检查创建它的进程的模块文件名.为了帮助您开始枚举顶级窗口,这是一个delphi实现.
首先,当你回调给你时,你需要一些与EnumWindows方法通信的方法.为此声明一条记录,该记录将保存您要查找的模块的文件名以及找到该进程的句柄:
TFindWindowRec = record
ModuleToFind: string;
FoundHWnd: HWND;
end;
Run Code Online (Sandbox Code Playgroud)
然后你需要声明并实现EnumWindows方法将为每个顶级窗口调用的回调函数:
function EnumWindowsCallBack(Handle: hWnd; var FindWindowRec: TFindWindowRec): BOOL; stdcall;
Run Code Online (Sandbox Code Playgroud)
请注意stdcall;声明末尾.这指定了调用约定,这很重要,因为Delphi的默认调用约定与Windows API的调用约定不同.
您的回调函数的实现可能如下所示:
function EnumWindowsCallBack(Handle: hWnd; var FindWindowRec: TFindWindowRec): BOOL; stdcall;
const
C_FileNameLength = 256;
var
WinFileName: string;
PID, hProcess: DWORD;
Len: Byte;
begin
Result := True;
SetLength(WinFileName, C_FileNameLength);
GetWindowThreadProcessId(Handle, PID);
hProcess := OpenProcess(PROCESS_ALL_ACCESS, False, PID);
Len := GetModuleFileNameEx(hProcess, 0, PChar(WinFileName), C_FileNameLength);
if Len > 0 then
begin
SetLength(WinFileName, Len);
if SameText(WinFileName, FindWindowRec.ModuleToFind) then
begin
Result := False;
FindWindowRec.FoundHWnd := Handle;
end;
end;
end;
Run Code Online (Sandbox Code Playgroud)
句柄是EnumWindows当前正在处理的顶级窗口的句柄.您可以使用它来获取该窗口的模块文件名.回调的结果确定EnumWindows是否应该继续枚举窗口.找到所需内容后返回false.
当然,您仍需要在运动中设置整个枚举操作:
var
FindWindowRec: TFindWindowRec;
function IsNotePadOpen: Boolean;
begin
FindWindowRec.ModuleToFind := 'c:\windows\system32\notepad.exe';
FindWindowRec.FoundHWnd := 0;
EnumWindows(@EnumWindowsCallback, integer(@FindWindowRec));
Result := FindWindowRec.FoundHWnd <> 0;
end;
Run Code Online (Sandbox Code Playgroud)
请注意,上面的代码会找到EnumWindows方法枚举的第一个记事本窗口,可能会有更多,可能没有.由您决定如何处理这些情况.
主窗口可以是无形的,所以你可以添加and (IsWindowInvisble(Handle))后If (Len > 0)的回调函数.
| 归档时间: |
|
| 查看次数: |
8617 次 |
| 最近记录: |