微软终于开始学苹果一样好好做触摸板了(就是键盘空格键下面那一大块)。然而鉴于以前没有好好做,以至于 WPF 程序甚至都没有对触摸板的横向滚动提供支持(竖向滚动是直接使用了 MouseWheel
,汗……)。但有些功能真希望能够支持横向滚动!
本文将介绍让触摸板支持横向滚动的方法,本质上也是用 MouseWheel
,但却支持了横向。
▲ 精确式触摸板
我们需要从 Windows 的窗口消息中获取 WM_MOUSEHWHEEL
消息。对,就是鼠标滚轮消息!以前我们只取了纵向数据,现在我们要取横向数据。
首先,我们需要能够监听得到消息才行。重写 Window
的 OnSourceInitialized
方法可以开始监听消息;如果代码没办法写到 Window
中,可以通过 Window.GetWindow(DependencyObject)
获取到窗口实例后监听它的 SourceInitialized
事件。如果拿不到这样的时机,则只要在任何 SourceInitialized
之后的时机(比如 Loaded
)都可以写下面方法内部的两行代码。
1
2
3
4
5
6
7
8
9
10
11
protected override void OnSourceInitialized(EventArgs e)
{
var source = PresentationSource.FromVisual(_board);
((HwndSource) source)?.AddHook(Hook);
}
private IntPtr Hook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
// 在这里添加消息的处理。
return IntPtr.Zero;
}
接下来,我们开始处理 WM_MOUSEHWHEEL
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
const int WM_MOUSEHWHEEL = 0x020E;
private IntPtr Hook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
switch (msg)
{
case WM_MOUSEHWHEEL:
int tilt = (short) HIWORD(wParam);
OnMouseTilt(tilt);
return (IntPtr) 1;
}
return IntPtr.Zero;
}
/// <summary>
/// 取指针所在高位数值。
/// </summary>
private static int HIWORD(IntPtr ptr)
{
var val32 = ptr.ToInt32();
return ((val32 >> 16) & 0xFFFF);
}
/// <summary>
/// 取指针所在低位数值。
/// </summary>
private static int LOWORD(IntPtr ptr)
{
var val32 = ptr.ToInt32();
return (val32 & 0xFFFF);
}
private void OnMouseTilt(int tilt)
{
// 这里就是触摸板横向滚动的时机,参数是横向滚动的数值,就像鼠标滚轮纵向滚动的数值一样。
}
OnMouseTilt
中就可以写我们触摸板横向滚动的处理代码。
以上代码都可以封装成通用的方法,在 OnMouseTilt
中抛出一个类似于 MouseWheel
一样的事件是非常好的选择。
微软的 Microsoft Sculpt Comfort Mouse 鼠标滚轮也是支持横向滚动的,以上方法也可以支持。
本文会经常更新,请阅读原文: https://blog.walterlv.com/post/handle-horizontal-scrolling-of-touchpad.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名 吕毅 (包含链接: https://blog.walterlv.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 ([email protected]) 。