Search code examples
c#wpfinterophwndhwndhost

Implement HwndHost to handle MouseMove and MouseWheel in C# WPF


I am trying to host DirectX content inside WPF app. What I learnt from this link is to subclass HwndHost and create your own implementation of WndProc as well BuildWindowCore and DestroyWindowCore. https://learn.microsoft.com/en-us/dotnet/framework/wpf/advanced/walkthrough-hosting-a-win32-control-in-wpf#implement-a-class-to-host-the-microsoft-win32-control

I then found pretty much useful implemenation following the same here: https://github.com/Smartrak/WpfSharpDxControl/blob/master/WpfSharpDxControl/Win32HwndControl.cs

Now, I need to implement two more methods such as WM_MOUSEMOVE (0x0200) and WM_MOUSEWHEEL (0x020A). I am not sure how to do that properly to pass information such as mouse wheel delta and timestamp. Any pointer in this direction would really be helpful.

protected override IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
    {
        switch (msg)
        {
            case NativeMethods.WM_MOUSEMOVE:
                //What should go here
                break;
            case NativeMethods.WM_MOUSEWHEEL:
                //What should go here
                break;
            case NativeMethods.WM_LBUTTONDOWN:
                RaiseMouseEvent(MouseButton.Left, Mouse.MouseDownEvent);
                break;

            case NativeMethods.WM_LBUTTONUP:
                RaiseMouseEvent(MouseButton.Left, Mouse.MouseUpEvent);
                break;

            case NativeMethods.WM_RBUTTONDOWN:
                RaiseMouseEvent(MouseButton.Right, Mouse.MouseDownEvent);
                break;

            case NativeMethods.WM_RBUTTONUP:
                RaiseMouseEvent(MouseButton.Right, Mouse.MouseUpEvent);
                break;
        }

        return base.WndProc(hwnd, msg, wParam, lParam, ref handled);
    }

Thanks, Jay


Solution

  • I finally found the answer and exact implementation I wanted here:

    https://github.com/tgjones/gemini/blob/master/src/Gemini/Framework/Controls/HwndWrapper.cs

    It just works perfect. If you get OverFlow exception for NativeMethods.GetWheelDeltaWParam(Convert.ToInt32(value));

    Use NativeMethods.GetWheelDeltaWParam(Convert.ToInt64(value));

    Full credit to Tim Jones for this awesome github repo and work! https://github.com/tgjones