2013-10-22 1 views
1

내 노트북 ​​스페이스 바를 끊어지고 그래서 나는 (그것이 모든 시간을 누르면되고 있었다 주장으로)을 해제하기 위해 낮은 수준의 키보드 후크를 작성하고 변경하는 벤처 갔다 내 전체 스페이스 바/마침표 키를 새 스페이스 바에 넣으십시오 .. 그게 잘 작동합니다. 그러나 2 문제가 있습니다.낮은 수준의 키보드 후크 반복 키 입력 (원치 않는)

1) 새로운 스페이스 바 키 입력이 두 번 전송, 항상 - 내가 입력이 출력을 확인하는 것을 할 때 나는

2) 대체 입력을 읽어이 후크를 다시 작성하기 위해 노력하고있어 이유를 알고하지 않으며, 출력에서 두 배가됩니다.

내가 강한의 C++ 프로그래머가 아니에요도 나는 수도 경우 윈도우 API 그래서, 너희들로부터 지침의 자리를 사랑한다면 마스터입니다!

코드는 다음과 같습니다 -

#include<Windows.h> 
#include <stdio.h> 
#include <iostream> 

using namespace std; 

HHOOK hHook = NULL; 
INPUT space[2]; 
bool sendingSpace=false; 

void sendSpace() 
{ 
      cout << "Sending space\n"; 

     space[0].type=INPUT_KEYBOARD; 
     space[0].ki.wVk=VK_SPACE; 
     space[0].ki.time=0; 

     space[1].type=INPUT_KEYBOARD; 
     space[1].ki.wVk=VK_SPACE; 
     space[1].ki.time=0; 
     space[1].ki.dwFlags=KEYEVENTF_KEYUP; 

     SendInput(2,space,sizeof(INPUT)); 


} 

LRESULT CALLBACK MyLowLevelHook (int nCode , WPARAM wParam , LPARAM lParam) 
{ 
    KBDLLHOOKSTRUCT* hs = (KBDLLHOOKSTRUCT*)lParam; 
    if(nCode <0) 
    return CallNextHookEx(hHook , nCode ,wParam , lParam); 

    switch(hs->vkCode) 
    { 
    case VK_SPACE: 
     if(!sendingSpace) 
     { 
     cout << "Ignoring space bar\n"; 
      return 1; 
     } 
     else 
     { 
      return CallNextHookEx(hHook , nCode ,wParam , lParam); 
     } 
     break; 

     case VK_OEM_PERIOD: 
     sendingSpace=true; 
     sendSpace(); 
     sendingSpace=false; 

     return 1; 


     break; 

     default: 
      cout << hs->vkCode << " (" << (char)(hs->vkCode) << ")" << endl; 
      break; 
    } 

     return CallNextHookEx(hHook , nCode ,wParam , lParam); 
} 

int main() 
{ 
    //FreeConsole(); 

    MSG msg; 
    hHook = SetWindowsHookEx(WH_KEYBOARD_LL, MyLowLevelHook , NULL,NULL); 

    while(!PeekMessage(&msg, NULL, 0, 0,PM_REMOVE)>0) 
    { 

      TranslateMessage(&msg); 
      DispatchMessage(&msg); 
    } 

    UnhookWindowsHookEx(hHook); 
    return 0; 
} 

P.S 임은 내 문제를 해결하기 위해 시행 착오 시도로를 PeekMessage를 사용!

어떤 지침, 도움에 미리 감사 또는 올바른 방향으로 가리키는 손가락!

  • 티미.
+3

:

이 작업을 수행하는 가장 쉬운 방법은 것 같습니다 있도록 sendSpace() 함수에 매개 변수를 추가하는 것입니다 . 아마도 두 가지를 모두 감지하고 키 업 공간을 보냅니다. 'wParam' 매개 변수는 [어떤 이벤트가 수신되었는지 알려줍니다.] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms644985(v=vs.85) .aspx). – Petesh

+0

'.'을 입력해야한다면 어떻게됩니까? – ComicSansMS

+0

'십진법'을 사용했습니다. 숫자 패드에서 : 감사합니다 Petesh, 그 푸시는 내 피곤한 눈이이 드라마의 끝을 보는데 도움이되었습니다, 대단히 감사합니다 - 당신이 대답으로 글을 쓰게되면 기꺼이 받아 들일 것입니다! – Timmy

답변

1

키보드 훅은 키가 눌려지고 키가 놓이기위한 이벤트를 봅니다. 후크 콜백의 wParam 인수는 키 다운에서 WM_KEYDOWN을 포함하고 키 업에서는 WM_KEYUP을 포함합니다. 이 경우

, 당신은 알아 둘을 분리하지 않는 및 공백 문자에게 키를 누른 후 발표 될 때마다 전송된다. 당신이 WM_KEYUP보고에 WM_KEYDOWNKEYEVENTF_KEYUPSendInput에 볼 때

은 당신이 정말해야 할 것은 SendInputKEYEVENTF_KEYDOWN이다. 아래 하나의 최대 하나 - 당신은 키를 누르 당 두 개의 메시지를 수신하고

void sendSpace(WPARAM param) 
{ 
    INPUT space; 

    cout << "Sending space " << (param == WM_KEYDOWN ? "Down" : "Up") << endl; 

    space.type = INPUT_KEYBOARD; 
    space.ki.wVk = VK_SPACE; 
    space.ki.time = 0; 
    space.ki.dwFlags = (param == WM_KEYDOWN) ? KEYEVENTF_KEYDOWN : KEYEVENTF_KEYUP; 

    SendInput(1, &space, sizeof INPUT); 
} 
+0

원래 코드가 keydown과 키를 보낼 때마다이 변경 사항이 다운 된 포스트를 별도의 포스트 이벤트로 전송합니다. – Petesh

+0

[UIPI] (http : // en .wikipedia.org/wiki/User_Interface_Privilege_Isolation) 및 32 비트/64 비트 까다 롭고 적절하게 처리해야합니다. – Petesh

+0

WH_KEYBOARD_LL 후크에는 32 비트/64 비트 트릭이 포함되지 않습니다. 낮은 수준의 후크는 항상 후크 응용 프로그램의 컨텍스트에서 실행됩니다. WH_KEYBOARD 후크 인 경우 32 비트 프로그램 만 32 비트 후크를 다른 32 비트 프로그램에 삽입 할 수 있고 64 비트 용으로 삽입 할 수 있습니다. 비트가 일치하지 않으면 후크는 후킹 프로그램의 컨텍스트에서 실행됩니다. –