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;
wp.length = sizeof wp;
if ( GetWindowPlacement(&wp) )
{
if ( IsIconic() )
wp.showCmd = SW_SHOW ;
if ((wp.flags & WPF_RESTORETOMAXIMIZED) != 0)
wp.showCmd = SW_SHOWMAXIMIZED ;
WriteWindowPlacement(&wp);
}
CFrameWnd::OnClose();
}
Override the ActivateFrame()
method of your CMainFrame
class:
void CMainFrame::ActivateFrame(int nCmdShow)
{
if (nCmdShow == -1)
{
if (!IsWindowVisible())
nCmdShow = SW_SHOWNORMAL;
else if (IsIconic())
nCmdShow = SW_RESTORE;
}
BringToTop(nCmdShow);
if (nCmdShow != -1)
{
WINDOWPLACEMENT wp;
if ( !ReadWindowPlacement(&wp) )
{
ShowWindow(nCmdShow);
}
else
{
if ( nCmdShow != SW_SHOWNORMAL )
wp.showCmd = nCmdShow;
SetWindowPlacement(&wp);
}
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;
}
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");