Click here to Skip to main content
Click here to Skip to main content

Preserving window position in a MFC SDI application

, 12 Sep 2001 Public Domain
Rate this:
Please Sign up or sign in to vote.
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

Share

About the Author

Michael Walz

Switzerland Switzerland
No Biography provided

Comments and Discussions

 
GeneralOther approaches PinmemberGeepster8-Dec-06 7: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 PinmemberMichael Walz10-Dec-06 8:15 
AnswerRe: Other approaches PinmemberGeepster11-Dec-06 6:04 
GeneralActivateFrame not called Pinmemberquzi9-Apr-04 3:50 
GeneralFinally.. A working solution PinmemberJoeB5-Apr-03 2:43 
GeneralUse the registry... PinmemberPaul A. Howes14-Sep-01 4:21 
GeneralRe: Use the registry... PinmemberMichael Walz14-Sep-01 5:08 

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

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

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.141223.1 | Last Updated 13 Sep 2001
Article Copyright 2001 by Michael Walz
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid