Raising Keyboard events via an Interface in WPF

2019-09-04 09:18发布

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 !!!

1条回答
Emotional °昔
2楼-- · 2019-09-04 10:03

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.

查看更多
登录 后发表回答