簡體   English   中英

EnumWindows在64位Delphi中表現得很奇怪

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM