views:

43

answers:

2

When I use the mouse wheel to scroll the WPF Toolkit DataGrid on a Vista 64 Machine I get a cryptic low level error:

   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)

I logged an issue on CodePlex.

But has anyone found a way to resolve this already?

A: 

This bug is within Microsoft's libraries and it is unbelievable that its still there.

To circumvent it presuming you have Visual Studio and you are the developer:

Right click on the project and select -> Properties

Select the Build tab. Platform Target: x86

Then rebuild the project.

Background:

I had a perfectly good program working on 32 bit OS's. Then I bought a new laptop with Windows 7 64 Bit OS. Installed Visual Studio and my solutions. One project that processes windows messages to handle user input with WndProc failed. Yours is similar processing mouse messages.

After finding no patch by Microsoft's Visual Studio team, I changed the platform target from "Any CPU" to "x86", redeployed it to the 64 Bit OS, and saw program operate correctly. This was the only change.

Roger
A: 

I just run into this issue myself.

Not sure if it is still usefull to you but here is the fix I found in case anyone else needs it as well.

I found this thread in the OpenTK project that smelled a lot like the problem I was having for a WPF project in a vista 64 machine. Like explained in that thread, the problem seems to be a misshandled sing bit on the wParam of the MouseWheel message. The Overflow exception happens in the HwndMouseInputProvider call when it tries to cast the wParam IntPtr to an int.

So the workaround is adding a hook to filter windows messages on the main window. The hook callback checks the value of wparam for the WM_MOUSEWHEEL message. If the value overflows then the value shifter around to recover the right bit information, the current message is marked as handled, and a new message is posted with the new value.

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;
    }

This works well for me. If anyone can add or correct anything would be great! K

CtzKane