Пользовательский контроль WPF на MFC, как закрыть родительское окно при нажатии кнопки - PullRequest
0 голосов
/ 23 февраля 2012

Я пытаюсь получить устаревшее приложение MFC и новый пользовательский контроль WPF, чтобы закрыть диалоговое окно на основе нажатия кнопки в пользовательском контроле WPF. В сущности, я хотел бы получить несколько советов о том, как получить функцию DoModal() возврата MFC.

По разным причинам диалоговое окно представляет собой MFC CDialog, запущенный через DoModal, в котором размещается один компонент WPF и ничего больше. Этот компонент затем имеет кнопку, которая должна будет закрыть CDialog после выполнения некоторых различных задач. Это приложение является… выходящим… случаем унаследованного, и очень трудно отследить поток управления и то, где находятся фактические сообщения, управляющие этой штукой. Он также полон #defines, что делает все в два раза сложнее, чем должно быть. Я думаю Я идентифицировал насос сообщений, поэтому я думаю, что могу что-то вставить в него, чтобы сделать его ближе - если я смогу добраться до этого из элемента управления WPF.

Я не знаю, как отправить сообщение windows из usercontrol на хост или как получить HWND хоста из usercontrol. Я уверен, что есть способ получить это или другой лучший способ общения?

Правильный ли подход для отправки WM_CLOSE сообщения родителю HWND? Или, может быть, я могу отправить WM_USER в диалоговую помпу и обработать фактическое закрытие там?

Ответы [ 3 ]

4 голосов
/ 23 февраля 2012

Попробуй это. Он должен работать для любого элемента WPF (если это визуальный элемент), обнаружив, что он содержит 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);
    }
2 голосов
/ 24 февраля 2012

Объявление события закрытия в элементе управления.Вызывайте событие, когда кнопка закрытия закрыта.

В своем классе, производном от CDialog, подпишитесь на событие, а затем вызовите EngDialog в обработчике события.

0 голосов
/ 23 февраля 2012

WM_CLOSE должно работать, но вы должны попробовать это.Другой подход заключается в публикации сообщения WM_COMMAND в родительском диалоге.Отправка WM_USER выглядит слишком сложно.

...