This article was contributed by James
R. Skinner
This code allows a window to remember its last position and
status. It takes into account the possibility of multiple
monitors being attached to the system as avaliable in Windows 98
and Windows 2000. This code is based on code by Yonat Sharon. His
code worked fine on systems with only one monitor but did not
restore the window properly if more than one monitor existed.
To have this code work on systems that don’t support multiple
monitors ( such as Windows 95 and Window NT 4.0 ) you need to add
the following define and include:
#define COMPILE_MULTIMON_STUBS
#include <multimon.h>
Saving the windows position and status is easy enough:
void CMainFrame::OnClose() { // Get the window position WINDOWPLACEMENT wp; wp.length = sizeof(WINDOWPLACEMENT); GetWindowPlacement( &wp ); // Save the info CWinApp* pApp = AfxGetApp(); pApp->WriteProfileInt( "Window", "Show", wp.showCmd); pApp->WriteProfileInt( "Window", "Left", wp.rcNormalPosition.left); pApp->WriteProfileInt( "Window", "Right", wp.rcNormalPosition.right); pApp->WriteProfileInt( "Window", "Top", wp.rcNormalPosition.top); pApp->WriteProfileInt( "Window", "Bottom", wp.rcNormalPosition.bottom); CFrameWnd::OnClose(); }
Restoring the window is a little harder. First we need to get
some information about the monitor upon which the window will be
displayed. Secondly we need to adjust the window position to take
into account the work area of the target monitor. Lastly, we
check to make sure that the upper left hand corner of the window
will be within the work area.
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) { CWinApp* pApp = AfxGetApp(); int showCmd = pApp->GetProfileInt( "Window", "Show", -1); // coodinates not saved if( showCmd == -1 ) return CFrameWnd::PreCreateWindow(cs); pApp->m_nCmdShow = showCmd; cs.x = pApp->GetProfileInt( "Window", "Left", 0); cs.y = pApp->GetProfileInt( "Window", "Top", 0); cs.cx = pApp->GetProfileInt( "Window", "Right", 0) - cs.x; cs.cy = pApp->GetProfileInt( "Window", "Bottom", 0) - cs.y; // Get a handle to the monitor HMONITOR hMonitor = ::MonitorFromPoint( CPoint(cs.x, cs.y), MONITOR_DEFAULTTONEAREST ); // Get the monitor info MONITORINFO monInfo; monInfo.cbSize = sizeof(MONITORINFO); if(::GetMonitorInfo( hMonitor, &monInfo )==0) { AfxMessageBox("GetMonitorInfo failed"); return(FALSE); } // Adjust for work area cs.x += monInfo.rcWork.left - monInfo.rcMonitor.left; cs.y += monInfo.rcWork.top - monInfo.rcMonitor.top; // Ensure top left point is on screen if( CRect( monInfo.rcWork ).PtInRect( CPoint(cs.x,cs.y) ) == FALSE ) { cs.x = monInfo.rcWork.left; cs.y = monInfo.rcWork.top; } return CFrameWnd::PreCreateWindow(cs); }