В данной статье мы рассмотрим проблему, с которой столкнулся пользователь при попытке дублирования кода из статьи "". При попытке компиляции кода возникла ошибка: "E2036 Variable required", указывающая на второй аргумент функции SetWindowsHookEx. Мы рассмотрим причину этой ошибки и предложим решение, а также альтернативное решение.
Причина ошибки
Ошибка возникает из-за того, что в коде пытаются использовать метод класса в качестве обратного вызова для функции SetWindowsHookEx. Однако, функция SetWindowsHookEx ожидает указатель на функцию, а не на метод класса. Методы класса имеют скрытый параметр "Self", который не известен функции SetWindowsHookEx, в результате чего и возникает ошибка.
Решение 1: Использование статического метода класса
Для устранения ошибки можно использовать статический метод класса в качестве обратного вызова для функции SetWindowsHookEx. Для этого нужно объявить метод как статический, используя ключевое слово "class", и удалить параметр "Self" из сигнатуры метода. Пример кода:
type
TForm1 = class(TForm)
ListBox1: TListBox;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
KBHook: HHook; {this intercepts keyboard input}
{callback's declaration}
class function KeyboardHookProc(Code: Integer; WordParam: WPARAM;
LongParam: LPARAM): LRESULT; stdcall; static;
public
{ Public declarations }
end;
var
Form1: TForm1;
...
procedure TForm1.FormCreate(Sender: TObject);
begin
{Set the keyboard hook so we can intercept keyboard input}
KBHook := SetWindowsHookEx( WH_KEYBOARD,
{callback >} @KeyboardHookProc,
HInstance,
GetCurrentThreadId() );
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
{unhook the keyboard interception}
UnHookWindowsHookEx(KBHook) ;
end;
class function TForm1.KeyboardHookProc(Code: Integer; WordParam: WPARAM;
LongParam: LPARAM): LRESULT;
begin
Form1.ListBox1.Items.Add( 'Code: ' + Code.ToString);
Form1.ListBox1.Items.Add( ' -- WordParam: ' + WordParam.ToString);
Form1.ListBox1.Items.Add( ' -- LongParam: ' + LongParam.ToString);
Form1.ListBox1.Items.Add( '' );
Result := 0;
{To prevent Windows from passing the keystrokes
to the target window, the Result value must be a nonzero value.}
end;
Решение 2: Использование свободной функции
Вместо использования метода класса, можно использовать свободную функцию в качестве обратного вызова для функции SetWindowsHookEx. Для этого нужно объявить функцию вне класса и передать указатель на эту функцию в качестве второго аргумента функции SetWindowsHookEx. Пример кода:
type
TForm1 = class(TForm)
ListBox1: TListBox;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
KBHook: HHook; {this intercepts keyboard input}
public
{ Public declarations }
end;
var
Form1: TForm1;
...
{callback's declaration}
function KeyboardHookProc(Code: Integer; WordParam: WPARAM;
LongParam: LPARAM): LRESULT; stdcall;
begin
Form1.ListBox1.Items.Add( 'Code: ' + Code.ToString);
Form1.ListBox1.Items.Add( ' -- WordParam: ' + WordParam.ToString);
Form1.ListBox1.Items.Add( ' -- LongParam: ' + LongParam.ToString);
Form1.ListBox1.Items.Add( '' );
Result := 0;
{To prevent Windows from passing the keystrokes
to the target window, the Result value must be a nonzero value.}
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
{Set the keyboard hook so we can intercept keyboard input}
KBHook := SetWindowsHookEx( WH_KEYBOARD,
{callback >} @KeyboardHookProc,
HInstance,
GetCurrentThreadId() );
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
{unhook the keyboard interception}
UnHookWindowsHookEx(KBHook) ;
end;
Оба решения устраняют ошибку и позволяют корректно устанавливать и снимать хук на ввод с клавиатуры в Delphi. Выбор между ними зависит от конкретных требований вашего проекта.
Статья посвящена решению проблемы, связанной с ошибкой компиляции кода при попытке дублирования кода из статьи 'Перехват ввода с клавиатуры в Delphi'. Ошибка 'E2036 Variable required' возникает из-за использования метода класса в качестве обратного вызова
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS