我试图获取旧版MFC应用程序和新的WPF用户控件,以根据WPF用户控件中的按钮按下关闭对话框窗口。从本质上讲,我想了解如何获得MFC返回的DoModal()
功能。
由于各种原因,对话框是通过CDialog
启动的MFC DoModal
,它承载单个WPF组件而没有其他内容。然后该组件有一个按钮,在执行一些不同的任务后需要关闭CDialog
。这个应用程序是一个遗留下来的遗留案例,很难跟踪控制流程以及驱动这个东西的实际消息泵所处的位置。它也充满了#defines
,使得一切都变得难以应对。我认为我已经确定了消息泵,所以我认为我可以在其中插入一些东西以使其接近 - 如果我可以从WPF控件获得它。
我不知道如何将windows消息从usercontrol发送到主机,或者如何从usercontrol获取主机的HWND
。我确定有办法实现这一目标,或者是另一种更好的沟通方式吗?
向父WM_CLOSE
发送HWND
邮件的正确方法是什么?或者也许我可以向对话泵发送WM_USER
并处理那里的实际关闭?
答案 0 :(得分:4)
试试这个。它应该适用于任何WPF元素(如果它是一个Visual),通过查找它包含HWND,跟踪HWND树直到它找到根父,然后发送WM_CLOSE消息。
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
private static extern IntPtr GetParent(IntPtr hWnd);
//I'd double check this constant, just in case
static uint WM_CLOSE = 0x10;
private void CloseContainingWindow(Visual visual)
{
// Find the containing HWND for the Visual in question
HwndSource wpfHandle = PresentationSource.FromVisual(this) as HwndSource;
if (wpfHandle == null)
{
throw new Exception("Could not find Window handle");
}
// Trace up the window chain, to find the ultimate parent
IntPtr hWindow = wpfHandle.Handle;
while (true)
{
IntPtr parentHWindow = GetParent(hWindow);
if (parentHWindow == (IntPtr)0) break;
hWindow = parentHWindow;
}
// Now send the containing window a close message
SendMessage(hWindow, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
}
答案 1 :(得分:2)
在控件中声明一个close事件。关闭关闭按钮时提升事件。
在您的CDialog派生类中,订阅该事件,然后在事件处理程序中调用EngDialog。
答案 2 :(得分:0)
WM_CLOSE应该可以使用,但你必须尝试一下。 另一种方法是将WM_COMMAND消息发布到父对话框。 发送WM_USER看起来太复杂了。