Question

I have a WPF app with a usercontrol that contains a HwndHost. The HwndHost is created as follows:

  hwndHost = CreateWindowEx(0, "static", "",
                            WS_CHILD | WS_VISIBLE,
                            0, 0,
                            hostHeight, hostWidth,
                            hwndParent.Handle,
                            (IntPtr)HOST_ID,
                            IntPtr.Zero,
                            0);

  hwndControl = CreateWindowEx(0, "Static", "",
                                WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN
                                  ,
                                0, 0,
                                hostHeight, hostWidth,
                                hwndHost,
                                (IntPtr)PICTUREBOX_ID,
                                IntPtr.Zero,
                                0);

I then hook into the message pump using HwndSourceHook and loads of messages come through.

Except the ones I want i.e. WM_MOUSEMOVE, WM_MOUSEHOVER, WM_LBUTTONDOWN and WM_LBUTTONUP

Also the OnMouseLeftButtonDown event is not fired in the WPF code on the main window or the control, I assume because windows is trapping it and throwing it away.

Anybody know how I can get these to come through, either with or without using the WIN32 window messages?

Was it helpful?

Solution

You need to handle WM_NCHITTEST. Until you do, it won't send you mouse messages.

// C++/CLI implementation of HwndHost.WndProc().
virtual IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, bool% handled) override
{
    switch (msg)
    {
        case WM_NCHITTEST:
        {
            handled = true;
        return IntPtr(HTCLIENT);
        }
    }

    return IntPtr::Zero;
}

OTHER TIPS

It would appear that the Border element in WPF prevents the OnMouseLeftButtonDown being thrown. My temporary solution until I find a better one is to change the WPF border to a WPF button then all mouse events are triggered.

Not ideal for most people but as I am using it to render 3D onto it doesn't matter what is underneath it.

Why don't you register a WndClass and get messages delivered to your own WndProc instead of hooking the message pump? I suspect you'd get much better results.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top