多屏幕显示器编程( 三 )

Programming for Multiple Monitors in Windows 98
New Multiple-Monitor Win32 API functions

Continued from Installing Multiple Monitors

In order to give applications access to multiple-monitor information, Microsoft has added several new Win32 API functions and updated several existing functions. In addition to new functions, there is also a new type of handle, the HMONITOR, which represents a physical display device. In order to get and set the settings of a particular monitor, you first need to obtain an HMONITOR, which will always point to the same monitor.

The first of the new functions we will discuss is MonitorFromPoint, which has the following definition:

HMONITOR MonitorFromPoint(POINT pt,

DWORD dwFlags);

The returned HMONITOR is the monitor that contains the POINT passed to the function. If no monitor contains the specified point, then the return value of MonitorFromPoint is determined by dwFlags, for which there are three possible values: MONITOR_DEFAULTTONULL returns NULL if the point is not contained by any monitor, MONITOR_DEFAULTTOPRIMARY returns the primary display device, and MONITOR_DEFAULTTONEAREST returns the monitor closest to the point.

HMONITOR MonitorFromRect(LPRECT lprc,

DWORD dwFlags);

HMONITOR MonitorFromWindow(HWND hWnd,

DWORD dwFlags);

MonitorFromRect and MonitorFromWindow return the handle of the monitor that contains the largest portion of the specified rectangle or window. If no monitor contains the specified rectangle or window, the return value depends upon the value of the dwFlags field, which has the same possible values for these two functions as it does for MonitorFromPoint.

Once you have obtained an HMONITOR, you can use the function GetMonitorInfo to retrieve a MONITORINFO structure filled with data relevant to the specified monitor, as follows:

BOOL GetMonitorInfo( HMONITOR hmonitor, LPMONITORINFO lpmi);

typedef struct tagMONITORINFO

{

DWORD cbSize;

RECT rcMonitor;

RECT rcWork;

DWORD dwFlags;

} MONITORINFO, *LPMONITORINFO;

typedef struct tagMONITORINFOEXA

{

MONITORINFO;

TCHAR szDevice[CCHDEVICENAME];

} MONITORINFOEX, *LPMONITORINFOEX;

There are actually two versions of this structure, MONITORINFO and MONITORINFOEX. The cbSize member contains the size of the structure, and it is used by Windows to determine whether a structure is a MONITORINFO or MONITORINFOEX. After a successful call to GetMonitor, the rcMonitor member contains the rectangle of the monitor within the virtual desktop. The rcWork member contains the work area of the monitor within the virtual desktop. (A monitor's work area is the portion not covered by the taskbar.) The dwFlags member has only one possible value, MONITORINFOF_PRIMARY, which is set if the monitor is the primary display. The MONITORINFOEX structure has one additional parameter, szDevice, which contains the unique name of the device. The device name can be passed to other functions, such as ChangeDisplaySettingsEx, allowing the settings for each monitor to be changed independently.

Before you pass GetMonitorInfo a pointer to a MONITORINFO or MONITORINFOEX structure, you must set the cbSize member to the size of the structure so that Windows can determine which structure is being used. The following code sample shows how:

MONITORINFOEX mix;

mix.cbSize = sizeof(mix);

GetMonitorInfo(hMonitor,

(LPMONITORINFO)&mix);

Some changes were made to GetSystemMetrics to allow the use of multiple monitors. Passing SM_CXSCREEN and SM_CYSCREEN as parameters returns the x and y extents, respectively, of only the primary monitor. If you wish to get the x and y extents of the virtual desktop, use the new constants SM_CXVIRTUALSCREEN and SM_CYVIRTUALSCREEN; GetSystemMetrics will return the left and top coordinates of the virtual desktop, respectively. You can no longer assume the top-left corner of the desktop is (0,0), and the extents will do you no good if you don't know the origins. Passing the new constant SM_SAMEDISPLAYFORMAT to GetSystemMetrics will return TRUE if all of the monitors on the system have exactly the same color settings, FALSE otherwise. Use the constant SM_CMONITORS when you want to know how many monitors make up the virtual desktop. Note that this value includes only installed monitors that have been added to the desktop by the user.

The SystemParametersInfo function has also been changed slightly. The changes affect only the uiAction values SPI_GETWORKAREA and SPI_SETWORKAREA. Using the former always returns the work area of the primary monitor. If you want to get the work area of another monitor, you need to use GetMonitorInfo. Using SPI_SETWORKAREA sets the work area of the monitor that contains the RECT structure passed into the pvParam value.

EnumDisplayMonitors is a new function that allows an application to optimize its drawing code when a window is being partially displayed on multiple monitors that have different color-bit depths.

BOOL WINAPI EnumDisplayMonitors(

HDC hdc,

LPCRECT lprcClip,

MONITORENUMPROC lpfnEnum,

LPARAM dwData);

The MONITORENUMPROC callback is called for each monitor that intersects the visible region of hdc and the lprcClip parameter. If the lprcClip parameter is NULL, then no additional clipping is performed. The dwData parameter is for user-defined data and is passed through to the dwData parameter in the callback function. MONITORENUMPROC is a user-defined callback function that must have the following signature:

BOOL CALLBACK MonitorEnumProc(

HMONITOR hmonitor,

HDC hdcMonitor,

LPRC lprcMonitor,

DWORD dwData);

If the hdc passed to EnumDisplayMonitors was NULL, then hdcMonitor is NULL. Otherwise, hdcMonitor contains a valid device context whose color attributes match the display monitor defined by hmonitor. If hdcMonitor is NULL, then lprcMonitor is in virtual-desktop coordinates. It is important to note that no application needs to use EnumDisplayMonitors to handle monitors of differing bit depths, since Windows automatically dithers high-color images on lower-color devices. You should use this function only if you want to do custom dithering to ensure the best possible display. In order to help you understand exactly how EnumDisplayMonitors is used, I will present a couple of code snippets illustrating common usage scenarios.

One use for EnumDisplayMonitors is to make sure that images are drawn optimally on lower-color devices. The best way to do this is to change how your window's WndProc handles the WM_PAINT message.

case WM_PAINT:

HDC hdc;

hdc = BeginPaint(hWnd,

&paintStruct);

EnumDisplayMonitors(hdc, NULL, monitorEnumPaintProc, 0);

EndPaint(&paintStruct);

Inside your callback, you query the passed device context to determine its capabilities and display area and do your drawing accordingly.

You can also use EnumDisplayMonitors to query every monitor on the desktop. If the device context and RECT passed into EnumDisplayMonitors are both NULL, no clipping is performed and your callback function is called once for each monitor in the virtual desktop. The code in Figure 3 caches the work area of every monitor for later use. (Note that if your application actually did this, you would need to update the cached information when the WM_DISPLAYCHANGE message was received, since the values might change.)

Another way to query display devices is the EnumDisplayDevices function, which can query all devices available on the system, whether or not they're part of the virtual desktop.

BOOL WINAPI EnumDisplayDevices(

PVOID Unused,

DWORD iDevNum,

PDISPLAY_DEVICE lpDisplayDevice,

DWORD dwFlags);

Unused is reserved for future use and must be set to NULL. There are no valid values for dwFlags, so set it to 0. iDevNum is the index of the device you wish to query and is zero-based. If there is not a device available in the iDevNum position, EnumDisplayDevices returns FALSE. If there is a device in the position indicated by iDevNum, EnumDisplayDevices returns TRUE and fills in lpDisplayDevice. So to examine all devices on the system, you'd call EnumDisplayDevices for each possible index, starting with 0, until it returned FALSE. The lpDisplayDDevice parameter is a pointer to a DISPLAY_DEVICE structure, which is defined as follows:

typedef struct _DISPLAY_DEVICE {

DWORD cb;

BYTE DeviceName[32];

BYTE DeviceString[128];

DWORD StateFlags;

} DISPLAY_DEVICE, *PDISPLAY_DEVICE,

*LPDISPLAY_DEVICE;

The cb member contains the size of the structure in bytes. DeviceName is the same unique name returned by GetMonitorInfo in the szDevice member of the MONITORINFOEX structure. DeviceString is a user-friendly description of the enumerated device. Unfortunately, I was not able to find documentation on the possible values of StateFlag, but they seem self-explanatory. Here are their definitions as listed in the Win32 SDK:

#define DISPLAY_DEVICE

_ATTACHED_TO_DESKTOP

0x00000001

#define DISPLAY_DEVICE

_MULTI_DRIVER

0x00000002

#define DISPLAY_DEVICE

_PRIMARY_DEVICE

0x00000004

#define DISPLAY_DEVICE

_MIRRORING_DRIVER

0x00000008

#define DISPLAY_DEVICE

_VGA_COMPATIBLE

0x00000010

Since EnumDisplayDevices allows you to query devices that aren't part of the desktop, your application can use monitors in an exclusive manner, without having to share the screen with the desktop. To do this, find a device that doesn't have the DISPLAY_DEVICE_ATTACHED_TO_DESKTOP bit set and call the Win32 API function CreateDC, passing the name returned in the DeviceName member of lpDisplayDevice. If you create a device context in this manner, you should delete it when you're done with it by calling DeleteDC.

Next: Other Issues

Published as Power Programming in the 4/7/98 issue of PC Magazine.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Dell 显示器是一款非常受欢迎的电脑显示设备品牌,它具有高清晰、高亮度、高对比度等优良的显示效果和易于使用的特点。除此之外,Dell 显示器还配备了分屏软件,帮助用户更好地进行多任务处理。 Dell 显示器分屏软件采用了非常直观的界面设计,用户可以方便地将屏幕划分成多个区域,以支持同时打开多个应用程序和窗口。用户可以根据自己的工作需要进行设置和调整,实现窗口在屏幕上自由地拖动和调整,而无需调整窗口大小和位置。 此外,Dell 显示器分屏软件还支持多个显示器,使用户可以同时在两个甚至更多的显示器上处理不同的任务,从而提高了工作效率和生产力。用户还可以自定义不同的分屏模式,并将其保存为自己的首选项,方便和快速地进行切换。 总之,Dell 显示器分屏软件是一款功能强大的工具,旨在帮助用户更好地进行多任务处理,提高生产效率和工作效率。无论是在家庭、办公室还是商业环境中,Dell 显示器分屏软件都能够为用户提供高品质、高性能的显示设备和软件支持。 ### 回答2: Dell 显示器分屏软件可以将一个大屏幕分成多个小屏幕,让用户能够同时查看和处理多个不同的应用程序,提高工作效率和生产力。该软件兼容 Dell 显示器系列,并且简单易用,可以通过简单几步设置,快速实现分屏效果,且不需要复杂的编程技巧。 通过 Dells 显示器分屏软件,用户可以自由地拖动和组合不同大小的窗口,并可按照自己的需求进行排列,例如:将两个窗口并排或上下对称分别显示。此外,该软件还提供了多种自定义选项,如:用于调整窗口大小和位置等。 这种软件最适合需要同时处理多个任务和多个程序的用户,例如:金融、财务、程序员、设计师或者游戏爱好者等。此外,该软件还适用于家庭用户,在享受高清视频娱乐的同时,还能够处理电子邮件、浏览网页等多个任务。 总体而言,Dell 显示器分屏软件是一款十分实用的软件,并且适用范围广泛。无论是工作还是娱乐,都可以帮助用户提高效率和便捷性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蝈蝈俊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值