65.9K
CodeProject 正在变化。 阅读更多。
Home

用于多显示器的 MFC 类

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.93/5 (39投票s)

2003年2月20日

CPOL

2分钟阅读

viewsIcon

262721

downloadIcon

8738

Win32 多显示器 API 的类包装器

Sample Image - multimon.jpg

引言

不久前,我决定编写一个屏幕保护程序,以此来学习 MFC。在我完成了第一个实现并运行之后,我把它发给了我的一个朋友。嗯,他指出的第一件事是一个明显的错误:他使用多个显示器,而我的屏幕保护程序只显示在一个显示器上。

经过一些互联网搜索和对 MSDN 的研究,我能够通过使用 Windows 98/2000 引入的一些 API 调用,使屏幕保护程序在多个显示器上运行。这个项目是几个小的 MFC 类,它们封装了多显示器 API。

这些类也可以安全地用于 Windows 95/NT4。在这些平台上,它们只提供一个且唯一显示器的属性。

背景

关于多显示器 API 的所有你想知道的知识,都在 David Campbell 在 1997 年 6 月的 MSJ 杂志上撰写的一篇非常好的文章中进行了描述。

API 本身简单明了。它有一些新的常量传递给 GetSystemMetrics,以及几个方法来枚举当前连接到系统的所有显示器,并获取给定显示器的属性。

所有类型和函数都在平台 SDK 的文件 multimon.h 中定义。如果将 #define WINVER 定义为大于 0x400,则不需要链接到 multimon.h,因为 API 在 windef.h 中为 Windows 98 和更高版本的目标构建定义。 Multimon.h 还提供了一些存根函数,这些函数允许在 Windows 95/NT4 机器上安全地进行调用。这些包装器会查询运行时操作系统,并调用实际的 API,或者返回那些较旧平台上一个(且唯一)显示器的属性。

多显示器类负责根据 WINVER 的值正确地包含 multimon.h

Using the Code

CMointor 是一个基本的 MFC 类,它允许您在任何 Win32 平台上安全地使用多显示器 API。

这个库中有三个类

CMonitors 表示当前连接到系统的显示器集合,并封装了 EnumDisplayMonitors API 函数。

//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 specified 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 是一个围绕 HMONITOR 句柄(从 EnumDisplayMonitors 返回)和 GetMonitorInfo 函数的包装器。 使用 CMonitor,您可以获得给定显示器的特征。

//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 是一个 CDC 派生类,它表示特定于显示器的设备上下文。我还没有对这个类做太多,但它似乎是库的逻辑组成部分。

已知限制

CMonitorCMonitors 依赖于显示器句柄不会改变的假设。 经验证明这是一个安全的假设,但并不一定是一个保证。

历史

  • 2003 年 2 月 20 日 - 初始版本
  • 2003 年 8 月 25 日 - 进行了更改以使其与 VC6 环境兼容
© . All rights reserved.