Restoring Window Position

Many applications need to “remember” the last window position and status
(minimized/maximized/normal). This seemingly trivial task holds a few
little-known subtleties, so I thought it might be helpful to show code
that handles these things correctly.

Saving the window’s position is straight forward:

void CMainFrame::OnClose() // message handler for WM_CLOSE
{
    // Save main window position
    CWinApp* app = AfxGetApp();
    WINDOWPLACEMENT wp;
    GetWindowPlacement(&wp);
    app->WriteProfileInt("Frame", "Status", wp.showCmd);
    app->WriteProfileInt("Frame", "Top",    wp.rcNormalPosition.top);
    app->WriteProfileInt("Frame", "Left",   wp.rcNormalPosition.left);
    app->WriteProfileInt("Frame", "Bottom", wp.rcNormalPosition.bottom);
    app->WriteProfileInt("Frame", "Right",  wp.rcNormalPosition.right);

    CFrameWnd::OnClose();
}

However, restoring it is a little more tricky:

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
    //
    // Restore main window position
    //

    CWinApp* app = AfxGetApp();
    int s, t, b, r, l;

    // only restore if there is a previously saved position
    if ( -1 != (s = app->GetProfileInt("Frame", "Status",   -1)) &&
         -1 != (t = app->GetProfileInt("Frame", "Top",      -1)) &&
         -1 != (l = app->GetProfileInt("Frame", "Left",     -1)) &&
         -1 != (b = app->GetProfileInt("Frame", "Bottom",   -1)) &&
         -1 != (r = app->GetProfileInt("Frame", "Right",    -1))
       ) {

        // restore the window's status
        app->m_nCmdShow = s;

        // restore the window's width and height
        cs.cx = r - l;
        cs.cy = b - t;

        // the following correction is needed when the taskbar is
        // at the left or top and it is not "auto-hidden"
        RECT workArea;
        SystemParametersInfo(SPI_GETWORKAREA, 0, &workArea, 0);
        l += workArea.left;
        t += workArea.top;

        // make sure the window is not completely out of sight
        int max_x = GetSystemMetrics(SM_CXSCREEN) -
                        GetSystemMetrics(SM_CXICON);
        int max_y = GetSystemMetrics(SM_CYSCREEN) -
                        GetSystemMetrics(SM_CYICON);
        cs.x = min(l, max_x);
        cs.y = min(t, max_y);
    }

    return CFrameWnd::PreCreateWindow(cs);
}

Date Posted: 6/24/98

Posted by: Pat Laplante.

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read