1

Windowsフォームユーザーを再利用するには、msdnの記事「MFCダイアログボックスでのWindowsフォームユーザーコントロールのホスト」[リンク](http://msdn.microsoft.com/en-us/library/94t3ebxz.aspx)を参照しています。 MFCレガシーアプリケーションのコントロール。派手なDDX_ManagedControlユーティリティを使用すると、コントロール(MyPanelクラス)がダイアログに埋め込まれているのを確認できます。タブを介しても100%動作します。

次に、ホスティングダイアログを別のモーダルダイアログの子にするために進みます。次に、WinFormsパネルのテキストボックスの1つがキーボードフォーカスを取得し、別のアプリケーションウィンドウ(別のプロセス)に切り替えて現在のダイアログを非アクティブ化すると、問題が発生します。 MFCダイアログを再度アクティブにすると、応答しなくなります。

問題を明確にするためのいくつかのコード://MFC子ダイアログでCWinFormsControlm_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);
}

いくつかの観察:

  1. 前述の場合、Spy ++を使用して現在のプロセスのすべてのWM_ACTIVATEXXXメッセージを監視すると、問題のある非アクティブ化と再アクティブ化が発生したときにWM_ACTIVATEまたはWM_ACTIVATEAPPメッセージがキャプチャされないことがわかりました。他のメッセージ、つまりメッセージポンプが停止しています。
  2. 対照的に、MFCコントロールのみを使用する通常のMFC子ダイアログの場合、1つのテキストボックスがフォーカスを取得した後に非アクティブ化と再アクティブ化が発生すると、それは引き続き応答し、すべてのWM_ACTIVATEXXXメッセージを表示できます。
  3. WinFormsコントロールをモーダルMFCダイアログに直接ホストすると、問題は解決します。ただし、暫定的なモーダルダイアログが必要です。私の場合は、各ツリーノードが異なるモーダルダイアログをロードするTreeViewを使用しています。
4

1 に答える 1

1

今日、私は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
}
于 2012-05-07T08:41:17.817 に答える