0

I am trying to build an application in WPF, where I want to handle inputs (KeyPress events) from multiple Keyboards connected to a single computer. So, I have a single class where I override the WndProc() method and am able to receive input from different keyboard devices. While doing this, I register this class with the MainWindow handle and the window can thus receive the CLR keyboard events. But this is not a problem.

The problem is that now I am developing UserControl in WPF which can also respond to these multi-keyboard events. These UserControls will be instantiated in the same window, but I was thinking of sending the events (especially as RoutedEvents) via an interface. So that, my custom UserControl class simply implements the interface and I am good to go.

Do you guys have any idea how to do this, I am really new to WPF so I am having some difficulties.

Thanks in advance !!!

Himanshu Verma
  • 257
  • 1
  • 3
  • 10
  • Why add the extra step of an interface to "send" the events. Just attach listeners to them as you would do normally. – A.R. Jul 12 '12 at 12:16
  • Because in that case my UserControl class will have to know about the KeyboardManager class instance (which is actually raising all the keyboard events) and this KeyboardManager is instantiated in the MainWindow. – Himanshu Verma Jul 12 '12 at 12:32
  • Your user controls will have to hook to events one way or another. Besides, based on your description, everything (user controls, keyboard manager, etc.) is in the same window, so your controls are at the same scope as the manager. Unless you have grander plans in mind, just hook it up and be done with it. – A.R. Jul 13 '12 at 12:53
  • Yes, I can actually do that because this KeyboardManager instance is in the same scope. But just to keep things separated and clean, I decided to go the interface way. – Himanshu Verma Jul 18 '12 at 07:57
  • Anyways I have implemented a CLR event which notifies my custom UserControl class of keyboard events, and I can do this because I know exactly about what is the input focus (a user control) of each keyboard device and using this idea I can actually call the interface method in the exact class I wish to call. Anyways thanks A.R. for your suggestions. – Himanshu Verma Jul 18 '12 at 07:59

1 Answers1

0

So, I figured out how to do this. I have a class called BIFUserControl which implements the interface I have created to handle events from multiple keyboards attached to the same computer. The interface is called IMultiKeyboardEvents. I also have a read-only collection which stores the current state of each keyboard device as instances of BIFKeyboardDevice class.

So, basically I know what is the input focus for each keyboard device, which is represented as a property in the BIFKeyboardDevice class. So when raising a CLR event from Keyboard manager class BIFKeyboardManager I can actually call the interface method implementation in the exact class which has the input focus to a specific control.

Here is the code for the interface IMultiKeyboardEvents which is implemented by the custom user control class:

public interface IMultiKeyboardEvents  
{
    event MultiKeyEventHandler MultiKeyDown;
    event MultiKeyEventHandler MultiKeyUp;

    void OnMultiKeyDown(MultiKeyEventArgs);
    void OnMultiKeyDown(MultiKeyEventArgs);
}

And in the keyboard manager class which overrides the WndProc() method, I have a method which processes the input events which is as follows :

void ProcessInput(Message message)
{
    // Code sample which raises just the key down event
    switch (rawInput.keyboard.Message)
    {
        case (uint) BIFWin32.WindowMessage.WM_KEYDOWN:
        {
            if (BIFDeviceCollections.MouseCollection[ID].MouseFocusElement is IMultiKeyboardEvents)
            {
                IMultiKeyboardEvents widget = 
                (IMultiKeyboardEvent)BIFDeviceCollections.MouseCollection[ID].MouseFocusedElement;
                widget.OnMultiKeyDown(eventArgs);
            }
            break;
        }
        case (uint) BIFWin32.WindowMessage.WM_KEYUP:
        {
            if (BIFDeviceCollections.MouseCollection[ID].MouseFocusElement is IMultiKeyboardEvents)
            {
                IMultiKeyboardEvents widget = 
                (IMultiKeyboardEvent)BIFDeviceCollections.MouseCollection[ID].MouseFocusedElement;
                widget.OnMultiKeyUp(eventArgs);
            }
            break;
        }
    }
}

This simply calls the implementation of OnMultiKeyDown method in my UserControl class and I don't have to use use the keyboard manager instance in the user control class and hook up the events to listen to them. Also, as I have already a collection of all the device objects (mice and keyboards) and they maintain a field saying what is the current focus element for each device and also I have paired each mouse and keyboard device, so I can directly use this information to raise the events.

Himanshu Verma
  • 257
  • 1
  • 3
  • 10
  • Post some code. I'd like to see how everything is wired up, and how the interface makes it 'cleaner' – A.R. Jul 18 '12 at 17:29
  • Hi, A.R. I have posted some code. Please have a look, I really hope it is sufficient and I also thank you for your suggestions :-) – Himanshu Verma Jul 19 '12 at 09:49
  • OK, I see what you are doing here. So the implementer of the interface (IMultiKeyboard...) doesn't actually handle any events (as they aren't listening), you just send some arguments when something else handles the actual event. – A.R. Jul 19 '12 at 11:49
  • So why does your interface definition have two events defined on it? Are these used somewhere else in your code? – A.R. Jul 19 '12 at 11:50
  • Yes, exactly...the implementer of the interface does not actually handle any events. Its analogous to simple `System.Windows.Controls.Button` class which gets from the WPF framework all the input events (mouse, touch etc.) but in turn provides the programmer with other events such as `Click`. So, in my case the `BIFUserControl` class is actually a base class which I would use to develop more specific multi-keyboard widgets (such as multi-keyboard post-it). THerefore, whenever there is an input event such as a key press the UserControl class does some action as well as raises some other events – Himanshu Verma Jul 19 '12 at 13:48
  • About the 2 events in my Interface, yes I have 2 events but in the code sample I only gave an example of one event. Yes both of them are used in my code. I will actually update the code now. – Himanshu Verma Jul 19 '12 at 13:49