Preserving window position in a MFC SDI application






4.42/5 (9 votes)
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");