我有一个WPF应用程序,可以使用鼠标和使用Touch.我禁用所有窗口"增强功能"以便只触摸事件:
Stylus.IsPressAndHoldEnabled="False"
Stylus.IsTapFeedbackEnabled="False"
Stylus.IsTouchFeedbackEnabled="False"
Stylus.IsFlicksEnabled="False"
Run Code Online (Sandbox Code Playgroud)
结果是点击的行为就像我想要的那样,除了两点:
两者都是这样一个事实的结果:当Windows正确传输触摸事件时,他仍然将鼠标移动到最后一个主触摸事件.
当我在应用程序中使用触摸时,我不希望窗口完全移动鼠标.有没有办法完全避免这种情况?
笔记:
Jul*_*lia 10
这是我从现在开始找到的最佳解决方案.不要犹豫发布自己的,特别是如果它更好.
使用SetWindowsHookEx低级别鼠标事件catch(WH_MOUSE_LL)以及从Touch转换为Mouse的所有事件都标记为这样(MOUSEEVENTF_FROMTOUCH标志在事件的ExtraInfo中设置,请参阅Microsoft的常见问题解答)我能够全局删除所有触摸后的鼠标事件面板.
它不是一个理想的解决方案,但它现在可以在我的应用程序中运行全屏幕(99%的时间,因为它是一个专用的硬件设备).
第二步也只有全屏(我不会提供代码,因为它很简单)只是将鼠标移动到屏幕右下方的"安全"位置SetCursorPos.
如果您需要代码,那么它就在Github上的Gist中,我将在本文末尾发布当前版本.要使用它:
// As long as the instance is alive the conversion won't occur
var disableTouchMouse = new DisableTouchConversionToMouse();
// To let the conversion happen again, Dispose the class.
disableTouchMouse.Dispose();
Run Code Online (Sandbox Code Playgroud)
该类的完整源代码:
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_MASK) == MOUSEEVENTF_FROMTOUCH)
{
if((extraInfo & 0x80) != 0)
{
//Touch Input
return new IntPtr(1);
}
else
{
//Pen Input
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_MASK = 0xFFFFFF00;
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
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:从故障排除应用程序和系统事件和鼠标消息的注释部分,以消除触摸笔消除歧义的其他信息.