ATL’s CenterWindow

It appears that ATL does not center window correctly on multi-monitor systems. ATL code checks screen work area coordinates in CWindow::CenterWindow to ensure new position is within visible area, however since SystemParametersInfo/SPI_GETWORKAREA is used target rectangle is always on a primary monitor.

This hotfix works the problem around:

atlwin.h, CWindow::CenterWindow:

#if TRUE
	if(hWndCenter)
	{
		ATLVERIFY(::GetWindowRect(hWndCenter, &rcCenter));
		HMONITOR hMonitor = MonitorFromRect(&rcCenter, MONITOR_DEFAULTTONEAREST);
		ATLASSERT(hMonitor);
		if(hMonitor)
		{
			MONITORINFO MonitorInfo = { sizeof MonitorInfo };
			ATLVERIFY(GetMonitorInfo(hMonitor, &MonitorInfo));
			rcArea = MonitorInfo.rcWork;
		} else
			ATLVERIFY(::SystemParametersInfo(SPI_GETWORKAREA, NULL, &rcArea, NULL));
	} else
	{
		ATLVERIFY(::SystemParametersInfo(SPI_GETWORKAREA, NULL, &rcArea, NULL));
		rcCenter = rcArea;
	}
#else
	::SystemParametersInfo(SPI_GETWORKAREA, NULL, &rcArea, NULL);
	if(hWndCenter == NULL)
		rcCenter = rcArea;
	else
		::GetWindowRect(hWndCenter, &rcCenter);
#endif

Leave a Reply