分享
 
 
 

多屏幕显示器编程( 三 )

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

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.

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有