Как передать адрес функции потока в качестве обратного вызова в Winapi? - PullRequest
1 голос
/ 10 октября 2011

У меня есть простой поток, и внутри выполнения я пытаюсь вызвать EnumWindows () с адресом одной из функций, определенных в потоке. Поэтому я пытаюсь сделать это: EnumWindows (@cbEnumWindowsClickOK, 0); где cbEnumWindowsClickOK - это EnumWindowProc, определенный внутри класса потока, например:

TAutoClickOKThread = class(TThread)
private
     fExitEvent : THandle;
     function cbEnumWindowsClickOK(Wnd: HWND; Info: Pointer): BOOL;
public
   constructor Create(ExitEvent : Thandle);
   procedure Execute(); override;
end;

Когда я пытаюсь это сделать, я получаю сообщение «Ошибка: требуется переменная», намекая на то, что он не интерпретирует @cbEnumWindowsClickOK как адрес. Если я переместу функцию в глобальную область (удалив ее из потока), она сработает.

Есть мысли о том, как я могу это исправить?

1 Ответ

6 голосов
/ 10 октября 2011

Вы должны передать EnumWindows обычную старую функцию, то есть ту, которая не привязана к экземпляру.Вы должны передать экземпляр отдельно.Например:

function EnumFunc(hwnd: HWND; lParam: LPARAM): BOOL; stdcall;
begin
  Result := TAutoClickOKThread(lParam).cbEnumWindowsClickOK(hwnd);
  //note that there is now no need for the Info parameter
end;
...
procedure TAutoClickOKThread.Execute;
begin
  ...
  EnumWindows(EnumFunc, LPARAM(Self));
  ...
end;

Причина, по которой это необходимо сделать, заключается в том, что метод экземпляра не соответствует требуемой подписи для EnumWindows.У метода экземпляра есть дополнительный неявный параметр, содержащий ссылку на экземпляр, то есть Self.Вот как вы можете ссылаться на членов экземпляра.Но подпись для EnumFunc не обслуживает это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...