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.
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:
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:
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
ShowWindow during the initialization of the window in the function. This implies that the call to
InitInstance() is redundant and not needed.
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
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 (
this->m_nCmdShow = SW_MAXIMIZE;
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.