I have no Touchpad to test, but this test with the mouse works for me with GetCurrentInputMessageSource :
[DllImport("User32.dll", SetLastError = true)]
private static extern bool GetCurrentInputMessageSource(out INPUT_MESSAGE_SOURCE inputMessageSource);
[StructLayout(LayoutKind.Sequential)]
public struct INPUT_MESSAGE_SOURCE
{
public INPUT_MESSAGE_DEVICE_TYPE deviceType;
public INPUT_MESSAGE_ORIGIN_ID originId;
}
public enum INPUT_MESSAGE_DEVICE_TYPE
{
IMDT_UNAVAILABLE = 0x00000000, // not specified
IMDT_KEYBOARD = 0x00000001, // from keyboard
IMDT_MOUSE = 0x00000002, // from mouse
IMDT_TOUCH = 0x00000004, // from touch
IMDT_PEN = 0x00000008, // from pen
IMDT_TOUCHPAD = 0x00000010, // from touchpad
}
public enum INPUT_MESSAGE_ORIGIN_ID
{
IMO_UNAVAILABLE = 0x00000000, // not specified
IMO_HARDWARE = 0x00000001, // from a hardware device or injected by a UIAccess app
IMO_INJECTED = 0x00000002, // injected via SendInput() by a non-UIAccess app
IMO_SYSTEM = 0x00000004, // injected by the system
}
public const int WM_MOUSEFIRST = 0x0200;
public const int WM_MOUSELAST = 0x020E;
public const int WM_KEYFIRST = 0x0100;
public const int WM_KEYLAST = 0x0109;
public const int WM_TOUCH = 0x0240;
public const int WM_POINTERWHEEL = 0x024E;
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
HwndSource hWndSource = PresentationSource.FromVisual(this) as HwndSource;
hWndSource.AddHook(WndProc);
}
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if ((msg >= WM_MOUSEFIRST && msg <= WM_MOUSELAST) || (msg >= WM_KEYFIRST && msg <= WM_KEYLAST) || (msg >= WM_TOUCH && msg <= WM_POINTERWHEEL))
{
INPUT_MESSAGE_SOURCE ims = new INPUT_MESSAGE_SOURCE();
GetCurrentInputMessageSource(out ims);
if (ims.deviceType == INPUT_MESSAGE_DEVICE_TYPE.IMDT_MOUSE)
{
Console.Beep(6000, 5);
}
// not tested
else if (ims.deviceType == INPUT_MESSAGE_DEVICE_TYPE.IMDT_TOUCHPAD)
{
Console.Beep(2000, 5);
}
}
return IntPtr.Zero;
}