Using Delphi XE2 update 3 or update 4 on Win7 64 bit.
Calling enumwindows does not work like it used to work in Delphi 6.
In Delphi 6 enumwindows processed windows until the callback function returned False. That is what the documentation says it should do:
“To continue enumeration, the callback function must return TRUE; to stop enumeration, it must return FALSE.”
Making a call to enumwindows as follows:
procedure TForm1.Button1Click(Sender: TObject);
begin
EnumWindows(@FindMyWindow,0);
if GLBWindowHandle <> 0 then begin
ShowMessage('found');
end;
end;
Here is the callback function:
function FindMyWindow(hWnd: HWND; lParam: LPARAM): boolean; stdcall;
var TheText : array[0..150] of char;
str : string;
begin
Result := True;
GLBWindowHandle := 0;
if (GetWindowText(hWnd, TheText, 150) <> 0) then
begin
str := TheText;
if str = 'Form1' then
begin
GLBWindowHandle := hWnd;
Result := False;
end
else
result := True;
end;
end;
Just to be clear the callback function is defined in code BEFORE the buttonclick event so it is found by the compiler without needing to be defined in the interface section.
If this is run using Delphi 6 the enumeration of windows stops once the False result is returned and GLBWindowHandle is not zero
If this is run using Delphi XE2 the enumeration continues after the False result is returned and GLBWindowHandle is always zero.
WTF? Anybody have any ideas why the enumeration is not stopping like the documentation states it should and how it used to in Delphi 6?
Cheers!
This declaration is incorrect:
It should be:
You have to be careful not to mix up
BooleanandBOOLsince they are not the same thing. The former is a single byte, the latter is 4 bytes. This mismatch between whatEnumWindowsexpects and what your callback function delivers is enough to cause the behaviour you observe.In addition, Rob Kennedy contributed this excellent comment:
Discussion
Unfortunately the
Windows.pasheader translation definesEnumWindowsin a most unhelpful manner, like this:Now, the problem is in the definition of
TFNWndEnumProc. It is defined as:This means that you have to use the
@operator to make a generic pointer, because the function needs a generic pointer. IfTFNWndEnumProcwere declared like this:then the compiler would have been able to find the error.
The compiler rejects the call to
EnumWindowswith the following error:I think I will QC this issue and try my luck at persuading Embarcadero to stop using
TFarProc.