Delphi Xe2: WH_KEYBOARD не будет возвращать левые и правые коды виртуальных клавиш

Я пытаюсь создать DLL, чтобы (глобально) перехватить нажатия клавиш и отправить их в мое приложение. Все работает нормально (перехват, обмен сообщениями и т. Д.). Единственная проблема, с которой я столкнулся, заключается в том, что я не могу вернуть коды левых и правых виртуальных клавиш (VK_LSHIFT, VK_RSHIFT, VK_LCONTROL и т. Д.).

Я потратил несколько часов на чтение msdn о KeyboardProc, VkKeyScan, MapVirtualKey и т. Д., Не имея возможности принять решение. Вот мой код:

function HookCallBack(Code: Integer; wParam: WPARAM; lParam: LPARAM): LongInt; stdcall;
begin
  Result := 0;
  if (Code < HC_ACTION) then Exit;
  if (Code = HC_NOREMOVE) then Result := CallNextHookEx(Keyboard, Code, wParam, lParam);
  if (Code = HC_ACTION) then begin
    PostMessage(Reciever, WM_USER + 1, wParam, lParam);
    Result := CallNextHookEx(Keyboard, Code, wParam, lParam);
  end;
end;

Я верю, что это как-то связано с LParam по этой ссылке, но я до сих пор не могу понять это.

Заранее спасибо.

Изменить: потратив много часов на эту проблему, я узнал, что LParamHi возвращает коды, аналогичные таблице ключей Linux, которая может отправлять разные коды каждого из этих ключей. Например, LSHIFT = 42, RSHIFT = 54, LCTRL = 29, RCTRL = 29+256(?) И т. Д. Я сейчас пытаюсь выяснить эти мелкие детали.

1 ответ

Shift, Alt, Ctrl - не клавиши. Это ключевые модификаторы, эти ключи не имеют собственного реального кода ключа. Вы действительно можете обнаружить их, только если нажата другая немодифицирующая клавиша.

Посмотрите, реализация TWinControl для понимания, как обнаружить эти ключи:

function TWinControl.DoKeyDown(var Message: TWMKey): Boolean;
var
  ShiftState: TShiftState;
  Form, FormParent: TCustomForm;
  LCharCode: Word;
begin
 ...
  with Message do
  begin
    ShiftState := KeyDataToShiftState(KeyData); //see this method.
    if not (csNoStdEvents in ControlStyle) then
    begin
      LCharCode := CharCode;
      KeyDown(LCharCode, ShiftState);
      CharCode := LCharCode;
      if LCharCode = 0 then Exit;
    end;
  end;
  Result := False;
end;
Другие вопросы по тегам