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