Click here to Skip to main content
13,294,516 members (61,719 online)
Click here to Skip to main content
Add your own
alternative version


35 bookmarked
Posted 12 Sep 2001

Preserving window position in a MFC SDI application

, 12 Sep 2001
Rate this:
Please Sign up or sign in to vote.
How to preserve the window position in a SDI MFC application.


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


Add a WM_CLOSE handler to the CMainFrame class:

void CMainFrame::OnClose() 

    // 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

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

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

         // ShowWindow(wp.showCmd);

      // and finally, bring to top after showing

    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->,
                &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->,
            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");


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


About the Author

Michael Walz
Switzerland Switzerland
No Biography provided

You may also be interested in...


Comments and Discussions

GeneralOther approaches Pin
Geepster8-Dec-06 7:10
memberGeepster8-Dec-06 7:10 
GeneralRe: Other approaches Pin
Michael Walz10-Dec-06 8:15
memberMichael Walz10-Dec-06 8:15 
AnswerRe: Other approaches Pin
Geepster11-Dec-06 6:04
memberGeepster11-Dec-06 6:04 
Something else that may have changed...
The signed integers of the Window Placement structure are long (is that new, e.g., with recent patches to XP?), so the format string (whether using sprintf, its successor _stprinf_s, or CString::Format) should use "%ld" for those instead of "%d". The two unsigned fields remain normal int.

Some recent (Nov/Dec 2006) mysterious window size collapses on startup in one my older apps (but not on my development machine) conjecturally could be attributable to that cause. It's what led me to consult sites such as this one, although I didn't discover another report of this problem on the web. Maybe most developers save placement data as binary, so avoiding the difficulty. Me, I prefer clear text in Registry settings generally. I should be able to get away with this in this case, because my app is deployed only in-house, so I don't have to support pre-XP Windows, and the patch level is relatively homogeneous and up-to-date. Time will tell if "%ld" is my silver bullet.

- G
GeneralActivateFrame not called Pin
quzi9-Apr-04 3:50
memberquzi9-Apr-04 3:50 
GeneralFinally.. A working solution Pin
JoeB5-Apr-03 2:43
memberJoeB5-Apr-03 2:43 
GeneralUse the registry... Pin
Paul A. Howes14-Sep-01 4:21
memberPaul A. Howes14-Sep-01 4:21 
GeneralRe: Use the registry... Pin
Michael Walz14-Sep-01 5:08
memberMichael Walz14-Sep-01 5: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.

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