当滚轮滚动WPF DataGrid时,如何避免溢出

时间:2009-08-26 08:45:54

标签: wpf mouse wpftoolkit

当我使用鼠标滚轮在Vista 64计算机上滚动WPF Toolkit DataGrid时,我得到一个神秘的低级别错误:

   at System.IntPtr.op_Explicit(IntPtr value)
   at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)

我记录了issue on CodePlex

但有没有人找到办法解决这个问题?

2 个答案:

答案 0 :(得分:1)

我自己也遇到过这个问题。

不确定它是否对您有用,但这是我发现的修复,以防其他人也需要它。

我在OpenTK项目中找到了this线程,它闻起来很像我在Vista 64机器上的WPF项目所遇到的问题。就像在该线程中解释的那样,问题似乎是MouseWheel消息的wParam上的错误处理的唱歌位。当HwndMouseInputProvider调用尝试将wParam IntPtr强制转换为int时,会发生溢出异常。

所以解决方法是添加一个钩子来过滤主窗口上的窗口消息。钩子回调检查WM_MOUSEWHEEL消息的wparam值。如果值溢出然后值移位以恢复正确的位信息,则将当前消息标记为已处理,并使用新值发布新消息。

public partial class Window1 : Window
{    
    private const int WM_MOUSEWHEEL = 0x020A;

    public Window1()
    {
        InitializeComponent();

        SourceInitialized += (o, e) =>
        {
            HwndSource source = PresentationSource.FromVisual(this) as HwndSource;
            source.AddHook(WndProc);
        };
    }

    [DllImport("user32.dll")]
    private static extern IntPtr PostMessage(IntPtr hwnd, IntPtr msg, IntPtr wParam, IntPtr lParam);

    private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
    {
        switch (msg)
        {
            case WM_MOUSEWHEEL:
                // Check that wParam won't cause an OverflowException 
                if ((long)wParam >= (long)Int32.MaxValue)
                {
                    // Filter the evenet
                    handled = true;

                    HwndSource source = PresentationSource.FromVisual(this) as HwndSource;
                    // Repost the event with the proper value
                    PostMessage(source.Handle, new IntPtr(msg), new IntPtr((long)wParam << 32 >> 32), lParam);
                }

                break;
        }

        return IntPtr.Zero;
    }

这适合我。如果有人可以添加或更正任何东西会很棒! ķ

答案 1 :(得分:0)

这个bug存在于Microsoft的库中,令人难以置信的是它仍然存在。

为了规避它,假设你有Visual Studio并且你是开发人员:

右键单击该项目并选择 - &gt;特性

选择“构建”选项卡。 平台目标:x86

然后重建项目。

背景:

我有一个非常好的程序在32位操作系统上工作。然后我买了一台装有Windows 7 64位操作系统的新笔记本电脑。安装了Visual Studio和我的解决方案。一个处理Windows消息以使用WndProc处理用户输入的项目失败。你的类似处理鼠标消息。

在微软的Visual Studio团队找不到补丁之后,我将平台目标从“任何CPU”更改为“x86”,将其重新部署到64位操作系统,并看到程序正常运行。这是唯一的改变。

相关问题