基于 CDialog 的应用程序是不是应该设置 AfxGetApp()->m_pMainWnd
Posted
技术标签:
【中文标题】基于 CDialog 的应用程序是不是应该设置 AfxGetApp()->m_pMainWnd【英文标题】:Should a CDialog based app set AfxGetApp()->m_pMainWnd基于 CDialog 的应用程序是否应该设置 AfxGetApp()->m_pMainWnd 【发布时间】:2013-12-05 18:03:42 【问题描述】:编辑:
我需要先研究一些奇怪的东西,有什么办法可以“搁置”这个问题吗?
原文:
我正在使用基于 CDialog 的 GUI 处理现有代码库。该应用程序包含一个 CDialog“MainWindow”,它使用 CDialog.DoModal 生成其他 CDialog“SubWindow”。 这在显示子窗口、主窗口块等时确实有效。
当我们从“子窗口”调用 AfxMessageBox 时,主窗口重新启用并获得焦点。
调试到 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();
首选的方式是什么?我应该评论该行以使成员保持 NULL 吗?
或者这会导致任何副作用吗?
我猜(尚未测试)我也可以设置
AfxGetApp()->m_pMainWnd = &subDlg;
在 subDlg.DoModal() 之前并在之后重置它,但这也意味着更改 50 个不同的文件,每个子窗口一个。
MFC 是否依赖于 m_pMainWnd,还是应该让它保持为 NULL? 谢谢。
编辑:
我尝试将 MainWindow 传递给 SubWindow 的构造函数,但无济于事。
这是 MainWindow 重新启用的地方:
这是 MFC 找到 MainWindow 的地方: 我需要手动设置 m_pActiveWnd 吗?
(OFF 主题:我喜欢有可用的 mfc 源代码。)
编辑 2:
MFC App实际上是一个DLL,可以通过两种方式调用: 由简单的 loader.exe 或任何其他大型应用程序加载。 这个其他应用程序也可能使用 MFC,因此可能有两个不同的 CWinApp 对象。
如果是loader.exe加载,则不会出现错误。
【问题讨论】:
【参考方案1】:MFC 在很多情况下都依赖于 m_pMainWnd。将其保留为 NULL 不是一个好方法,也不能解决您的问题。
主要问题接缝更加微妙。问题是为什么 AfxMessageBox 发现主对话框是最后一个活动的,而不是你的子对话框。如果您在创建新的基于子对话框的 con CDialog 时没有定义 pParent,这可能只是个问题。
尝试将当前活动的对话框传递给您正在调用的子对话框。 CDialog“自动”找到父级。但有时它对我不起作用。 我遇到了同样的问题,在消息框或 DoModal 之后再次启用了错误对话框。
我修复了它,在创建子对话框时始终定义父级。
【讨论】:
不幸的是,将 MainWindow 传递给 SubWindow 的构造函数并没有改变。 你有simle小样吗。我刚刚使用向导创建了一个,但它按预期工作。 调试到函数 CWnd::GetSafeOwner。查看此代码。 (由 ShowAppMessageBox 调用)。此代码确定被禁用和再次启用的窗口。最好使用远程调试,因为调试此代码可能会更改活动窗口...以上是关于基于 CDialog 的应用程序是不是应该设置 AfxGetApp()->m_pMainWnd的主要内容,如果未能解决你的问题,请参考以下文章
MFC中CDialog 的OnKeyDown()为啥不好使?
★VC-MFC◆CToolbarCtrl && CDialog 下拉菜单 ★