2014-12-06 3 views
1

Caps Lock 키의 상태에 따라 모양이 변경되는 아이콘을 시스템 트레이에 배치하는 응용 프로그램을 만듭니다. 내가 직면하고있는 문제는 Caps Lock 이외의 키를 누른 후에는 후크가 지나간 후 ​​해당 키가 체크를 뒤집어 아이콘이 잘못된 상태로 잘못 표시되기 때문에 후크가 올바르게 작동한다는 것입니다.하위 수준 키보드 후크에서 특정 키 감지

탐지 된 상태를 뒤집기 위해 Caps Lock 키를 눌렀을 때 감지하는 방법이 필요합니다.

private static NotifyIcon notifyIcon = new NotifyIcon(); 
private static bool CapsPressed = Control.IsKeyLocked(Keys.CapsLock); 
static Icon 
    AppIcon = CapsIndicator.Properties.Resources.AppIcon, 
    OnIcon = CapsIndicator.Properties.Resources.OnIcon, 
    OffIcon = CapsIndicator.Properties.Resources.OffIcon; 

static void UpdateIcon() { 
    notifyIcon.Icon = CapsPressed ? OnIcon : OffIcon; 
} 

// Hook initializing & other stuff here 

private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) { 
    if (nCode >= 0 && wParam == (IntPtr) WM_KEYDOWN) { 
     CapsPressed = Control.IsKeyLocked(Keys.CapsLock); 
     UpdateIcon(); 
    } 
    return CallNextHookEx(_hookID, nCode, wParam, lParam); 
} 

답변

1

이 솔루션은 매우 솔직 아니라, 키 코드는 lParam 포인터 인수를 사용하여 공개 할 수있다.

private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) { 
    if (nCode >= 0 && wParam == (IntPtr) WM_KEYDOWN) { 
     int vkCode = Marshal.ReadInt32(lParam); 

     CapsPressed = Control.IsKeyLocked(Keys.CapsLock); 
     // Flip the detected value if CapsLock is pressed 
     if ((Keys) vkCode == Keys.CapsLock) CapsPressed = !CapsPressed; 

     UpdateIcon(); 
    } 
    return CallNextHookEx(_hookID, nCode, wParam, lParam); 
} 
: 당신은 그것을 Marshal.ReadInt32으로 가리키는 것 32 비트 정수를 액세스하여이 작업을 수행 할 수 있습니다, 다음, 당신은 Keys 유형으로 캐스팅, 그리고 마지막으로 (당신이 좋아하는 또는 다른 키) Keys.CapsLock이 값을 비교해야
+0

기술적 인면에서는 올바르지 않습니다. 다른 후크는 키가 사용되는 것을 막을 수 있습니다. 낮은 확률, 0이 아닙니다. 양식의 BeginInvoke() 또는 SynchronizationContext.Current.Post() 메서드를 사용하면 나중에 코드를 실행할 수있는 훌륭한 방법입니다. –

+0

@HansPassant 제 경우에는 트레이 아이콘의 오른쪽 클릭 메뉴에서 응용 프로그램을 호출 할 때까지 응용 프로그램에 열려있는 양식이 없습니다. 내가 열쇠를 잡을 수있는 유일한 방법은 글로벌 포수를 통해서이다. – SeinopSys

+0

그래서 SynchronizationContext에 대해 언급했습니다. –