This declaration is incorrect:
function FindMyWindow(hWnd: HWND; lParam: LPARAM): boolean; stdcall;
It should be:
function FindMyWindow(hWnd: HWND; lParam: LPARAM): BOOL; stdcall;
You must be careful not to confuse Boolean and BOOL , as they are not the same. The first is one byte, the last is 4 bytes. This is a mismatch between the expected EnumWindows and what the callback function provides to cause the observed behavior.
In addition, Rob Kennedy made a wonderful comment:
The compiler can help find this error if you break the habit of using the @ operator before the function name when calling EnumWindows . If the function signature is compatible, the compiler will allow you to use it without @ . Using @ turns it into a generic pointer and is compatible with everything, so the error is masked by unnecessary syntax. In short, using @ to create function pointers should be considered a code smell.
Discussion
Unfortunately, translating the Windows.pas header defines EnumWindows most useless way:
function EnumWindows(lpEnumFunc: TFNWndEnumProc; lParam: LPARAM): BOOL; stdcall;
Now the problem is defining TFNWndEnumProc . It is defined as:
TFarProc = Pointer; TFNWndEnumProc = TFarProc;
This means that you must use the @ operator to create a shared pointer, because functions require a shared pointer. If TFNWndEnumProc were declared as follows:
TFNWndEnumProc = function(hWnd: HWND; lParam: LPARAM): BOOL; stdcall;
then the compiler could find the error.
type TFNWndEnumProc = function(hWnd: HWND; lParam: LPARAM): BOOL; stdcall; function EnumWindows(lpEnumFunc: TFNWndEnumProc; lParam: LPARAM): BOOL; stdcall; external 'user32'; function FindMyWindow(hWnd: HWND; lParam: LPARAM): Boolean; stdcall; begin Result := False; end; .... EnumWindows(FindMyWindow, 0);
The compiler rejects the EnumWindows call with the following error:
[DCC error] Unit1.pas (38): E2010 Incompatible types: "LongBool" and "Boolean"
I think I will be QC this problem and try my luck convincing Embarcadero to stop using TFarProc .