基于CDialog的应用程序应该设置AfxGetApp() - > m_pMainWnd

时间:2013-12-05 18:03:42

标签: c++ mfc cdialog

修改

我需要首先研究一些奇怪的东西,是否有某种方法可以将问题“搁置”?

原始

我正在使用基于CDialog的GUI处理现有代码库。该应用程序包含一个CDialog“MainWindow”,它使用CDialog.DoModal生成其他CDialog“SubWindow”。 当显示SubWindow,MainWindow块等时,这确实有效。

当我们从“SubWindow”调用AfxMessageBox时,MainWindow会重新启用并重点关注。

调试到AfxMessagebox显示,该函数获取mainWindow并重新启用它。这会导致很多不同的错误。使用:: MesageBox正常工作,但我们有大约50个不同的SubWindows,如果可能的话,我只想进行小的局部更改。

C:\ Program Files(x86)\ Microsoft Visual Studio 11.0 \ VC \ atlmfc \ src \ mfc \ appui1.cpp

int CWinApp::ShowAppMessageBox(CWinApp *pApp, LPCTSTR lpszPrompt, UINT nType, UINT nIDPrompt)
...
HWND hWndTop;
HWND hWnd = CWnd::GetSafeOwner_(NULL, &hWndTop);

// re-enable the parent window, so that focus is restored 
// correctly when the dialog is dismissed.
if (hWnd != hWndTop)
    EnableWindow(hWnd, TRUE);
...

在我们的入口点,我们做了类似的事情:

::AfxGetApp()->m_pMainWnd = &mainDlg;
mainDlg.DoModal();

首选方式是什么?我应该评论该行,以便该成员保持NULL?

或者是否会引起任何副作用?

我猜(尚未测试)我也可以设置

AfxGetApp()->m_pMainWnd = &subDlg;
在subDlg.DoModal()之前

并在之后重置它,但这也意味着更改50个不同的文件,每个SubWindow一个。

MFC是否依赖于m_pMainWnd,还是应该让它保持为NULL? 感谢。

修改

我尝试将MainWindow传递给SubWindow的构造函数,但无济于事。

这是MainWindow重新启用的地方: enter image description here

这是MFC找到MainWindow的地方: enter image description here 我需要手动设置m_pActiveWnd吗?

(关闭主题:我喜欢mfc的源代码可用。)

编辑2:

MFC App实际上是一个DLL,可以通过两种方式调用: 由简单的loader.exe加载,或由任何大型应用程序加载。 这个其他应用程序也可能使用MFC,因此可能有两个不同的CWinApp对象。

如果它由loader.exe加载,则不会发生错误。

1 个答案:

答案 0 :(得分:1)

在很多情况下,MFC依赖于m_pMainWnd。保持NULL不是一个好方法,它不会解决你的问题。

主要问题是接缝更加微妙。问题是为什么AfxMessageBox找到主对话框作为最后一个活动而不是你的子菜单。如果在创建新的基于子对话框的con CDialog时没有定义pParent,这可能只是一个问题。

尝试将当前处于活动状态的对话框传递给您正在调用的子对话框。 CDialog“自动”找到父级。但有时它对我没用。 我遇到了在消息框或DoModal之后再次启用了wrond对话框的问题。

我修复它,在创建子对话框时始终定义父对象。