用于多显示器的 MFC 类






4.93/5 (39投票s)
Win32 多显示器 API 的类包装器
引言
不久前,我决定编写一个屏幕保护程序,以此来学习 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
派生类,它表示特定于显示器的设备上下文。我还没有对这个类做太多,但它似乎是库的逻辑组成部分。
已知限制
CMonitor
和 CMonitors
依赖于显示器句柄不会改变的假设。 经验证明这是一个安全的假设,但并不一定是一个保证。
历史
- 2003 年 2 月 20 日 - 初始版本
- 2003 年 8 月 25 日 - 进行了更改以使其与 VC6 环境兼容