0

当我在 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)

我在 CodePlex 上记录了一个问题

但是有人已经找到解决这个问题的方法了吗?

4

2 回答 2

1

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

不确定它是否对您仍然有用,但这是我找到的修复程序,以防其他人也需要它。

我在 OpenTK 项目中发现了这个线程,它闻起来很像我在 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;
    }

这对我很有效。如果有人可以添加或更正任何内容,那就太好了!ķ

于 2010-10-15T20:58:19.333 回答
0

这个错误在微软的库中,令人难以置信的是它仍然存在。

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

右键单击项目并选择 -> 属性

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

然后重建项目。

背景:

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

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

于 2010-05-22T15:58:25.243 回答