1

编辑:

我需要先研究一些奇怪的东西,有什么办法可以“搁置”这个问题吗?

原来的:

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

当我们从“SubWindow”调用 AfxMessageBox 时,MainWindow 重新启用并获得焦点。

调试到 AfxMessagebox 显示,该函数获取 mainWindow 并重新启用它。这会导致许多不同的错误。使用 ::MessageBox 可以正常工作,但是我们有大约 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();

首选方式是什么?我应该评论该行以使成员保持为空吗?

还是会导致任何副作用?

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

AfxGetApp()->m_pMainWnd = &subDlg;

在 subDlg.DoModal() 之前并在之后重置它,但这也意味着更改 50 个不同的文件,每个子窗口一个。

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

编辑:

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

这是 MainWindow 重新启用的地方: 在此处输入图像描述

这是 MFC 找到 MainWindow 的地方: 在此处输入图像描述 我需要手动设置 m_pActiveWnd 吗?

(题外话:我喜欢有可用的 mfc 源代码。)

编辑2:

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

如果由loader.exe加载,则不会出现错误。

4

1 回答 1

1

MFC 在很多情况下都依赖于 m_pMainWnd。将其保留为 NULL 不是一个好方法,也不能解决您的问题。

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

尝试将当前活动的对话框传递给您正在调用的子对话框。CDialog“自动”找到父级。但有时它对我不起作用。我遇到了同样的问题,即在消息框或 DoModal 之后再次启用了错误对话框。

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

于 2013-12-06T08:08:48.860 回答