winformsmfcmessage-pump

When MFC dialog with a WinForms control hosted inside is deactivated and activated again, not responding then


I'm referring to msdn article "Hosting a Windows Form User Control in an MFC Dialog Box" [link] (http://msdn.microsoft.com/en-us/library/94t3ebxz.aspx), to reuse windows form user controls in MFC legacy application. With the fancy DDX_ManagedControl utility, I'm able to see the control (MyPanel class) right embedded into the dialog, even tabs through works 100%.

Then I move forward to make the hosting dialog a child of another modal dialog, then the problem comes when one of the textboxes on my WinForms panel gets the keyboard focus and I switch to another application window (different process) to deactivate current dialog, next time when I activate the MFC dialog again, it's not responding any more.

Some code to clarify the issue: //in my MFC child dialog CWinFormsControl m_ctrl1;

void CMyWinFormControlTab::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    DDX_ManagedControl(pDX, IDC_MYPANEL_STATIC, m_ctrl1);
}

//in my out-most modal dialog
BOOL CMFCAppTestDlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    CDialog *pNewTab = new CMyWinFormControlTab();
    pNewTab->Create(IDD_MYWINFORMTAB, this);
    pNewTab->ShowWindow(SW_SHOW);
}

Some observations:

  1. In the case aforementioned, if I use Spy++ to monitor all WM_ACTIVATEXXX message in current process, I found no WM_ACTIVATE or WM_ACTIVATEAPP messages captured when the problematic deactivation and re-activation happens, neither any other messages, i.e. message pump is dead.
  2. By contrast, for normal MFC child dialog with MFC controls only, when deactivation and reactivation occur after one textbox gets focus, it's still responding and I can see all WM_ACTIVATEXXX messages.
  3. If i directly host my WinForms control into a modal MFC dialog, the problem is gone. However, I need a interim modaless dialog, for in my case I use TreeView in which each tree node will load a different modaless dialog.

Solution

  • today I managed to overcome this problem by adding a ON_WM_ACTIVATE macro and a blank message handler with correct signature to the modal dialog. FYI

    //in header
    afx_msg void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized);
    
    //in implementation cpp
    BEGIN_MESSAGE_MAP(CMyDialog, CDialog)
        //{{AFX_MSG_MAP(CMyDialog)
        ON_WM_ACTIVATE()
        //}}AFX_MSG_MAP
    END_MESSAGE_MAP()
    
    void CMyDialog::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)
    {
        //you can leave it blank
    }