有没有办法从代码中禁用鼠标升级,这会阻止Windows将触摸事件解释为鼠标事件?
我在WPF应用程序中捕获触摸事件,我不希望这些交互影响鼠标指针的可见性和位置。
有TouchFrameEventArgs.SuspendMousePromotionUntilTouchUp Method似乎正是这样做的。不幸的是,它仅适用于Silverlight和Windows Phone。
此外,还有一些系统设置可用于禁用双击和右键单击促销,但没有任何内容可以禁用整个鼠标升级。
Windows 8特定解决方案或低级别解决方案也会有所帮助。
答案 0 :(得分:2)
public static class PreventTouchToMousePromotion
{
public static void Register(FrameworkElement root)
{
root.PreviewMouseDown += Evaluate;
root.PreviewMouseMove += Evaluate;
root.PreviewMouseUp += Evaluate;
}
private static void Evaluate(object sender, MouseEventArgs e)
{
if (e.StylusDevice != null)
{
e.Handled = true;
}
}
}
采样用法:
public MainWindow()
{
InitializeComponent();
PreventTouchToMousePromotion.Register(this);
}
或者看一下这篇文章
答案 1 :(得分:0)
似乎没有任何此类选项(至少在Windows 8.1和.NET 4.5中)。
禁用鼠标升级的唯一方法是从系统控制面板中完全禁用手指输入(打开控制面板,打开“笔和触摸”,选择“触摸”选项卡,取消“使用手指作为输入”设备“)或通过注册表(HKLM \ Software \ Microsoft \ Wisp \ Touch,TouchGate = 0 =禁用触摸)
然后,您仍然可以使用以下(讨厌的)替代方案之一来处理触摸输入:
最后,您可以使用custom routed events或使用touch injection将收集的触摸数据注入您的应用程序。
在任何情况下,您都会为系统上的任何其他应用程序提供松散的触摸支持,因此这种解决方案通常对您没有太大帮助。
答案 2 :(得分:0)
禁用鼠标的触摸提升功能的普通Win32 API方法是处理窗口WindowProc
中的WM_POINTER*
条消息(实际上,似乎WM_POINTERDOWN
就足够了)并且不调用{{ 1}}。
这是我们在某些商业应用中的实际工作,以及here的建议。
这仅在Windows 8和更高版本中可用,因为DefWindowProc()
消息不是Windows 7和更低版本生成的。
现在,在WPF世界中,这变得更加复杂。
首先,为了获得WPF堆栈的正确WM_POINTER*
处理,您首先需要
(在此处报告代码,以防MS页面消失)您需要将其插入到您的app.config文件中:
WM_POINTER*
现在,新的闪亮WPF堆栈已激活,但是即使您处理OnTouchDown
,OnTouchUp
,OnTouchMove
事件并设置{{3} }标记为true。
我们发现,通过使用Handled
并阻止HwndSourceHook
消息,鼠标光标终于保持静止(尽管我们阻止了所有触地互动!)
因此,我们推断出,即使我们正在处理<configuration>
<runtime>
<AppContextSwitchOverrides value="Switch.System.Windows.Input.Stylus.EnablePointerSupport=true"/>
</runtime>
</configuration>
事件,闪亮的新WPF实际上也正在调用DefWindowProc
。
我们的灵魂是使用WM_POINTERDOWN
,以拦截OnTouch*
的呼叫,并阻止DefWindowProc
到达真实的WM_POINTERDOWN
。
绕行代码是:
DefWindowProc
注意:#include <Windows.h>
#include <detours.h>
static LRESULT(WINAPI * _originalDefWindowProcA)(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) = DefWindowProcA;
static LRESULT(WINAPI * _originalDefWindowProcW)(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) = DefWindowProcW;
static LRESULT WINAPI myDefWindowProcA(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
switch (Msg)
{
case WM_POINTERDOWN:
return 0;
default:
return _originalDefWindowProcA(hWnd, Msg, wParam, lParam);
}
}
static LRESULT WINAPI myDefWindowProcW(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
switch (Msg)
{
case WM_POINTERDOWN:
return 0;
default:
return _originalDefWindowProcW(hWnd, Msg, wParam, lParam);
}
}
void SetupDefWindowProcDetour()
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)_originalDefWindowProcA, myDefWindowProcA);
DetourAttach(&(PVOID&)_originalDefWindowProcW, myDefWindowProcW);
DetourTransactionCommit();
}
必须由应用程序的主(UI)调用。