禁用鼠标触摸提升的普通 Win32 API 方法是处理WM_POINTER*
窗口中的消息WindowProc
(实际上,这似乎就WM_POINTERDOWN
足够了)而不是调用DefWindowProc()
.
这是我们在一些商业应用程序中实际所做的,也是这里的建议。
这仅适用于 Windows 8 及更高版本,因为WM_POINTER*
消息不是由 Windows 7 及更低版本生成的。
现在,在 WPF 世界中,这变得更加复杂。
首先,为了获得WM_POINTER*
WPF 堆栈的正确处理,您首先需要
(在这里报告代码,以防MS页面消失)您需要将其插入到您的app.config文件中:
<configuration>
<runtime>
<AppContextSwitchOverrides value="Switch.System.Windows.Input.Stylus.EnablePointerSupport=true"/>
</runtime>
</configuration>
现在,新的闪亮 WPF 堆栈已激活,但即使您处理OnTouchDown
、OnTouchUp
、OnTouchMove
事件并将Handled
标志设置为 true,它也会出现问题并移动鼠标光标。
通过使用 aHwndSourceHook
并阻止WM_POINTERDOWN
消息,我们发现鼠标光标最终保持静止(尽管我们阻止了所有触地交互!)
因此,我们推断出闪亮的新 WPF 实际上正在调用DefWindowProc
,即使我们正在处理OnTouch*
事件。
我们的想法是使用Microsoft Detours来拦截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();
}
注意:SetupDefWindowProcDetour
必须由应用程序的主 (UI) 线程调用。