Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

A Simple Method to Control the Startup State of an MFC SDI Application

0.00/5 (No votes)
28 Feb 2008 2  
How to minimize or maximize an SDI application without any flash artifacts.

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:

// The one and only window has been initialized, so show and update it.
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),       // main SDI frame window
        RUNTIME_CLASS(CMyMFCProgramView));
    AddDocTemplate(pDocTemplate);


    // Parse command line for standard shell commands, DDE, file open
    CCommandLineInfo cmdInfo;
    ParseCommandLine(cmdInfo);

        // Add the following line:
        // Set the initial window display to whatever mode you like
    this->m_nCmdShow = SW_MAXIMIZE;

        // Dispatch commands specified on the command line
    if (!ProcessShellCommand(cmdInfo))
        return FALSE;

        // The following line should be deleted since it is not needed 
        // for a SDI application that used MFC The one and only window has
        // been initialized, so show and update it.

        //m_pMainWnd->ShowWindow(SW_SHOW);
    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

  • First version.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here