Should a CDialog based app set AfxGetApp()->m_pMainWnd

3.1k views Asked by At

EDIT:

I Need to Research some weird stuff first, is there some way to put the question "on hold"?

Original:

I am working on an existing codebase using a CDialog based GUI. The Application consists of a CDialog "MainWindow", which spawns other CDialog "SubWindow"s using CDialog.DoModal. This does work, when showing the SubWindow, the MainWindow blocks, etc.

When we call AfxMessageBox from "SubWindow", the MainWindow gets reenabled and focused.

Debugging into AfxMessagebox shows, that the function gets the mainWindow and reenables it. This causes a lot of different bugs. Using ::MesageBox works correctly, but we have about 50 different SubWindows, and, if possible, i would like to make only small, localized changes.

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);
...

In our entry Point we do something like this:

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

What is the prefered way? Should i comment the line so the member stays NULL?

or could that cause any side effects?

I guess (not yet tested) i could also set

AfxGetApp()->m_pMainWnd = &subDlg;

prior to subDlg.DoModal() and reset it afterwards, but that would also mean changing 50 different files, one for every SubWindow.

Does MFC depend on m_pMainWnd, or should i just let it stay at NULL? Thanks.

EDIT:

I tried passing the MainWindow to the SubWindow's constructor, but to no avail.

This is, where MainWindow gets reenabled: enter image description here

This is, where MFC finds the MainWindow: enter image description here Do i need to manually set m_pActiveWnd ?

(OFF Topic: I love that there is the source code for mfc available.)

EDIT 2:

The MFC App is actually a DLL, which can be invoked in two ways: Either loaded by a simple loader.exe, or by anyther big application. This other application may also use MFC, so there may be two different CWinApp objects.

If it is loaded by loader.exe, the error does not occur.

1

There are 1 answers

3
xMRi On

MFC depends on m_pMainWnd in a lot of cases. Leaving it NULL isn't a good approach and it doen't fix your problem.

The main problem seams to be more subtle. The question is why does AfxMessageBox find the main dialog as the last active and not you subdialog. And this can be only a problem if you don't define a pParent when you create a new subdialog based con CDialog.

Try to pass the dialog that is currently active to the sub dialog you are calling. CDialog find the parent "automatically". But sometimes it doen't worked for me. I had the same problem that the wrond dialog was enabled again after a message box or DoModal.

I fixed it, in defining always the parent when I create the sub dialogs.