Click here to Skip to main content
15,885,546 members
Articles / Desktop Programming / MFC
Article

Preserving window position in a MFC SDI application

Rate me:
Please Sign up or sign in to vote.
4.42/5 (9 votes)
12 Sep 2001Public Domain 86.8K   1.9K   35   7
How to preserve the window position in a SDI MFC application.

Introduction

In this article, we show a method for preserving the position and size of an application's window from one execution to another.

Steps

Add a WM_CLOSE handler to the CMainFrame class:

void CMainFrame::OnClose() 
{
    WINDOWPLACEMENT    wp;

    // before it is destroyed, save the position of the window
    wp.length = sizeof wp;

    if ( GetWindowPlacement(&wp) )
    {

        if ( IsIconic() )
          // never restore to Iconic state
          wp.showCmd = SW_SHOW ;

        if ((wp.flags & WPF_RESTORETOMAXIMIZED) != 0)
          // if maximized and maybe iconic restore maximized state
          wp.showCmd = SW_SHOWMAXIMIZED ;

        // and write it to the .INI file
        WriteWindowPlacement(&wp);
    }
    
    CFrameWnd::OnClose();
}

Override the ActivateFrame() method of your CMainFrame class:

void CMainFrame::ActivateFrame(int nCmdShow)
{
    // nCmdShow is the normal show mode this frame should be in
    // translate default nCmdShow (-1)
    if (nCmdShow == -1)
    {
        if (!IsWindowVisible())
            nCmdShow = SW_SHOWNORMAL;
        else if (IsIconic())
            nCmdShow = SW_RESTORE;
    }

    // bring to top before showing
    BringToTop(nCmdShow);

    if (nCmdShow != -1)
    {
        // show the window as specified
      WINDOWPLACEMENT wp;
      
      if ( !ReadWindowPlacement(&wp) )
      {
          ShowWindow(nCmdShow);
      }
      else
      {
         if ( nCmdShow != SW_SHOWNORMAL )  
           wp.showCmd = nCmdShow;

         SetWindowPlacement(&wp);
         // ShowWindow(wp.showCmd);
      }

      // and finally, bring to top after showing
      BringToTop(nCmdShow);
    }

    return ;
}

The ReadWindowPlacement and WriteWindowPlacement is shown below:

static char szSection[]   = "Settings";
static char szWindowPos[] = "WindowPos";
static char szFormat[] = "%u,%u,%d,%d,%d,%d,%d,%d,%d,%d";

BOOL CMainFrame::ReadWindowPlacement(WINDOWPLACEMENT *pwp)
{
    CString strBuffer;
    int    nRead ;

    strBuffer = AfxGetApp()->GetProfileString(szSection, szWindowPos);
    if ( strBuffer.IsEmpty() )  return FALSE;

    nRead = sscanf(strBuffer, szFormat,
                &pwp->flags, &pwp->showCmd,
                &pwp->ptMinPosition.x, &pwp->ptMinPosition.y,
                &pwp->ptMaxPosition.x, &pwp->ptMaxPosition.y,
                &pwp->rcNormalPosition.left,  &pwp->rcNormalPosition.top,
                &pwp->rcNormalPosition.right, &pwp->rcNormalPosition.bottom);
    if ( nRead != 10 )  return FALSE;
    pwp->length = sizeof(WINDOWPLACEMENT);

    return TRUE;
}

// Write a window placement to settings section of app's ini file.

void CMainFrame::WriteWindowPlacement(WINDOWPLACEMENT *pwp)
{
    char szBuffer[sizeof("-32767")*8 + sizeof("65535")*2];
    int max = 1;
    CString s;

    sprintf(szBuffer, szFormat,
            pwp->flags, pwp->showCmd,
            pwp->ptMinPosition.x, pwp->ptMinPosition.y,
            pwp->ptMaxPosition.x, pwp->ptMaxPosition.y,
            pwp->rcNormalPosition.left, pwp->rcNormalPosition.top,
            pwp->rcNormalPosition.right, pwp->rcNormalPosition.bottom);
     AfxGetApp()->WriteProfileString(szSection, szWindowPos, szBuffer);

}

These two functions are inspired from the SUPERPAD sample shipped with Microsoft Visual C++ 1.52.

If you want to store the window placement information rather in the registry than in a .ini file, just add this after the call to AddDocTemplate in the InitInstance() method in your project's main .cpp file.

SetRegistryKey("My Company Name");

License

This article, along with any associated source code and files, is licensed under A Public Domain dedication


Written By
Switzerland Switzerland
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralOther approaches Pin
Geepster8-Dec-06 6:10
Geepster8-Dec-06 6:10 
Note that the sample code you copied is in theory prone to buffer overruns, because it forgot to allow for the commas in the format string when it sized the buffers (i.e., forgot to add sizeof(",")* 9).

There are MFC approaches to this that don't require fixed-size string buffers, just CStrings. See this www.koders.com article by Kirk Stowell.
Also, an alternative is to store the wp structure as binary instead of parsing it. See
this code project article by James Pullicino.

-Geepster
GeneralRe: Other approaches Pin
Michael Walz10-Dec-06 7:15
Michael Walz10-Dec-06 7:15 
AnswerRe: Other approaches Pin
Geepster11-Dec-06 5:04
Geepster11-Dec-06 5:04 
GeneralActivateFrame not called Pin
quzi9-Apr-04 2:50
quzi9-Apr-04 2:50 
GeneralFinally.. A working solution Pin
JoeB5-Apr-03 1:43
JoeB5-Apr-03 1:43 
GeneralUse the registry... Pin
Paul A. Howes14-Sep-01 3:21
Paul A. Howes14-Sep-01 3:21 
GeneralRe: Use the registry... Pin
Michael Walz14-Sep-01 4:08
Michael Walz14-Sep-01 4:08 

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.