Skip to content

Instantly share code, notes, and snippets.

@vbfox
Created November 4, 2011 15:54
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save vbfox/1339671 to your computer and use it in GitHub Desktop.
Save vbfox/1339671 to your computer and use it in GitHub Desktop.
Globally disable the conversion of touch events to mouse events in Windows 7
namespace BlackFox
{
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Security;
/// <summary>
/// As long as this object exists all mouse events created from a touch event for legacy support will be disabled.
/// </summary>
class DisableTouchConversionToMouse : IDisposable
{
static readonly LowLevelMouseProc hookCallback = HookCallback;
static IntPtr hookId = IntPtr.Zero;
public DisableTouchConversionToMouse()
{
hookId = SetHook(hookCallback);
}
static IntPtr SetHook(LowLevelMouseProc proc)
{
var moduleHandle = UnsafeNativeMethods.GetModuleHandle(null);
var setHookResult = UnsafeNativeMethods.SetWindowsHookEx(WH_MOUSE_LL, proc, moduleHandle, 0);
if (setHookResult == IntPtr.Zero)
{
throw new Win32Exception();
}
return setHookResult;
}
delegate IntPtr LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam);
static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0)
{
var info = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));
var extraInfo = (uint)info.dwExtraInfo.ToInt32();
if ((extraInfo & MOUSEEVENTF_FROMTOUCH) == MOUSEEVENTF_FROMTOUCH)
{
return new IntPtr(1);
}
}
return UnsafeNativeMethods.CallNextHookEx(hookId, nCode, wParam, lParam);
}
bool disposed;
public void Dispose()
{
if (disposed) return;
UnsafeNativeMethods.UnhookWindowsHookEx(hookId);
disposed = true;
GC.SuppressFinalize(this);
}
~DisableTouchConversionToMouse()
{
Dispose();
}
#region Interop
// ReSharper disable InconsistentNaming
// ReSharper disable MemberCanBePrivate.Local
// ReSharper disable FieldCanBeMadeReadOnly.Local
const uint MOUSEEVENTF_FROMTOUCH = 0xFF515700;
const int WH_MOUSE_LL = 14;
[StructLayout(LayoutKind.Sequential)]
struct POINT
{
public int x;
public int y;
}
[StructLayout(LayoutKind.Sequential)]
struct MSLLHOOKSTRUCT
{
public POINT pt;
public uint mouseData;
public uint flags;
public uint time;
public IntPtr dwExtraInfo;
}
[SuppressUnmanagedCodeSecurity]
static class UnsafeNativeMethods
{
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr SetWindowsHookEx(int idHook, LowLevelMouseProc lpfn, IntPtr hMod,
uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr GetModuleHandle(string lpModuleName);
}
// ReSharper restore InconsistentNaming
// ReSharper restore FieldCanBeMadeReadOnly.Local
// ReSharper restore MemberCanBePrivate.Local
#endregion
}
}
@ulatekh
Copy link

ulatekh commented May 25, 2016

From what I can tell (running under Windows 7), touch-events converted to mouse-events are NOT reported under WH_MOUSE_LL, but instead are reported under WH_MOUSE. So I modified this code to hook into both types of events, and return new IntPtr(1) when a mouse-event created from a touch-event has been detected. Unfortunately, the system cursor is still moved to the position of the last touch. (My goal is similar to @tavoe; I want to allow one user to interact with a window using touch, and another user to interact with a different window using the mouse, on the same computer.)

Also, the call to ToInt32() on line 41 will break in a 64-bit process. One should test whether IntPtr.Size is 4 or 8, and if the latter, call ToInt64() instead.

I've forked this gist & submitted my changes.

@SaveTheHuman5
Copy link

Same as @tavoe and @ulatekh

Windows seems to automatically jump the mouse to the first touch (as you have observed).

I want prevent that happen and cant find the way.

Somebody have some news about this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment