[英]EnumWindows behaving oddly in 64-bit Delphi
我正在使用64位Windows 8計算機上的Delphi XE3,構建32位和64位應用程序。
我正在使用EnumWindows找出給定其進程ID的進程主窗口的Windows句柄。 代碼使用回調例程中的LPARAM參數將指針傳遞給記錄。
我正在使用的代碼適用於32位版本。
當我編譯並運行64位構建時,它失敗了。 出現此問題的原因是LPARAM值似乎在Wnd參數中傳遞。 Param值總是設置為$ FFFF ...換句話說,我根本沒有傳遞HWND值...所以它不是因為參數只是交換了。
type
PEnumInfo = ^TEnumInfo;
TEnumInfo = record
ProcessID : DWORD;
HWND : THandle;
end;
function EnumWindowsProc(Wnd: HWND; Param : LPARAM): Bool; stdcall;
var
PID : DWORD;
PEI : PEnumInfo;
begin
// in 32-bit Param matches the address of the param that is passed
// in 64-bit Param is set to $FFFF - however Wnd = the expected address
ShowMessage('PEI = '+IntToStr(Param));
PEI := PEnumInfo(Param);
GetWindowThreadProcessID(Wnd, @PID);
// the code fails at this next line in 64-bit build because PEI = $FFFF rather than the actual pointer passed
Result := (PID <> PEI^.ProcessID) or
(not IsWindowVisible(WND)) or
(not IsWindowEnabled(WND));
if not Result then PEI^.HWND := WND; //break on return FALSE
end;
function FindMainWindow(PID: DWORD): DWORD;
var
EI : TEnumInfo;
begin
EI.ProcessID := PID;
EI.HWND := 0;
ShowMessage('PEI = '+IntToStr(LPARAM(@EI)));
EnumWindows(@EnumWindowsProc, LPARAM(@EI));
Result := EI.HWND;
end;
Win64調用約定是否不同? 還是我犯了一些其他的根本錯誤?
感謝任何幫助或想法。
您問題中的代碼運行正常。 你的EnumWindowsProc
聲明是正確的。 參數和返回值具有正確的類型。 調用約定是正確的,盡管這對於只有一個調用約定的x64 Windows實際上並不重要。
如果使用問題中的代碼構建一個簡單的應用程序,您會發現它的行為正確並且可以正確枚舉窗口。
問題肯定是您的實際代碼與您顯示的代碼不同。 我的猜測是,在你的實際代碼中, EnumWindowsProc
是一個嵌套函數: 為什么不能將地址轉換為64位Delphi中的嵌套本地函數? 但這只是猜測。 我不知道你的真實代碼是什么樣的。 我知道問題中的代碼可以正常工作。
另一個評論是您錯誤地將HWND
成員聲明為THandle
類型。 這不會影響程序的正確性,但它在語義上是錯誤的。 我會聲明這樣的類型:
type
TEnumInfo = record
PID: DWORD;
Wnd: HWND;
end;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.