Click here to Skip to main content
15,884,473 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 
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 
Hello,

Is you knowing why my ActivateFrame not called? I is overridded, but is not called. OnClose IS called. Also, your demo working OK.

Thanking,
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.