• 【VS开发】MFC多显示器适配显示设置


    由于工程需要在多个显示器上显示不同类容,故查找了一些资料来满足这个功能。在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()中,这样程序一开始运行就可以在你想要显示的屏幕中运行.
  • 相关阅读:
    spring data jpa 不更新 null 值,
    Android 生命周期
    Java相对路径/绝对路径总结
    android 系统广播
    ADB 设置远程调试
    adb server is out of date ADB server didn't ACK * failed to start daemon *一种解决方式
    Windows 8.1 Enterprise Preview
    反编译CMD命令
    判断运营商
    ADT安装
  • 原文地址:https://www.cnblogs.com/huty/p/8517117.html
Copyright © 2020-2023  润新知