When MFC dialog with a WinForms control hosted inside is deactivated and activated again, not responding then
-
04-06-2021 - |
Question
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:
- 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.
- 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.
- 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
}