Introduction
I recently wrote an MFC SDI application that depending on the command line argument would startup either in normal or minmized mode. I noticed when I attempted to initialize the app in minimized mode, the window would briefly "flash" in its normal state before minimizing. After searching for and not finding a simple, elegant solution to this problem, I went into the MFC code to see if I could find the source of this problem (PUN intended), and if I could resolve the issue in my client application. If you have had similar problems, please read on.
Background
The initialization and display of an MFC SDI program initially created by the MFC application wizard is handled by the InitInstance()
method of its application class. At first glance, it appears that the function that actually displays the initialized window is the ShowWindow
call that is the end of InitInstance()
. This premise is bolstered by the fact that the text comment generated by the app wizard clearly states that it is so. See below:
m_pMainWnd->ShowWindow(SW_MINIMIZE);
m_pMainWnd->UpdateWindow();
It would then seem logical that in order to change the startup state of the application, one only needs to change the parameter passed in ShowWindow
. For example, to have the application initially display in its minimized state, pass the parameter SW_MINIMZE
, by changing the line:
m_pMainWnd->ShowWindow(SW_SHOW);
to:
m_pMainWnd->ShowWindow(SW_MINIMIZE);
After making this change and compiling the program and running it, we will see the application flashes briefly in its normal window state before it becomes minimized in the task bar. Similarly, if we want to initially show the window in its maximized state, and we modify the ShowWindow
statement to use SW_MAXIMIZE
, we observe a similar effect. The reason why this effect occurs is, as we will explain later on in this article, due to a Microsoft bug in the application wizard. We will first investigate the reason behind this problem, and then present a very simple solution to solve the issue.
Why the flash occurs
In order to understand why the application does not minimize properly, we need to look into the MFC code that constructs and displays the main window. By placing a breakpoint in the ProcesShellCommand
function, we see that, by default, the AppWnd OnFileNew
handler is called. OnFileNew
calls the CDocument* CDocument* CSingleDocTemplate::OpenDocumentFile(LPCTSTR lpszPathName,BOOL bMakeVisible) OpenDocument
, which creates a new document instance, creates a new frame for the document, and finally displays the window by calling InitialUpdateFrame(pFrame, pDocument, bMakeVisible);
, and displays the view and the mainframe window. The reason why the application does not display correctly when a different SW parameter is chosen instead of SW_SHOW
, is because InitialUpdateFrame
CFrameWnd::ActivateFrame()
calls ShowWindow
during the initialization of the window in the function. This implies that the call to ShowWindow
in InitInstance()
is redundant and not needed.
The solution
There are two solutions that can be used to solve the flashing problem. The first solution is to make a subclass of the SingleDocumentTemplate
and call our derived version of OpenDocument
with bMakeVisible = false
for the minimized case. This, however, does not solve the case of using SW_MAXMIMIZE
. Another solution, which is far more simpler and can be used for any ShowWIndow
mode, is to set the application ShowWindow
property prior to initializing the window, as shown below:
CSingleDocTemplate * pDocTemplate;
pDocTemplate = new CSingleDocTemplate (
IDR_MAINFRAME,
RUNTIME_CLASS(CMyMFCProgramDoc),
RUNTIME_CLASS(CMainFrame),
RUNTIME_CLASS(CMyMFCProgramView));
AddDocTemplate(pDocTemplate);
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
this->m_nCmdShow = SW_MAXIMIZE;
if (!ProcessShellCommand(cmdInfo))
return FALSE;
m_pMainWnd->UpdateWindow();
return TRUE;
One may ask if the ShowWindow()
line in the InitInstance
has no purpose, and why Microsoft put that line there in the first place. The answer is, if one decides to construct an SDI application using the MFC application wizard and checks the option not to use MFC, this line is required to show the window. However, Microsoft should have deleted this line if MFC is used. However, since the vast majority of applications initially display ShowWindow
with the SW_SHOW
parameter, calling ShowWindow
twice (the first time in ActivateFrame
, as described above) will not influence the display of the application.
History