I'm working on an MFC app. I have a class inheriting from CWinApp
which tries to open an AfxMessageBox
inside its InitInstance
function.
When the AfxMessageBox
function is called, no message-box is visible, but I hear a Windows bell sound. If I press Alt, the message box appears. Why isn't the AfxMessageBox
appearing immediately?
This question mentions a similar issue, but the answer only refers to the non-MFC function MessageBox
, not AfxMessageBox
which is what I'm using:
MFC MessageBox Not Showing at Top Of All Windows
I'm working on a minimal reproducible example, but it's tricky because this is part of a large application with poor encapsulation.
In my app, it appears that a call to the function ProcessShellCommand()
is causing AfxMessageBox
to stop working. However, calls to AfxMessageBox
work correctly both before and after ProcessShellCommand
in a newly-created MFC application.
It looks like some consequence of calling ProcessShellCommand
is causing AfxMessageBox
to behave differently, but I'm not sure how to identify all the consequences of calling ProcessShellCommand
. When I'm debugging, the particular call to ProcessShellCommand includes a filename, so the file-open command is causing the app's CView
to be launched.
In the OnInitialUpdate
code for my CView
-inheriting class, AfxMessageBox
functions correctly. The best transition point I can identify between AfxMessageBox
working, and not working, is when the CView
's OnInitialUpdate
function returns from it being called by ProcessShellCommand
.
It seems that m_pMainWnd
is NULL
before the call to ProcessShellCommand
(while AfxMessageBox
is working as expected), and non-NULL
after the call to ProcessShellCommand
.
Based on this discussion:
Why would a message box be not displaying?
, I tried printing out the message-queue contents before and after the call to ProcessShellCommand
. Before, the message-queue only contains a single message. Afterwards, the message-queue printout loop is full of WM_PAINT
and it never terminates until I press Alt. This makes me think that I'm running into a message-pump-related issue rather than something related to e.g. visibility state.
---------- More observations ------------
It looks like the call to AfxMessageBox stops inside win32u.dll; I determined this by hitting the 'pause execution' button while waiting for the message-box to appear. Here's the call-stack and debug screenshot:
It turns out that my CWinApp
had a CFrameWnd
class that I had forgotten about; I was focusing too much on the CView
class.
In the CFrameWnd
class, in the BEGIN_MESSAGE_MAP
block, there was an ON_WM_TIMER()
. I removed this from the message-map to test, and the AfxMessageBox() worked as expected.
When I create a fresh SDI application, there is no ON_WM_PAINT()
in the message-map block, so I think this may have been added incorrectly. The class itself does not implement OnPaint()
, so I guess this caused some unhandled WM_PAINT
messages to be floating around.
It's a bit surprising that this doesn't lead to a compiler error; as I understand it, having ON_WM_PAINT()
only makes sense if there's a corresponding OnPaint()
function.