Determine if SHIFT is pressed insde keyboard Hook Proc

旧巷老猫 提交于 2019-12-25 08:44:05

问题


inside my hook proc, how can i determine whether a used is pressing SHIFT (without releasing it) and then a char key (like A) ?

for example, if i press Shift+A, i want to know that it will be an uppercase a instead of getting it like Shift, a

so it will be A, if a user presses and releases Shift, it will capture Shift only.

the instaleld hook is WH_KEYBOARD (Global)

function KeyHookProc(Code: Integer; wVirtKey: WPARAM; lKeyStroke: LPARAM)
  : LRESULT; stdcall;
type
  TTransitionState = (tsPressed, tsReleased);

  PKeystrokeData = ^TKeystrokeData;

  TKeystrokeData = record
    VirtualKey: WPARAM;
    KeyStroke: LPARAM;
    KeyState: TKeyboardState;
  end;
var
  Transition: TTransitionState;
  KeystrokeDataPtr: PKeystrokeData;
begin
  Result := CallNextHookEx(hKeyHook, Code, wVirtKey, lKeyStroke);

  Transition := TTransitionState((lKeyStroke shr 31) and 1);

  if (Code = HC_ACTION) and (Transition = tsPressed) then
  begin
    New(KeystrokeDataPtr);
    try
      KeystrokeDataPtr^.VirtualKey := wVirtKey;
      KeystrokeDataPtr^.KeyStroke := lKeyStroke;
      GetKeyboardState(KeystrokeDataPtr^.KeyState);
      SendMessage(hConsole, WM_NULL, 0, LPARAM(KeystrokeDataPtr));
    finally
      Dispose(KeystrokeDataPtr);
    end;
  end;
end;

回答1:


Here's the code we use in normal day-to-day use to detect the shift key. I've never used it in a hooked context, so I don't know if it would work there, or if something is different in that context that would prevent it.

function ShiftIsDown : Boolean;
var
  State: TKeyboardState;
begin
  WINDOWS.GetKeyboardState(State);
  Result := ((State[vk_Shift] and 128) <> 0);
end; 



回答2:


You detect the pressing of the SHIFT key when your hook proc is called with wParam equal to VK_SHIFT.

When your hook proc is called corresponding to the A key being pressed, the wParam and lParam values are identical whether or not the SHIFT key is down. Since you are not calling TranslateMessage and DispatchMessage as would happen in a normal message loop, you are going to have to translate the raw key down/up events into actual key presses.

It's probably going to be easiest for you to use GetKeyState(VK_SHIFT)<0 to detect whether or not the SHIFT key is down. That depends on exactly what you are trying to do. It looks a little like you are making a fully functioned keylogger. In which case ad-hoc calls to GetKeyState(VK_SHIFT)<0 may not meet your needs, and proper processing of the individual key down/up messages would be better.


Some other comments:

  1. Why are you heap allocating your TKeystrokeData record? You can perfectly well use a stack allocated record.
  2. I hope that hConsole is a window in the same process as your hook. If not it won't receive any useful information because the pointer you send it is only meaningful in the process that defines it. If you want to send information cross-process them WM_COPYDATA is your guy.


来源:https://stackoverflow.com/questions/16385466/determine-if-shift-is-pressed-insde-keyboard-hook-proc

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!