GLControl has defined various mouse events (such as MouseDown
, MouseMove
etc.). These events are raised even if touch or stylus is used for interaction.
However, I am curious to know if there is a way to distinguish between these events. In other words, I'd like to handle touch events differently than mouse events. How can this be done?
From what I've seen, you have to determine the event yourself. This question and this MSDN page helped me.
To summarize, in order to determine what triggered the event, you need to call GetMessageExtraInfo()
from user32.dll
. The MSDN article describes how to distinguish between the three inputs based on the bits set on the result of the call. Here's the code I whipped up for this purpose:
/// <summary>
/// The sources of the input event that is raised and is generally
/// recognized as mouse events.
/// </summary>
public enum MouseEventSource
{
/// <summary>
/// Events raised by the mouse
/// </summary>
Mouse,
/// <summary>
/// Events raised by a stylus
/// </summary>
Pen,
/// <summary>
/// Events raised by touching the screen
/// </summary>
Touch
}
/// <summary>
/// Gets the extra information for the mouse event.
/// </summary>
/// <returns>The extra information provided by Windows API</returns>
[DllImport("user32.dll")]
private static extern uint GetMessageExtraInfo();
/// <summary>
/// Determines what input device triggered the mouse event.
/// </summary>
/// <returns>
/// A result indicating whether the last mouse event was triggered
/// by a touch, pen or the mouse.
/// </returns>
public static MouseEventSource GetMouseEventSource()
{
uint extra = GetMessageExtraInfo();
bool isTouchOrPen = ((extra & 0xFFFFFF00) == 0xFF515700);
if (!isTouchOrPen)
return MouseEventSource.Mouse;
bool isTouch = ((extra & 0x00000080) == 0x00000080);
return isTouch ? MouseEventSource.Touch : MouseEventSource.Pen;
}
For my purposes, I'v overridden OnMouse*
events in the GLControl class and perform the check using the function above and invoke my custom event handlers accordingly.