65.9K
CodeProject is changing. Read more.
Home

Don Kackman Multiple Monitors Classes Port to WTL

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.78/5 (7 votes)

Apr 26, 2009

CPOL

1 min read

viewsIcon

25331

downloadIcon

466

Class wrappers around the Win32 multi-monitor API

Introduction 

I was researching the multiple monitors support in Windows and came across Don Kackman's excellent article (see the link below) describing his MFC wrapper classes around the Win32 multi-monitor API. Since I needed it for a WTL project, I ported these classes to WTL retaining a majority of the original code.

Using the Code

There are 3 classes:

  • CMonitor - Wrapper around an HMONITOR handle (returned from EnumDisplayMonitors) and the GetMonitorInfo function. With CMonitor, you can get at the characteristics of a given monitor.
  • CMonitors - Represents the collection of monitors currently attached to the system and wraps the EnumDisplayMonitors API function.
  • CMonitorDC - CDC derived class that represents a monitor specific device context. It's not used anywhere but I kept it for completeness.

With the help of these classes, it's very easy to add a multiple monitors support to your application. Take a look at the couple examples below.

  1. Add the "Monitor.h" and "Monitors.h" header files to a project.
  2. If you are saving a window position to restore it later, you need to make sure that the position is still valid before using it. Add the following code right before you create or show a window:
    CMonitors::MakeSureRectIsVisible(pRect);
    Below is the implementation of this function. No need to explain what it does, right?
    // Makes sure a rectangle is visible
    void CMonitors::MakeSureRectIsVisible(const LPRECT lprc)
    {
    	// Check if a rectangle will be visible on any monitor
    	if (!CMonitors::IsOnScreen(lprc))
    	{
    		// If not a rectangle will be positioned 
    		// in the center of the primary monitor
    		CMonitor monitor = CMonitors::GetPrimaryMonitor();
    		monitor.CenterRectToMonitor(lprc);
    	}
    }
  3. If you need to center a window on the primary monitor, add the following code:
    CMonitor monitor = CMonitors::GetPrimaryMonitor();
    monitor.CenterWindowToMonitor(this);

Points of Confusion

Please do not forget that negative coordinates or coordinates larger than SM_CXSCREEN, SM_CYSCREEN are now valid. 

Credits

See Don Kackman's original article for more details: MFC classes for multiple monitors [^]

History

  • 26th April, 2009: Initial post