October 24, 2016
Hot Topics:

Restoring Window Position With Multiple Monitors

  • December 12, 1998
  • By James R. Skinner
  • Send Email »
  • More Articles »

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:

#include <multimon.h>

Saving the windows position and status is easy enough:

void CMainFrame::OnClose()
    	// Get the window position
	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);

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
	monInfo.cbSize = sizeof(MONITORINFO);
	if(::GetMonitorInfo( hMonitor, &monInfo )==0)
		AfxMessageBox("GetMonitorInfo failed");

	// 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);

Date Posted: December 13, 1998

Comment and Contribute


(Maximum characters: 1200). You have characters left.



Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Sitemap | Contact Us

Thanks for your registration, follow us on our social networks to keep up-to-date
Rocket Fuel