2013-05-05 2 views
0

внутри моего hook proc, как определить, используется ли нажатие клавиши SHIFT (не отпуская ее), а затем клавишу char (например, A)?Определите, нажата ли кнопка SHIFT на клавиатуре insde Hook Proc

, например, если я нажимаю Shift + A, я хочу знать, что это будет прописным вместо того, чтобы его, как Shift,

так будут, если пользователь нажимает и отпускает Сдвиг , он будет захватывать только Shift.

instaleld крючок 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

Этот класс должен предоставить необходимую информацию. http://wwww.bummisoft.de/download/Key_Hook_Class.zip – bummi

+0

Кстати, не глобальные крючки suppouse для внутри .dll? из моего воспоминания LowLevel один не должен быть внутри .dll, хотя, я прав? – 2013-05-05 17:54:34

+0

@ user1803300 Это правильно. –

ответ

3

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

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

Я знаком с этим кодом, bu..t Я хочу извлечь эту информацию из lParam, возможно ли: S? – 2013-05-05 14:39:57

+0

Остерегайтесь временных проблем здесь. 'GetKeyboardState' возвращает * текущее состояние клавиатуры.Если пользователь выпустил или нажал клавишу SHIFT между нажатием клавиши, которая сгенерировала соответствующее сообщение, и обработчиком сообщения, которое может быть нетривиальным количеством времени в некоторых ситуациях, это даст неточные результаты. –

+0

@MasonWheeler У вас есть это право? * Приложение может вызывать эту функцию для получения текущего состояния всех виртуальных ключей. Статус изменяется как поток, удаляет сообщения клавиатуры из очереди сообщений. Статус не изменяется, поскольку сообщения клавиатуры отправляются в очередь сообщений потока и не изменяются, поскольку сообщения клавиатуры отправляются или получаются из очередей сообщений других потоков. * –

0

Вы детектировать нажатие SHIFT ключ, когда ваш крючок прок вызывается с wParam равным VK_SHIFT.

Когда крючок прок называется соответствующий ключ нажат, то wParam и lParam значения совпадают ли или нет SHIFT клавиша нажата. Поскольку вы не вызываете TranslateMessage и DispatchMessage, как это было бы в обычном цикле сообщений, вам придется переводить необработанные ключевые события down/up в фактические нажатия клавиш.

Возможно, вам будет проще использовать GetKeyState(VK_SHIFT)<0, чтобы определить, выключен ли ключ SHIFT. Это зависит от того, что вы пытаетесь сделать. Это немного похоже на то, что вы создаете полностью функционирующий кейлоггер. В этом случае специальные вызовы на GetKeyState(VK_SHIFT)<0 могут не соответствовать вашим потребностям, и правильная обработка отдельных сообщений вниз/вверх по клавишам будет лучше.


Некоторые другие комментарии:

  1. Почему вы кучного выделяющие свой TKeystrokeData запись? Вы можете отлично использовать стоп, выделенный записи.
  2. Я надеюсь, что hConsole - это окно в том же процессе, что и ваш крючок. Если нет, он не получит никакой полезной информации, потому что указатель, который вы отправляете, имеет смысл только в процессе, который его определяет. Если вы хотите пересылать информацию, перекрестно обрабатывайте их WM_COPYDATA - твой парень.
+0

Я узнал что-то ДЕЙСТВИТЕЛЬНО странное ... у меня на клавиатуре есть 2 языка, английский и иврит, теперь, когда я сосредоточился на Блокноте и изменил его на иврит и начал набирать случайные буквы, крючок захватывает английские буквы (я вижу это в TMemo), когда я сосредоточился на TMemo и изменил его на иврит, а затем снова вернулся к блокноту и написал снова, тогда он захватывает иврит, почему это происходит? (может ли это быть раскладка клавиатуры?) P.S - Я изменил его с помощью языковой панели. – 2013-05-05 17:50:21

+0

Я не знаю ответа на этот другой вопрос. –