Jon*_*_rs 3 delphi winapi win64 delphi-xe3
我正在使用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;
Run Code Online (Sandbox Code Playgroud)
Win64调用约定是否不同?还是我犯了一些其他的根本错误?
感谢任何帮助或想法.
您问题中的代码运行正常.你的声明EnumWindowsProc
是正确的.参数和返回值具有正确的类型.调用约定是正确的,尽管这对于只有一个调用约定的x64 Windows实际上并不重要.
如果使用问题中的代码构建一个简单的应用程序,您会发现它的行为正确并且正确地枚举了窗口.
问题肯定是您的实际代码与您显示的代码不同.我的猜测是,在你的实际代码中,EnumWindowsProc
是一个嵌套函数:为什么不能将地址转换为64位Delphi中的嵌套本地函数?但这只是猜测.我不知道你的真实代码是什么样的.我知道问题中的代码可以正常工作.
另一个评论是您错误地声明该HWND
成员属于类型THandle
.这不会影响程序的正确性,但它在语义上是错误的.我会声明这样的类型:
type
TEnumInfo = record
PID: DWORD;
Wnd: HWND;
end;
Run Code Online (Sandbox Code Playgroud)