转自:http://cauchy.blog.163.com/blog/static/175272539201251991510720/ 

由于工程需要在多个显示器上显示不同类容,故查找了一些资料来满足这个功能。在VC中分为三步来操作:检测显示器个数;读取屏幕分辨率和其他参数;设置程序的显示坐标。

第一步:检测屏幕个数

       网上查找到的通用方法有两个:EnumDisplayDevicess和GetSystemMetrics,下面分别介绍一下:

       A。EnumDisplayDevices(百度百科连接:http://baike.baidu.com/view/1080527.htm?fr=ala0_1,MSDN连接:http://msdn.microsoft.com/en-us/library/windows/desktop/dd162609(v=vs.85).aspx

函数功能:该函数可得到系统中显示设备的信息。   

函数原型:BOOL EnumDisplayDevices (PVOID Unused, DWORD iDevNum, PDISPLAY_DEVICE lpDisplayDevice,

DWORD dwFlags);

其中第一个参数和最后一个参数现在都还没用到,主要是第二个参数和第三个,这里简要介绍一下

iDevNum:指定感兴趣的显示设备的索引值,操作系统通过索引值确定每一个显示设备。索引值是连续的整数。从0开始,例如:如果一个系统有三个显示设备,那么它们的索引值为0、1、2。

lpdisplayDevice:DISPLAY_DEVICE结构的指针,该结构检索由iDevNum指定的显示设备的信息,在调用EnumDisplayDevices之前,必须以字节为单位把DISPLAY_DEVICE结构中cb元素初始化为DISPLAY_DEVICE结构的大小。

示例代码:

INT iNumber=0; BOOL bFlag=TRUE;

DISPLAY_DEVICE dd; ZeroMemory(&dd,sizeof(dd)); dd.cb =sizeof(dd);

DEVMODE devMode; ZeroMemory(&devMode,sizeof(devMode)); devMode.dmSize=sizeof(devMode);

do {

bFlag =EnumDisplayDevices(NULL, iNumber,&dd,0);

bFlag=bFlag&&EnumDisplaySettings(dd.DeviceName,ENUM_CURRENT_SETTINGS,&devMode);

if(bFlag) iNumber +=1;

}

while(bFlag);

其中iNumber中就为系统所带显示器的数量,网上很多地方都没有红色这一行,这样检测的结果并不准确,
我用的笔记本不管是不是有外接显示器,检测出的数字始终为5,
查看了这篇日志(http://hi.baidu.com/lin65505578/item/ffa9c32598b14fc3a5275add)后添加了红色语句后,运行结果就正常了。
猜想EnumDisplayDevices只是检测系统中存在的显示设备,并不一定是当前一定在用的设备。添加设置语句后,就可以检测到正在使用的设备了。
B.int WINAPI GetSystemMetrics(  __in  int nIndex)
(MSDN连接:http://msdn.microsoft.com/en-us/library/windows/desktop/ms724385(v=vs.85).aspx)
用于得到被定义的系统数据或者系统配置信息,百度百科上的资料较老,不全面。
只要设置nIndex为SM_CMONITORS即可,MSDN的解释为:The number of display monitors on a desktop. 
示例代码:

  INT iNumber=GetSystemMetrics(SM_CMONITORS);

CString csNum;

csNum.Format(_T("%d"),iNumber);

MessageBox(csNum,_T("显示器数量"),MB_OK);

相比A中的设置,这个简单多了,推荐使用此函数。

第二步,读取显示器参数及其他参数

该过程使用前面的两个API函数:EnumDisplayDevices和EnumDisplaySettings。

//初始化

BOOL bFlag;

DISPLAY_DEVICE dd;

ZeroMemory(&dd,sizeof(dd));

dd.cb =sizeof(dd);

DEVMODE devMode;

ZeroMemory(&devMode,sizeof(devMode));

devMode.dmSize=sizeof(devMode);

bFlag=EnumDisplayDevices(BULL,iNumber,&dd,0);

if(bFlag)

return FLASE;

bFlag=EnumDisplayDevices(dd.DeviceName,ENUM_CURRENT_SETTINGS,&devMode);

iNumber为要查询的显示器编号,从0开始,主屏为0,然后1,2,3....一直下去。
查询为EnumDisplaySettings(),查询的数据存储在devMode中,常用的为dmPosition(为当前显示器的坐标位置),dmPelsWidth,dmPelsHeight(为当前显示器的分辨率),
其余根据自己需要参见MSDN(http://msdn.microsoft.com/en-us/library/windows/desktop/dd183565(v=vs.85).aspx).
第三步:设置当前程序的显示位置
在前两步的基础上,根据自己的需要来设置当前程序的显示坐标(ps:如果对系统虚拟坐标不了解的可以去查看一下相关资料)
示例代码:

CRect reTemp;

reTemp.BottomRight()=CPoint(devMode.dmPelsWidth+devMode.dmPosition.x,devMode.dmPelsHeight);

reTemp.TopLeft()=CPoint(devMode.dmPosition.x,devMode.dmPosition.y);

MoveWindow(&reTemp);

这段代码添加在MFC程序中的OnInitDialog()中,这样程序一开始运行就可以在你想要显示的屏幕中运行.
posted on 2013-07-29 11:11  竟飞工作室  阅读(2219)  评论(0编辑  收藏  举报