Я создаю приложение, которое помещает значок на системный лоток, который меняет внешний вид на основе состояния ключа 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);
}
Это имеет тенденцию работать, это не технически правильно. Другие крючки могут не допустить использования ключа. Низкие коэффициенты, а не ноль. Использование методов BeginInvoke() или SynchronizationContext.Current.Post() - отличные способы запуска кода позже. –
@HansPassant В моем случае приложение не имеет открытой формы, пока не вызывается из контекстного меню значка в трее. Единственный способ поймать ключи - это глобальный ловец. – SeinopSys
Вот почему я упомянул SynchronizationContext. –