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?
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;
}
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.
精彩评论