当MFC对话框与内部托管的WinForms控件一起被停用并再次激活时,不响应

当MFC对话框与内部托管的WinForms控件一起被停用并再次激活时,不响应,winforms,mfc,message-pump,Winforms,Mfc,Message Pump,我指的是msdn文章“在MFC对话框中托管Windows窗体用户控件”[link](),以在MFC遗留应用程序中重用Windows窗体用户控件。使用奇特的DDX_ManagedControl实用程序,我可以看到控件(MyPanel类)嵌入到对话框中,甚至可以100%看到选项卡 然后我向前移动,使宿主对话框成为另一个模式对话框的子对话框,然后当我的WinForms面板上的一个文本框获得键盘焦点时,问题就会出现,我切换到另一个应用程序窗口(不同的进程)以停用当前对话框,下次我再次激活MFC对话框时,

我指的是msdn文章“在MFC对话框中托管Windows窗体用户控件”[link](),以在MFC遗留应用程序中重用Windows窗体用户控件。使用奇特的DDX_ManagedControl实用程序,我可以看到控件(MyPanel类)嵌入到对话框中,甚至可以100%看到选项卡

然后我向前移动,使宿主对话框成为另一个模式对话框的子对话框,然后当我的WinForms面板上的一个文本框获得键盘焦点时,问题就会出现,我切换到另一个应用程序窗口(不同的进程)以停用当前对话框,下次我再次激活MFC对话框时,它不再有反应了

澄清问题的一些代码: //在我的MFC子对话框中 CWInformControl 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);
}
一些意见:

  • 在上述情况下,如果我使用Spy++监视当前进程中的所有WM_Activatexx消息,我发现在出现问题的停用和重新激活时未捕获WM_ACTIVATE或WM_ACTIVATEAPP消息,也未发现任何其他消息,即消息泵已关闭
  • 相比之下,对于仅带有MFC控件的普通MFC子对话框,当一个文本框获得焦点后发生停用和重新激活时,它仍在响应,我可以看到所有WM_Activatexx消息
  • 如果我直接将WinForms控件宿主到模式MFC对话框中,那么问题就消失了。然而,我需要一个临时的modales对话框,因为在我的例子中,我使用TreeView,其中每个树节点将加载一个不同的modales对话框

  • 今天,我通过在模式对话框中添加一个ON_WM_ACTIVATE宏和一个具有正确签名的空白消息处理程序,成功地解决了这个问题。供参考

    //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
    }
    

    今天,我通过在模式对话框中添加一个ON_WM_ACTIVATE宏和一个具有正确签名的空白消息处理程序,成功地解决了这个问题。供参考

    //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
    }