在 Delphi 11 Alexandria 的 Windows 10 中的 32 位 VCL 應用程式中,我試圖從任務的模塊路徑中獲取正在運行的主任務的視窗句柄:
type
TFindWindowRec = record
ModuleToFind: string;
FoundHWnd: HWND;
end;
function EnumWindowsCallBack(aHandle: 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(aHandle, 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 := aHandle;
end;
end;
end;
var
FindWindowRec: TFindWindowRec;
function TformMain.GetmainWindowHandleFRomProcessPath(aProcessPath: string): HWND;
begin
Result := 0;
CodeSite.Send('TformMain.GetmainWindowHandleFRomProcessPath: aProcessPath', aProcessPath);
FindWindowRec.ModuleToFind := aProcessPath;
FindWindowRec.FoundHWnd := 0;
EnumWindows(@EnumWindowsCallback, Integer(@FindWindowRec));
if FindWindowRec.FoundHWnd <> 0 then
begin
Result := FindWindowRec.FoundHWnd;
CodeSite.Send('TformMain.GetmainWindowHandleFRomProcessPath: Result', Result);
end;
end;
當我這樣做時:
GetmainWindowHandleFRomProcessPath('c:\windows\system32\notepad.exe');
...然后我得到正確的視窗句柄。
當我這樣做時:
GetmainWindowHandleFRomProcessPath('C:\Program Files (x86)\Embarcadero\Studio\22.0\bin\bds.exe');
...然后我得到一個錯誤的(不存在的)視窗句柄!
為什么會這樣?如何獲得正確的視窗句柄?
uj5u.com熱心網友回復:
與 Remy 和 Andreas 的討論使我得到了這個成功的作業答案:
type
TFindWindowRec = record
ModuleToFind: string;
FoundHWnd: HWND;
end;
// The `RzShellUtils` unit is from Ray Konopka's Signature Library available from GetIt:
function PathsAreSamePIDL(const Path1, Path2: string): Boolean;
begin
var AIL1: PItemIdList;
var AIL2: PItemIdList;
RzShellUtils.ShellGetIdListFromPath(Path1, AIL1);
RzShellUtils.ShellGetIdListFromPath(Path2, AIL2);
var CompResult:= RzShellUtils.CompareAbsIdLists(AIL1, AIL2);
Result := CompResult = 0;
end;
function EnumWindowsCallBack(aHandle: HWND; var FindWindowRec: TFindWindowRec): BOOL; stdcall;
const
C_FileNameLength = MAX_PATH;
PROCESS_QUERY_LIMITED_INFORMATION = $1000;
var
WinFileName: string;
PID, hProcess: DWORD;
Len: Byte;
begin
Result := True;
SetLength(WinFileName, C_FileNameLength);
GetWindowThreadProcessId(aHandle, PID);
hProcess := OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, False, PID);
Len := GetModuleFileNameEx(hProcess, 0, PChar(WinFileName), C_FileNameLength);
CloseHandle(hProcess);
if Len > 0 then
begin
SetLength(WinFileName, Len);
//if SameText(WinFileName, FindWindowRec.ModuleToFind) then
if PathsAreSamePIDL(WinFileName, FindWindowRec.ModuleToFind) then
begin
var IsVisible := IsWindowVisible(aHandle);
if not IsVisible then EXIT;
var IsOwned := GetWindow(aHandle, GW_OWNER) <> 0;
if IsOwned then EXIT;
var IsAppWindow := GetWindowLongPtr(aHandle, GWL_EXSTYLE) and WS_EX_APPWINDOW <> 0;
if not IsAppWindow then EXIT;
Result := False;
FindWindowRec.FoundHWnd := aHandle;
end;
end;
end;
function TformMain.GetMainWindowHandleFromProcessPath(aProcessPath: string): HWND;
var
FindWindowRec: TFindWindowRec;
begin
Result := 0;
FindWindowRec.ModuleToFind := aProcessPath;
FindWindowRec.FoundHWnd := 0;
EnumWindows(@EnumWindowsCallback, LPARAM(@FindWindowRec));
if FindWindowRec.FoundHWnd <> 0 then
begin
Result := FindWindowRec.FoundHWnd;
end;
end;
我不明白為什么將討論轉移到另一個頁面的人洗掉了最新評論。那些被洗掉的評論有什么禁止的嗎?
再次感謝 Remy 和 Andreas!
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/433770.html
標籤:德尔福 温纳皮 delphi-11-亚历山大
