繁体   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