Click here to Skip to main content
15,891,721 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.9K   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 
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 
Hello,

I have spent much time searching for a way to save this info, i got as far as resetting the correct size and position but got stumped on setting the app to maximised (if it was when it was closed)

You have addressed all these issues and the code works perfectly (VC7.net)

MANY MANY thanks.

Joe
#
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.