Click here to Skip to main content
15,867,568 members
Articles / Desktop Programming / MFC
Article

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

Rate me:
Please Sign up or sign in to vote.
4.49/5 (19 votes)
28 Feb 2008CPOL3 min read 74.5K   594   37   14
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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) DreamWorks Animation
United States United States
I started programming a TRS-80 Model I in Junior High School with the goal to write arcade games. Since then, I have had the opportunity to work with a wide variety of technologies and environments ranging from real-time telemetry data systems, state-of-the art animation and rigging software, 3D computer games, non-contact measurement acquisition devices, and digital TV systems. I have worked on everything from low-level device drivers to state of the art GUI apps using C#.

Comments and Discussions

 
Generalthank you Pin
piaomiaoju8-Nov-08 20:36
piaomiaoju8-Nov-08 20:36 
GeneralRe: thank you Pin
David Saelman9-Nov-08 20:28
David Saelman9-Nov-08 20:28 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.