2017-03-13 1 views
0

"alt"키 입력을 처리하려고하는데 아무 일도 일어나지 않습니다. 나는 키 : 수() 함수에서 "ALT"키를 제외하고는 창문과 winuser 라이브러리"alt"키 입력을 처리하는 방법 api C++

#include <windows.h> 
#include <winuser.h> 
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) 
{ 
    KBDLLHOOKSTRUCT *hook=(KBDLLHOOKSTRUCT *)lParam; 
    std::string input; 
    if (wParam == WM_KEYUP) { 
     input = Key::get(hook->vkCode, 1); 
    } 
    else if (wParam == WM_KEYDOWN) { 
    input = Key::get(hook->vkCode, 0); 
    } 
    Key::print(input); 
    return 0; 
} 

나는 모든 키보드를 처리 할 수와 C++를 사용합니다. 아무도 그것을 처리하는 방법을 알고 있습니까?

std::string get(int code, int up) { 
    std::string input; 
    switch(code) { 
     case 0x12: input = "[ALT]"; break; 
    } 
    return input; 

가 [편집]을 실제로 Alt 키를 처리하기 위해 사용 있어야 할 WM_SYSKEYDOWN 메시지이다, 나는 문제가 어디에 볼 충분 게시 마지막 코드를 생각했다. 절차를 게시하지 않았고 문제가있는 곳이 있습니다. 답장을 보내 주셔서 감사합니다.

+3

? 문제를 진단 할 수있는 정보가 충분하지 않습니다. –

+0

Microsoft 전설의 레이몬드 첸 (Raymond Chen)이 위에 언급 한 것을 추가하려면 스택 오버플로에 대한 모든 질문에 답할 수있는 [최소, 완전하고 검증 가능한 예제 (MCVE)]가 필요합니다. 링크 작성시 조언을 보려면 링크를 참조하십시오. – MrEricSir

+0

추측 - Alt 키를 누르면 'WM_KEYDOWN' 메시지가 아닌'WM_SYSKEYDOWN' 메시지가 게시되며 둘 다 처리하지는 않습니다. –

답변

0

0x12는 Windows API가 반환 할 것으로 보이지만 그걸 어떻게 얻을 수 있습니까? 그러나 그것을 점검하는 것만으로는 충분하지 않습니다. VK_MENU라는 이름의 "마법"번호는 사용하지 마십시오. 비 시스템 키를 누르면 인 경우

WM_KEYDOWN 메시지가 키보드 포커스가있는 창으로 게시 됨. 비 시스템 키는 Alt 키가 이 눌려지지 않을 때 눌려지는 키입니다.

wParam 비 시스템 키의 가상 키 코드입니다. 가상 키 코드를 참조하십시오.

  • 0-15 반복 다음 나타낸 바와 같이

    의 lParam 반복 횟수, 스캔 코드, 확장 키 플래그 컨텍스트 코드, 이전 키 상태 플래그 및 천이 상태 플래그 현재 메시지에 대해 계산하십시오. 값은 키를 누르고있는 사용자 의 결과로 키 입력이 자동 반복되는 횟수입니다. 키 입력이 길면 여러 개의 메시지가 전송됩니다. 그러나 반복 횟수는 누적되지 않습니다.

  • 16-23 스캔 코드. 값은 OEM에 따라 다릅니다.
  • 24 키가 확장 된 1015 또는 102 키 키보드에 나타나는 오른쪽 Alt 키와 Ctrl 키와 같은 확장 키인지 여부를 나타냅니다. 확장 키인 경우 값은 1입니다. 그렇지 않은 경우 은 0입니다.
  • 25-28 예약 됨. 사용하지 마세요.
  • 29 컨텍스트 코드. WM_KEYDOWN 메시지의 경우 값은 항상 0입니다.
  • 30 이전 키 상태. 메시지를 보내기 전에 키가 눌려져 있으면 값은 1이고, 키가 올라 오면 값은 0입니다.
  • 31 전환 상태입니다. WM_KEYDOWN 메시지의 경우 값은 항상 0입니다. 사용자가 (메뉴 모음을 활성화) 또는 ALT 키를 보유하고 다음 다른 키를 누를 F10 키를 누를 때

WM_SYSKEYDOWN 메시지

는 키보드 포커스가있는 창으로 게시 됨.현재 키보드에 키보드 포커스가있는 창 ( )이 없을 때도 발생합니다. 이 경우 WM_SYSKEYDOWN 메시지는 활성 창 으로 전송됩니다. 메시지를 수신하는 창 lParam 매개 변수의 컨텍스트 코드를 확인하여이 두 컨텍스트를 구별 할 수 있습니다.

wParam 누르는 키의 가상 키 코드입니다. 가상 키 코드를 참조하십시오.

lParam 반복 횟수, 스캔 코드, 확장 키 플래그, 컨텍스트 코드, 이전 키 상태 플래그 및 전환 상태 플래그.

당신이 PeekMeessage \ 가져 오기를 사용하는 경우,이 같은 뭔가 가능성을 설명 할 것 :

당신`에서 code` 되었나요
// Receives a WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN or WM_SYSKEYUP message and 
// returns a virtual key of the key that triggered the message. 
// 
// If the key has a common virtual key code, that code is returned. 
// For Alt's and Ctrl's, the values from the KeyCodes enumeration are used. 
int translateKeyMessage (MSG& Msg); 

// Virtual key codes for keys that aren't defined in the windows headers. 
enum KeyCodes 
{ 
    VK_LEFTCTRL = 162, 
    VK_RIGHTCTRL = 163, 
    VK_LEFTALT = 164, 
    VK_RIGHTALT = 165 
}; 


int translateKeyMessage (MSG& Msg) 
{ 
    // Determine the virtual key code. 
    int VirtualKeyCode = Msg.wParam; 

    // Determine whether the key is an extended key, e.g. a right 
    // hand Alt or Ctrl. 
    bool Extended = (Msg.lParam & (1 << 24)) != 0; 

    // If this is a system message, is the Alt bit of the message on? 
    bool AltBit = false;  
    if (Msg.message == WM_SYSKEYDOWN || Msg.message == WM_SYSKEYUP) 
     AltBit = (Msg.lParam & (1 << 29)) != 0; 

    if ((Msg.message == WM_SYSKEYUP || Msg.message == WM_KEYUP) && !Extended && !AltBit && VirtualKeyCode == VK_MENU) 
    { 
     // Left Alt 
     return KeyCodes::VK_LEFTALT; 
    } 

    // Left Ctrl 
    if (!Extended && !AltBit && VirtualKeyCode == VK_CONTROL) 
    { 
     // Peek for the next message. 
     MSG nextMsg; 
     BOOL nextMessageFound = PeekMessage(&nextMsg, NULL, 0, 0, PM_NOREMOVE); 

     // If the next message is for the right Alt: 
     if (nextMessageFound && nextMsg.message == Msg.message && nextMsg.wParam == VK_MENU) 
     { 
      // 
      bool nextExtended = (nextMsg.lParam & (1 << 24)) != 0; 

      // 
      bool nextAltBit = false;  
      if (nextMsg.message == WM_SYSKEYDOWN || nextMsg.message == WM_SYSKEYUP) 
       nextAltBit = (nextMsg.lParam & (1 << 29)) != 0; 

      // If it is really for the right Alt 
      if (nextExtended && !nextAltBit) 
      { 
       // Remove the next message 
       PeekMessage(&nextMsg, NULL, 0, 0, PM_REMOVE); 

       // Right Alt 
       return KeyCodes::VK_RIGHTALT; 
      } 
     } 

     // Left Ctrl 
     return KeyCodes::VK_LEFTCTRL; 
    } 

    if (Msg.message == WM_SYSKEYUP && !Extended && AltBit && VirtualKeyCode == VK_CONTROL) 
    { 
     // Peek for the next message. 
     MSG nextMsg; 
     BOOL nextMessageFound = PeekMessage(&nextMsg, NULL, 0, 0, PM_NOREMOVE); 

     // If the next message is for the right Alt: 
     if (nextMessageFound && nextMsg.message == WM_KEYUP && nextMsg.wParam == VK_MENU) 
     { 
      // 
      bool nextExtended = (nextMsg.lParam & (1 << 24)) != 0; 

      // 
      bool nextAltBit = false;  
      if (nextMsg.message == WM_SYSKEYDOWN || nextMsg.message == WM_SYSKEYUP) 
       nextAltBit = (nextMsg.lParam & (1 << 29)) != 0; 

      // If it is really for the right Alt 
      if (nextExtended && !nextAltBit) 
      { 
       // Remove the next message 
       PeekMessage(&nextMsg, NULL, 0, 0, PM_REMOVE); 

       // Right Alt 
       return KeyCodes::VK_RIGHTALT; 
      } 
     } 
    } 

    // Right Ctrl 
    if (Extended && !AltBit && VirtualKeyCode == VK_CONTROL) 
     return KeyCodes::VK_RIGHTCTRL; 

    // Left Alt 
    if (!Extended && AltBit && VirtualKeyCode == VK_MENU) 
     return KeyCodes::VK_LEFTALT; 

    // Default 
    return VirtualKeyCode; 
} 
+0

추측하지 않는 것이 좋습니다. 사용자가 설명을 제공 할 때까지 기다렸다가 질문이 끝나면 답변을 작성하십시오. 그렇지 않으면이 질문이이 양식에서 유효하다고 말할 수있는 상황이 발생합니다. –

+0

이것은 완벽한 대답이었습니다. 스위프트, 고마워. – WaLinke

관련 문제