Это объявление неверно:
function FindMyWindow(hWnd: HWND; lParam: LPARAM): boolean; stdcall;
Должно быть:
function FindMyWindow(hWnd: HWND; lParam: LPARAM): BOOL; stdcall;
Вы должны быть осторожны, чтобы не перепутать Boolean
и BOOL
, поскольку они не одно и то же. Первый - это один байт, последний - 4 байта. Этого несоответствия между тем, что ожидает EnumWindows
, и тем, что обеспечивает ваша функция обратного вызова, достаточно, чтобы вызвать поведение, которое вы наблюдаете.
Кроме того, Роб Кеннеди внес этот превосходный комментарий:
Компилятор может помочь найти эту ошибку, если вы избавитесь от привычки использовать оператор @
перед именем функции при вызове EnumWindows
. Если подпись функции совместима, компилятор позволит вам использовать ее без @
. Использование @
превращает его в универсальный указатель, и это совместимо со всем, поэтому ошибка маскируется ненужным синтаксисом. Короче говоря, использование @
для создания указателей на функции должно рассматриваться как запах кода .
Обсуждение
К сожалению, перевод заголовка Windows.pas
определяет EnumWindows
самым бесполезным образом, например:
function EnumWindows(lpEnumFunc: TFNWndEnumProc; lParam: LPARAM): BOOL; stdcall;
Теперь проблема в определении TFNWndEnumProc
. Он определяется как:
TFarProc = Pointer;
TFNWndEnumProc = TFarProc;
Это означает, что у вас есть , чтобы использовать оператор @
для создания универсального указателя, потому что функции нужен универсальный указатель. Если TFNWndEnumProc
было объявлено так:
TFNWndEnumProc = function(hWnd: HWND; lParam: LPARAM): BOOL; stdcall;
тогда компилятор смог бы найти ошибку.
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);
Компилятор отклоняет вызов EnumWindows
со следующей ошибкой:
[Ошибка DCC] Unit1.pas (38): E2010 Несовместимые типы: «LongBool» и «Boolean»
Думаю, я проверю эту проблему и попытаюсь убедить Embarcadero прекратить использование TFarProc
.