I am working in Delphi XE3, on a 64-bit Windows 8 machine, building 32-bit and 64-bit applications.
I am using EnumWindows to find out the Windows Handle of the main window of a process given its Process ID. The code uses the LPARAM parameter in the call back routine to pass a pointer to a record.
The code I am using has worked fine for a 32-bit build.
It is failing when I compile and run the 64-bit build. The problem occurs because the LPARAM value appears to be passed in the Wnd parameter. The Param value is always set to $FFFF ... in other words I don't get passed the HWND value at all ... so it's not as through the parameters are just swapped around.
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;
Is the Win64 calling convention different? Or am I making some other fundamental mistake?
Any help or ideas gratefully accepted.