Не используйте жестко закодированные magic numbers. В этом контексте 13 составляет WH_KEYBOARD_LL
, $0101
- WM_KEYUP
и т. Д. Используйте фактические имена в вашем коде. Они объявлены в единицах Windows
и Messages
.
Вы объявили KeyboardHook()
, чтобы использовать соглашение о звонках stdcall
? Код, который вы показали, не делает этого. Это очень важно, поэтому значения параметров передаются правильно в стеке вызовов.
lParam
значение WH_KEYBOARD_LL
крючка НЕ PEventMsg
(указатель на структуру EVENTMSG
). Эта структура используется для крючков WH_JOURNALPLAYBACK
. WH_KEYBOARD_LL
использует структуру KBDLLHOOKSTRUCT
. Delphi не объявляет эту конкретную структуру, поэтому вам придется объявить ее самостоятельно в своем коде.
И не игнорируйте параметр обратного вызова Code
или возвращаемое значение CallNextHookEx()
. Они важны. Значения wParam
и lParam
действительны только тогда, когда параметр Code
равен HC_ACTION
(0). И возвращаемое значение CallNextHookEx()
должно быть передано цепочке крючков.
Попробуйте вместо этого:
type
PKBDLLHOOKSTRUCT = ^KBDLLHOOKSTRUCT;
KBDLLHOOKSTRUCT = record
vkCode: DWORD;
scanCode: DWORD;
flags: DWORD;
time: DWORD;
dwExtraInfo: ULONG_PTR;
end;
function KeyboardHook(Code: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
if Code = HC_ACTION then
begin
if (wParam = WM_KEYUP) and (App.Inside) then
begin
case PKBDLLHOOKSTRUCT(lParam)^.vkCode of
VK_NEXT: App.Next;
VK_CAPITAL: App.Show;
end;
end;
end;
// note that CallNextHookEx() ignores the first parameter,
// so you could pass 0 instead of ID_Keyboard...
Result := CallNextHookEx(Hook_ID_Keyboard, Code, wParam, lParam);
end;
function StartHookKeyboard: Boolean; stdcall;
begin
if Hook_ID_Keyboard = 0 then
Hook_ID_Keyboard := SetWindowsHookEx(WH_KEYBOARD_LL, @KeyboardHook, HInstance, 0);
Result := Hook_ID_Keyboard <> 0;
end;
function StopHookKeyboard: Boolean; stdcall;
begin
if Hook_ID_Keyboard <> 0 then
begin
if UnhookWindowsHookEx(Hook_ID_Keyboard) then
Hook_ID_Keyboard := 0;
end;
Result := Hook_ID_Keyboard = 0;
end;
Если код еще сбой, это, вероятно, связано с App
. Что такое App
? Где и как оно объявляется? Как он инициализируется? Что делать Next()
и Show()
на самом деле делаете? Вы устанавливаете глобальный крючок, чтобы закрепить все запущенные процессы, так что App
используется в кросс-технологическом режиме?
Повторение * Через некоторое время происходит сбой, и я должен снова запустить крючок * несколько раз не вопрос. Копирование и вставка * Через некоторое время происходит сбой, и я должен снова запустить крючок. Через некоторое время происходит сбой, и я должен снова запустить крючок. После некоторого сбоя и я снова должен снова запустить крючок. * Не вопрос. Копирование и вставка * Через некоторое время происходит сбой, и я должен снова запустить крючок. Через некоторое время происходит сбой, и я должен снова запустить крючок. После некоторого сбоя и я снова должен снова запустить крючок. * Не вопрос. Повторите попытку и повторите попытку. –
Письмо *, поэтому я пишу этот абзац, бесполезный для его публикации * так же неправильно, как копирование и вставка бессмыслицы. Существует требование для определенного количества текста, чтобы вы предоставили ** полезную ** информацию, а не шум. Если вы не хотите участвовать здесь, действуя правильно, отправляйтесь в другое место, чтобы найти помощь. –
Хорошо, мне очень жаль. – user2022323