C# RawInputDevice in Windows: How I can disable messages for all applications except my?

1

I have a RawInputDevice that I registered.

// sample
private void SplashLoad(object sender, EventArgs e)
        {
            var rid = new RawInputDevice[1];
            rid[0].UsagePage = HidUsagePage.GENERIC;
            rid[0].Usage = HidUsage.Keyboard;
            rid[0].Flags = RawInputDeviceFlags.INPUTSINK;
            rid[0].Target = Handle;
            if (!Win32.RegisterRawInputDevices(rid, (uint)rid.Length, (uint)Marshal.SizeOf(rid[0])))
            {
                throw new ApplicationException("Не удалось зарегистрировать устройство.");
            }
            inputBuffer = "";
            this.terminateFlag = false;
            t = new Thread(MainThread);
            t.Start(this);
        }
// another cs file goes there
    internal enum RawInputDeviceFlags
        {
            /// <summary>No flags.</summary>
            NONE = 0,
            /// <summary>If set, this removes the top level collection from the inclusion list. This tells the operating system to stop reading from a device which matches the top level collection.</summary>
            REMOVE = 0x00000001,
            /// <summary>If set, this specifies the top level collections to exclude when reading a complete usage page. This flag only affects a TLC whose usage page is already specified with PageOnly.</summary>
            EXCLUDE = 0x00000010,
            /// <summary>If set, this specifies all devices whose top level collection is from the specified UsagePage. Note that Usage must be zero. To exclude a particular top level collection, use Exclude.</summary>
            PAGEONLY = 0x00000020,
            /// <summary>If set, this prevents any devices specified by UsagePage or Usage from generating legacy messages. This is only for the mouse and keyboard.</summary>
            NOLEGACY = 0x00000030,
            /// <summary>If set, this enables the caller to receive the input even when the caller is not in the foreground. Note that WindowHandle must be specified.</summary>
            INPUTSINK = 0x00000100,
            /// <summary>If set, the mouse button click does not activate the other window.</summary>
            CAPTUREMOUSE = 0x00000200,
            /// <summary>If set, the application-defined keyboard device hotkeys are not handled. However, the system hotkeys; for example, ALT+TAB and CTRL+ALT+DEL, are still handled. By default, all keyboard hotkeys are handled. NoHotKeys can be specified even if NoLegacy is not specified and WindowHandle is NULL.</summary>
            NOHOTKEYS = 0x00000200,
            /// <summary>If set, application keys are handled.  NoLegacy must be specified.  Keyboard only.</summary>
            APPKEYS = 0x00000400,
            /// If set, this enables the caller to receive input in the background only if the foreground application
            /// does not process it. In other words, if the foreground application is not registered for raw input,
            /// then the background application that is registered will receive the input.
            /// </summary>
            EXINPUTSINK = 0x00001000,
            DEVNOTIFY = 0x00002000
        }

        public enum HidUsagePage : ushort
        {
            /// <summary>Unknown usage page.</summary>
            UNDEFINED = 0x00,
            /// <summary>Generic desktop controls.</summary>
            GENERIC = 0x01,
            /// <summary>Simulation controls.</summary>
            SIMULATION = 0x02,
            /// <summary>Virtual reality controls.</summary>
            VR = 0x03,
            /// <summary>Sports controls.</summary>
            SPORT = 0x04,
            /// <summary>Games controls.</summary>
            GAME = 0x05,
            /// <summary>Keyboard controls.</summary>
            KEYBOARD = 0x07,
        }

        public enum HidUsage : ushort
        {
            /// <summary>Unknown usage.</summary>
            Undefined = 0x00,
            /// <summary>Pointer</summary>
            Pointer = 0x01,
            /// <summary>Mouse</summary>
            Mouse = 0x02,
            /// <summary>Joystick</summary>
            Joystick = 0x04,
            /// <summary>Game Pad</summary>
            Gamepad = 0x05,
            /// <summary>Keyboard</summary>
            Keyboard = 0x06,
            /// <summary>Keypad</summary>
            Keypad = 0x07,
            /// <summary>Muilt-axis Controller</summary>
            SystemControl = 0x80,
            /// <summary>Tablet PC controls</summary>
            Tablet = 0x80,
            /// <summary>Consumer</summary>
            Consumer = 0x0C,
        }

That device - card scanner, is HID that emulating keyboard in system. All works but I have problem: messages from device goes no only for my app (that works in the background, in the tray) but to active window app too. How I can disable that and set message available only for my app?

c#
winapi
raw-input
asked on Stack Overflow Oct 7, 2014 by UndeadDragon

2 Answers

1

Raw Input does not support what you are asking for. Multiple apps are allowed to register for the same device, there is no option to gain exclusive access. You would have to use SetWindowsHookEx() to intercept and discard WM_INPUT messages, and WM_KEY... related messages (assuming the other apps are not using the RIDEV_NOLEGACY flag), that are not directed at your window.

answered on Stack Overflow Oct 7, 2014 by Remy Lebeau
1

Ok, I spend a lot of time to solve that problem and here are results and illustration for it: Keyboard message path in Windows

  1. I can't use Raw Input because on this level message already reached all applications that register that device for input data as my.
  2. I can't use low level keyboard hooks because WinAPI provides no information about device in hook. Yes, that's unbelievable, but design of that API is so bad.
  3. The only way (I'm sure of it) is to use kernel modules. If you need to solve that problem, you can write it yourself or use this library on C++. It works perfect, have very good get started on english and solved my problem. Yes, it is no C# but it is not problem for me. If you need it on C# try to use this code in managable C++.
answered on Stack Overflow Oct 12, 2014 by UndeadDragon

User contributions licensed under CC BY-SA 3.0