Click here to Skip to main content
6,305,776 members and growing! (16,828 online)
Email Password   helpLost your password?
Multimedia » GDI » General     Intermediate License: The Code Project Open License (CPOL)

MFC classes for multiple monitors

By Don Kackman

Class wrappers around the Win32 multi-monitor API
VC6, VC7, VC7.1Win2K, WinXP, MFC, GDI, VS.NET2003, Dev
Posted:19 Feb 2003
Updated:27 Aug 2003
Views:94,570
Bookmarked:67 times
Announcements
Loading...
 
Search    
Advanced Search
printPrint   Broken Article?Report       add Share
  Discuss Discuss   Recommend Article Email
27 votes for this article.
Popularity: 6.93 Rating: 4.84 out of 5

1

2
1 vote, 3.7%
3
4 votes, 14.8%
4
22 votes, 81.5%
5

Sample Image - multimon.jpg

Introduction

Awhile back I decided to write a screensaver application as a way to pick up MFC. After I got my first implementation up and running I shipped it off to a friend. Well the first thing he noted was a a glaring bug: he uses multiple monitors and my screen saver only showed up on one.

After some scouring of the internet and research into MSDN I was able to to get the screensaver running on multiple monitors by using some API calls the were introduced with Windows 98/2000. This project is a couple of small MFC classes that wrap the multi-monitor API.

These classes can be safely used on Windows 95/NT4 as well. On those platforms, they just provide the properties of the one and only monitor.

Background

Eveyrything you ever wanted to know about the API for multiple monitors is described in a very well written article by David Campbell in the June 1997 issue of MSJ.

The API itself is simple and straightforward. It has some new constants to pass to GetSystemMetrics and a couple methods to enumerate all of the monitors currently attached to the system and get the properties of a given monitor.

All of the types and functions are defined by the platform SDK in the file multimon.h . If you #define WINVER to be greater than 0x400 you don't need to link to multimon.h, as the API gets defined in windef.h for Windows 98 and later targeted builds. Multimon.h also provides some stub functions that allow calls to be safely made on Windows 95/NT4 machines. These wrappers interrogate the runtime OS and either make fall-through calls into the actual API or return the propeties of the one (and only) monitor on those older platforms.

The multi monitor classes take care of including multimon.h correctly depending on the value of WINVER.

Using the code

CMointor is a basic MFC class that allows you to safely use the multi-monitor API on any Win32 platform. 

There are three classes in this library:

CMonitors represents the collection of monitors currently attached to the system and wraps the EnumDisplayMonitors API function.

//CMonitors' interface

CMonitor GetMonitor( const int index ) const;
int GetCount() const; 

//returns the monitor closest to the specified item

static CMonitor GetNearestMonitor( const LPRECT lprc );
static CMonitor GetNearestMonitor( const POINT pt );
static CMonitor GetNearestMonitor( const CWnd* pWnd );

//is the specificed item visible on any monitor

static BOOL IsOnScreen( const POINT pt );
static BOOL IsOnScreen( const CWnd* pWnd );
static BOOL IsOnScreen( const LPRECT lprc );

//returns the rectangle encompassing all monitors

static void GetVirtualDesktopRect( LPRECT lprc );

//determines whether the given handle is a valid monitor handle

static BOOL IsMonitor( const HMONITOR hMonitor );
static CMonitor GetPrimaryMonitor();
static BOOL AllMonitorsShareDisplayFormat();

static int GetMonitorCount();

CMonitor is a wrapper around an HMONITOR handle (returned from EnumDisplayMonitors) and the GetMonitorInfo function. With CMonitor you can get at the characteristics of a given monitor.

//The interface of CMonitor            

void Attach( const HMONITOR hMonitor );
HMONITOR Detach();

void ClipRectToMonitor( LPRECT lprc, 
const BOOL UseWorkAreaRect = FALSE ) const; void CenterRectToMonitor( LPRECT lprc,
const BOOL UseWorkAreaRect = FALSE ) const; void CenterWindowToMonitor( CWnd* const pWnd,
const BOOL UseWorkAreaRect = FALSE ) const; //creates a device context for the monitor - the client is responsible for
// DeleteDC
HDC CreateDC() const; void GetMonitorRect( LPRECT lprc ) const; //the work area is the monitor rect minus the start bar void GetWorkAreaRect( LPRECT lprc ) const; void GetName( CString& string ) const; int GetBitsPerPixel() const; //determines if the specified item on the monitor BOOL IsOnMonitor( const POINT pt ) const; BOOL IsOnMonitor( const CWnd* pWnd ) const; BOOL IsOnMonitor( const LPRECT lprc ) const; BOOL IsPrimaryMonitor() const; BOOL IsMonitor() const;

CMonitorDC is a CDC derived class that represents a monitor specific device context. I haven't really gone to far with this class but it seemed like a logical part of the library.  

Known Limitations

CMonitor and CMonitors rely on the assumption that a monitor handle does not change. This has proved to be a safe assumption empirically but isn't nessecarily a guarantee.

History

  • 02/20/2003 - Initial Release
  • 08/25/2003 - Made changes to make compatible with VC6 environment

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Don Kackman


Member
The first computer program I ever wrote was in BASIC on a TRS-80 Model I and looked something like:

10 PRINT Don is cool
20 GOTO 10

It only went downhill from there.
Occupation: Team Leader
Company: Starkey Laboratories
Location: United States United States

Other popular GDI articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 25 of 44 (Total in Forum: 44) (Refresh)FirstPrevNext
QuestionMultimon Code Project Licensing PinmemberDonaldJLucas18:40 17 May '09  
AnswerRe: Multimon Code Project Licensing PinmemberDon Kackman7:59 18 May '09  
QuestionRe: Multimon Code Project Licensing PinmemberDonaldJLucas20:17 18 May '09  
AnswerRe: Multimon Code Project Licensing PinmemberDon Kackman3:00 19 May '09  
GeneralDual Monitor problem PinmemberMember 469378722:00 11 Aug '08  
Generalvb.net or c# version please ? PinmemberUltraWhack10:43 12 May '08  
GeneralRe: vb.net or c# version please ? PinmemberDon Kackman2:27 5 Aug '08  
Questionmirror display Pinmemberfurry222:40 23 Apr '08  
QuestionMFC Classes Pinmemberkannettan21:49 15 Sep '06  
GeneralBits per pixel Pinmemberakorka10:39 17 Jul '06  
GeneralRe: Bits per pixel PinmemberDon Kackman12:02 17 Jul '06  
GeneralProblem Pinmemberakorka9:40 17 Jul '06  
GeneralSplitterWND question PinmemberKarl Bahr7:02 26 Nov '05  
GeneralNice classes, one fix PinmemberHans Dietrich16:48 24 Feb '05  
GeneralRe: Nice classes, one fix PinmemberDon Kackman16:18 19 Mar '05  
GeneralRe: Nice classes, one fix PinmemberHans Dietrich19:43 19 Mar '05  
GeneralRe: Nice classes, one fix PinmemberFreeDragon8010:22 29 May '08  
GeneralNice! What about turning on/off the second monitor PinmemberAORD22:48 17 Feb '05  
GeneralCMonitor not defined Pinmemberbujal14:58 20 Dec '04  
GeneralRe: CMonitor not defined PinmemberDon Kackman15:13 20 Dec '04  
GeneralRe: CMonitor not defined Pinmemberbujal23:39 21 Dec '04  
GeneralLink errors when MFC statically linked PinmemberTerry76010:14 8 Sep '04  
GeneralRe: Link errors when MFC statically linked PinmemberNeville Franks11:35 8 Sep '04  
GeneralRe: Link errors when MFC statically linked PinsussAnonymous16:22 16 Nov '04  
GeneralRe: Link errors when MFC statically linked Pinmemberleemidgley3:58 19 May '07  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 27 Aug 2003
Editor: Chris Maunder
Copyright 2003 by Don Kackman
Everything else Copyright © CodeProject, 1999-2009
Web15 | Advertise on the Code Project