private static void Refresh(object o) { var indicators = new KEYBOARD_INDICATOR_PARAMETERS(); int buffer_size = (int)Marshal.SizeOf(indicators); var led_vk = Settings.LedKey.Value[0].VirtualKey; // NOTE: I was unable to make IOCTL.KEYBOARD_QUERY_INDICATORS work // properly, but querying state with GetKeyState() seemed more // robust anyway. Think of the user setting Caps Lock as their // compose key, entering compose state, then suddenly changing // the compose key to Shift: the LED state would be inconsistent. foreach (var kv in m_vk_to_flag) { var vk = kv.Key; var flag = kv.Value; if (NativeMethods.GetKeyState(vk) != 0) { indicators.LedFlags |= flag; } else if (Composer.IsComposing) { if (Composer.CurrentComposeKey.VirtualKey == vk && led_vk == VK.COMPOSE || led_vk == vk) { indicators.LedFlags |= flag; } } } lock (m_kbd_devices) { foreach (ushort id in m_kbd_devices) { indicators.UnitId = id; using (var handle = NativeMethods.CreateFile($@"\\.\dos_kbd{id}", FileAccess.Write, FileShare.Read, IntPtr.Zero, FileMode.Open, FileAttributes.Normal, IntPtr.Zero)) { int bytesReturned; NativeMethods.DeviceIoControl(handle, IOCTL.KEYBOARD_SET_INDICATORS, ref indicators, buffer_size, IntPtr.Zero, 0, out bytesReturned, IntPtr.Zero); } } } }
public static void UpdateKeyboardLeds(object sender, EventArgs e) { var indicators = new KEYBOARD_INDICATOR_PARAMETERS(); int buffer_size = (int)Marshal.SizeOf(indicators); // NOTE: I was unable to make IOCTL.KEYBOARD_QUERY_INDICATORS work // properly, but querying state with GetKeyState() seemed more // robust anyway. Think of the user setting Caps Lock as their // compose key, entering compose state, then suddenly changing // the compose key to Shift: the LED state would be inconsistent. if (NativeMethods.GetKeyState(VK.CAPITAL) != 0 || (m_composing && Settings.ComposeKey.Value.VirtualKey == VK.CAPITAL)) { indicators.LedFlags |= KEYBOARD.CAPS_LOCK_ON; } if (NativeMethods.GetKeyState(VK.NUMLOCK) != 0 || (m_composing && Settings.ComposeKey.Value.VirtualKey == VK.NUMLOCK)) { indicators.LedFlags |= KEYBOARD.NUM_LOCK_ON; } if (NativeMethods.GetKeyState(VK.SCROLL) != 0 || (m_composing && Settings.ComposeKey.Value.VirtualKey == VK.SCROLL)) { indicators.LedFlags |= KEYBOARD.SCROLL_LOCK_ON; } for (ushort i = 0; i < 4; ++i) { indicators.UnitId = i; using (var handle = NativeMethods.CreateFile(@"\\.\" + "dos_kbd" + i.ToString(), FileAccess.Write, FileShare.Read, IntPtr.Zero, FileMode.Open, FileAttributes.Normal, IntPtr.Zero)) { int bytesReturned; NativeMethods.DeviceIoControl(handle, IOCTL.KEYBOARD_SET_INDICATORS, ref indicators, buffer_size, IntPtr.Zero, 0, out bytesReturned, IntPtr.Zero); } } }
public static extern bool DeviceIoControl(SafeFileHandle hDevice, IOCTL IoControlCode, IntPtr InBuffer, int nInBufferSize, out KEYBOARD_INDICATOR_PARAMETERS OutBuffer, int nOutBufferSize, out int pBytesReturned, IntPtr Overlapped);
public static void UpdateKeyboardLeds(object sender, EventArgs e) { var indicators = new KEYBOARD_INDICATOR_PARAMETERS(); int buffer_size = (int)Marshal.SizeOf(indicators); // NOTE: I was unable to make IOCTL.KEYBOARD_QUERY_INDICATORS work // properly, but querying state with GetKeyState() seemed more // robust anyway. Think of the user setting Caps Lock as their // compose key, entering compose state, then suddenly changing // the compose key to Shift: the LED state would be inconsistent. if (NativeMethods.GetKeyState(VK.CAPITAL) != 0 || (IsComposing() && Settings.ComposeKey.Value.VirtualKey == VK.CAPITAL)) indicators.LedFlags |= KEYBOARD.CAPS_LOCK_ON; if (NativeMethods.GetKeyState(VK.NUMLOCK) != 0 || (IsComposing() && Settings.ComposeKey.Value.VirtualKey == VK.NUMLOCK)) indicators.LedFlags |= KEYBOARD.NUM_LOCK_ON; if (NativeMethods.GetKeyState(VK.SCROLL) != 0 || (IsComposing() && Settings.ComposeKey.Value.VirtualKey == VK.SCROLL)) indicators.LedFlags |= KEYBOARD.SCROLL_LOCK_ON; for (ushort i = 0; i < 4; ++i) { indicators.UnitId = i; using (var handle = NativeMethods.CreateFile(@"\\.\" + "dos_kbd" + i.ToString(), FileAccess.Write, FileShare.Read, IntPtr.Zero, FileMode.Open, FileAttributes.Normal, IntPtr.Zero)) { int bytesReturned; NativeMethods.DeviceIoControl(handle, IOCTL.KEYBOARD_SET_INDICATORS, ref indicators, buffer_size, IntPtr.Zero, 0, out bytesReturned, IntPtr.Zero); } } }