7

The OS is Windows 8 on a Retina Macbook PRO.

i need to support both vertical scrolling using the trackpad and horizontal scrolling in my app.

I would like to move the WPF scrollviewer position based on the two finger swipes up-down (vertical scrolling) and left-right (horizontal scrolling).

As far as i see the vertical scrolling on the trackpad gets translated to a mouse wheel event in the framework. However, I found no way to recognize if a mouse wheel event is a horizontal scroll.

what events should i handle in WPF to be able to implement this?

4

3 回答 3

1

我专门为您写了一篇文章,让您了解如何在 WPF 应用程序中处理触摸板的水平滚动。那就是在WPF应用程序中支持触摸板的水平滚动 - walterlv


我们需要WM_MOUSEHWHEEL从 WPF 窗口中获取消息。是的!那个鼠标滚轮消息。我们之前从它获取垂直数据,但现在我们从它获取水平数据。

首先,我们应该挂钩窗口消息。

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)
{
    // Handle window message here.
    return IntPtr.Zero;
}

接下来,处理WM_MOUSEHWHEEL

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>
/// Gets high bits values of the pointer.
/// </summary>
private static int HIWORD(IntPtr ptr)
{
    var val32 = ptr.ToInt32();
    return ((val32 >> 16) & 0xFFFF);
}

/// <summary>
/// Gets low bits values of the pointer.
/// </summary>
private static int LOWORD(IntPtr ptr)
{
    var val32 = ptr.ToInt32();
    return (val32 & 0xFFFF);
}

private void OnMouseTilt(int tilt)
{
    // Write your horizontal handling codes here.
}

OnMouseTilt您可以在方法中编写水平滚动代码。

更好的是,您可以将上述所有代码打包到一个更常见的类中,并像引发事件MouseTilt一样引发MouseWheel事件。

于 2017-11-23T14:06:50.413 回答
0

向左滚动时改进walterlv的答案并修复 64 位系统上的算术溢出:

/// <summary>
/// Gets high bits values of the pointer.
/// </summary>
private static int HIWORD(IntPtr ptr)
{
    unchecked
    {
        if (Environment.Is64BitOperatingSystem)
        {
            var val64 = ptr.ToInt64();
            return (short) ((val64 >> 16) & 0xFFFF);
        }
        var val32 = ptr.ToInt32();
        return (short) ((val32 >> 16) & 0xFFFF);   
    }
}

/// <summary>
/// Gets low bits values of the pointer.
/// </summary>
private static int LOWORD(IntPtr ptr)
{
    unchecked
    {
        if (Environment.Is64BitOperatingSystem)
        {
            var val64 = ptr.ToInt64();
            return (short)(val64 & 0xFFFF);
        }

        var val32 = ptr.ToInt32();
        return (short)(val32 & 0xFFFF);
    }
}
于 2021-11-12T14:45:02.550 回答
0

完成答案walterlv

private void OnMouseTilt(int tilt)
{
    UIElement element = Mouse.DirectlyOver as UIElement;

    if (element == null) return;

    ScrollViewer scrollViewer = element is ScrollViewer viewer ? viewer : FindParent<ScrollViewer>(element);

    if (scrollViewer == null)
        return;

    scrollViewer.ScrollToHorizontalOffset(scrollViewer.HorizontalOffset + tilt);
}

public static T FindParent<T>(DependencyObject child) where T : DependencyObject
{
    DependencyObject parentObject = VisualTreeHelper.GetParent(child);

    if (parentObject == null) return null;

    T parent = parentObject as T;
    if (parent != null)
        return parent;
    else
        return FindParent<T>(parentObject);
}
于 2021-11-08T20:59:06.563 回答