http://download.csdn.net/detail/finerpfw/9260539

一、多屏显示器的获取

1.      先将模板示例程序文件夹中的User32.Lib文件拷贝至程序文件夹中

2.      在用于检测显示器名称的.cpp中添加如下头文件

3.      添加检测显示器代码:

void CSHView::OnButton2()

{

// TODO: Add your control notification handlercode here

//获得显示屏的名称

int  i;//显示器总数

BOOL flag;

DISPLAY_DEVICE dd;

i = 0;

flag = true;

ZeroMemory(&dd, sizeof(dd));

dd.cb = sizeof(dd);

do

{

flag = EnumDisplayDevices(NULL, i,&dd, 0);

if (flag) i ++;

} while (flag);

}

通过调试时查看dd.DeviceName中的显示器名称。一般看到的显示器名称为

“\\.\DISPLAY1”第二个显示名称为“\\.\DISPLAY2”。

但对应到程序中设置的名称时String cstrDeviceName=“\\\\.\\DISPLAY1”。

VC程序中“\”需用“\\”表示。

4.      双屏显示代码

voidCSHView::OnButton1()

{

// TODO: Add your control notification handlercode here

CString cstrDeviceName="\\\\.\\DISPLAY2";  //显示器名称“\\\\.\\DISPLAY1”由OnButton2()中的DISPLAY_DEVICEdd得到,调试时查看dd.DeviceName的显示器名称

DEVMODE devMode;

devMode.dmSize = sizeof(DEVMODE);

devMode.dmDriverExtra = sizeof(DEVMODE);

int nRet = EnumDisplaySettings(cstrDeviceName,ENUM_CURRENT_SETTINGS,&devMode);

if(nRet)

{

int x, y, cx, cy;

x = devMode.dmPosition.x;

y = devMode.dmPosition.y;

cx = devMode.dmPelsWidth;

cy = devMode.dmPelsHeight;

g_pDlgShow=new CDialog1;

g_pDlgShow->Create(IDD_DIALOG1);

g_pDlgShow->ShowWindow(SW_SHOW);

g_pDlgShow->SetWindowPos(&wndTop,x, y, cx, cy, SWP_SHOWWINDOW);

g_pDlgShow->ShowWindow(SW_SHOWMAXIMIZED);

}

}

5.      实际显示器号,跟电脑设置有关

如图:说明主显示屏的编号为:"\\\\.\\DISPLAY2"。

副显示屏的编号为:"\\\\.\\DISPLAY1"。

本文下载 地址 :http://download.csdn.net/download/finerpfw/9260539

上面文章错误纠正:http://cauchy.blog.163.com/blog/static/175272539201251991510720/

二、VC多屏幕显示

由于工程需要在多个显示器上显示不同类容,故查找了一些资料来满足这个功能。在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()中,这样程序一开始运行就可以在你想要显示的屏幕中运行.
 
 

三、其他封装多屏显示控制调用:

http://squallblog.blog.163.com/blog/static/1750938952012115112524980/
 

VC实现多屏显示(原创)

  直接贴源码吧,vc2008调试通过。只贴多屏显示相关操作类。

h文件如下:

/**********************************************

Copyright(c) 欧博科技软件部

文件名称:SquallMultiScreen.h
 文件描述:多屏显示操作类
 当前版本:1.0 v
 作    者:Squall(朱一)
 完成日期:2012-12-4

说明:
 1、此类只适用于单卡双屏的控制(目前绝大多数A卡、N卡都是双屏显卡);
 2、双屏显卡包括一个主屏,一个副屏;可配置不同分辨率,可配置不同的位置关系;
 3、该类通过推算虚拟屏与主屏的位置关系,查找出副屏的坐标;

***********************************************/

#pragma once

class CSquallMultiScreen
{
private:
 CRect m_MainScreen;  //主屏
 CRect m_VirtualScreen; //虚拟屏(主屏和副屏的外接矩形)

public:
 CSquallMultiScreen(void);
 ~CSquallMultiScreen(void);

longGetScreenCount();     //获取屏幕数量

CRectGetVirtualScreenRect(void);  //返回虚拟屏尺寸
 CRect GetMainScreenRect(void);   //返回主屏尺寸
 CRect GetSecondaryScreenRect(void);  //返回副屏尺寸

//显示窗体(将窗体移动至主屏或副屏的某个位置)
 void DisplayWindow( HWND hWnd, int x, int y, BOOL IsMainScreen = TRUE); 
};

cpp文件如下: 

#include"StdAfx.h"
#include "SquallMultiScreen.h"

CSquallMultiScreen::CSquallMultiScreen(void)
{
 m_MainScreen.left = 0;
 m_MainScreen.top = 0;
 m_MainScreen.right = ::GetSystemMetrics(SM_CXSCREEN);
 m_MainScreen.bottom = ::GetSystemMetrics(SM_CYSCREEN);

m_VirtualScreen.left= ::GetSystemMetrics(SM_XVIRTUALSCREEN);
 m_VirtualScreen.top = ::GetSystemMetrics(SM_YVIRTUALSCREEN);
 m_VirtualScreen.right = m_VirtualScreen.left +::GetSystemMetrics(SM_CXVIRTUALSCREEN);
 m_VirtualScreen.bottom = m_VirtualScreen.top +::GetSystemMetrics(SM_CYVIRTUALSCREEN);
}

CSquallMultiScreen::~CSquallMultiScreen()
{
}

longCSquallMultiScreen::GetScreenCount()
{
 return ::GetSystemMetrics(SM_CMONITORS);
}

CRectCSquallMultiScreen::GetVirtualScreenRect(void)
{
 return m_VirtualScreen;
}

CRectCSquallMultiScreen::GetMainScreenRect(void)
{
 return m_MainScreen;
}

CRectCSquallMultiScreen::GetSecondaryScreenRect(void)
{
 if ( GetScreenCount() > 1 )
 {
  //用MainScreen和VirtualScreen的矩形中心点坐标来比较。判断8个方位的关系。

CPoint mc =m_MainScreen.CenterPoint();  //MainCenter
  CPoint vc = m_VirtualScreen.CenterPoint(); //VirtualCenter
  CPoint TestPoint;

ASSERT(!(vc.x == mc.x && vc.y == mc.y) );

if ( vc.x ==mc.x && vc.y < mc.y ) //正上
  {
   TestPoint.SetPoint( vc.x, m_VirtualScreen.top );
  }

if ( vc.x> mc.x && vc.y < mc.y ) //右上
  {
   TestPoint.SetPoint( m_VirtualScreen.right,m_VirtualScreen.top );
  }

if ( vc.x> mc.x && vc.y == mc.y ) //正右
  {
   TestPoint.SetPoint( m_VirtualScreen.right, vc.y );
  }

if ( vc.x> mc.x && vc.y > mc.y ) //右下
  {
   TestPoint.SetPoint( m_VirtualScreen.right,m_VirtualScreen.bottom );
  }

if ( vc.x ==mc.x && vc.y > mc.y ) //正下
  {
   TestPoint.SetPoint( vc.x, m_VirtualScreen.bottom );
  }

if ( vc.x< mc.x && vc.y > mc.y ) //左下
  {
   TestPoint.SetPoint( m_VirtualScreen.left,m_VirtualScreen.bottom );
  }

if ( vc.x< mc.x && vc.y == mc.y ) //正左
  {
   TestPoint.SetPoint( m_VirtualScreen.left, vc.y );
  }

if ( vc.x< mc.x && vc.y < mc.y ) //左上
  {
   TestPoint.SetPoint( m_VirtualScreen.left, m_VirtualScreen.top);
  }
  
  MONITORINFO mi;
  memset( &mi, 0, sizeof(MONITORINFO) );
  mi.cbSize = sizeof(MONITORINFO);

HMONITORhScreen = MonitorFromPoint( TestPoint, MONITOR_DEFAULTTONEAREST );
  GetMonitorInfo( hScreen, &mi );
  ASSERT( mi.dwFlags == 0 );

returnCRect( mi.rcMonitor );
 }
 else
 {
  return CRect(0,0,0,0);
 }
}

voidCSquallMultiScreen::DisplayWindow( HWND hWnd, int x, int y, BOOL IsMainScreen )
{
 ASSERT( hWnd );

long nLeft =0,nTop = 0;

if ( IsMainScreen)
 {
  nLeft = x;
  nTop = y;
 }
 else
 {
  if ( GetScreenCount() > 1 )
  {
   CRect SecRect = GetSecondaryScreenRect();

nLeft= SecRect.left + x;
   nTop = SecRect.top + y;
  }
  else
  {
   nLeft = x;
   nTop = y;
  }
 }

::SetWindowPos(hWnd, NULL, nLeft, nTop, NULL, NULL, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOZORDER);
}

  以上是实现类。具体的使用非常简单,如果显示模态对话框,在对话框初始化函数中进行位置调整;如果显示非模态对话框,在Create函数后调整位置。
 

VC 多屏控制显示文章整理相关推荐

  1. 使用Python控制1602液晶屏实时显示时间(附PyCharm远程调试)

    前言 原创文章,转载引用务必注明链接.水平有限,如有疏漏,欢迎指正. 本文介绍一下UP板的GPIO资源使用,以及一个使用Python演示一个简单的demo. 本文使用Markdown写成,为获得更好的 ...

  2. FPGA实现图像任意位置显示,串口协议控制显示位置,提供工程源码和技术支持

    目录 1.图像任意位置显示理论基础 2.设计思路和架构 3.OV5640图像采集 4.图像DDR3三帧缓存 5.图像任意位置输出显示 6.串口协议控制显示位置 7.vivado工程介绍 8.上板调试验 ...

  3. Android QQ音乐/酷狗音乐锁屏控制实现原理,酷狗锁屏

    混乱的锁屏控制 Android自4.0版本, 也就是API level 14开始, 加入了锁屏控制的功能, 相关的类是RemoteControlClient, 这个类在API level 21中被标记 ...

  4. 【STM32标准库】【自制库】0.96寸OLED显示屏(SSD1306)(2)全屏动画显示

    文章目录 链接 需求分析 取模 pr操作 修改大小 python操作 显示动画 前期准备 动画帧发送 动画实现 成品 文章基于适用于STM32F4系列,作者使用STM32F401CCU6开发板. 本文 ...

  5. QQ音乐/酷狗音乐锁屏控制实现原理

    我实现的效果 混乱的锁屏控制 Android自4.0版本, 也就是API level 14开始, 加入了锁屏控制的功能, 相关的类是RemoteControlClient, 这个类在API level ...

  6. 利用c51进行数模转换并在液晶屏上显示_基于C51单片机的智能计算器、矩阵键盘、lcd1602...

    目录 1绪论.............................................................................................. ...

  7. 云优后台提交显示parsererror_微信现场大屏实时显示结果现场投票活动制作方法...

    原标题:微信现场大屏实时显示结果现场投票活动制作方法 在文艺晚会上,才艺节目竞赛中,当表演者表演完之后,可能会在现场进行投票表决.因为表演者想要评比出名次,自然需要在现场活动中通过观众或者是评委来进行 ...

  8. STF简单修改实现安卓多机同屏控制

    背景: STF是一个非常优秀的安卓真机管理平台,近期团队同学在看安卓真机适配方面的事情,想到如果采用STF来进行多机同屏控制那将是一件非常nice的事情. 动手: 初步看了一下STF的代码,前端主要是 ...

  9. winform,wpf全屏 还显示任务栏的解决方法

    winform,wpf全屏 还显示任务栏的解决方法 参考文章: (1)winform,wpf全屏 还显示任务栏的解决方法 (2)https://www.cnblogs.com/Viki/archive ...

最新文章

  1. 在VS2010中创建自定义的代码段
  2. Linux图形分区编辑器 GParted Live 1.0 Beta 发布
  3. osfmount 命令加载虚拟光驱_OSFMount挂载虚拟磁盘工具下载
  4. xmpp muc 群聊协议 1
  5. java的配置文件后缀,Java - 敏感配置文件位置
  6. web图片铺满网页_html5的video的背景图片poster铺满全屏大小方法
  7. 《SQL Server 必知必会》读书笔记
  8. 深度学习在植物种类及病害识别领域的研究
  9. 凸函数与简森不等式(Jensen's inequality)
  10. 【java学习之旅】——JSP入门
  11. 迅为4412开发板上的步进电机小知识
  12. 4g内存 mysql_mysql 4G内存配置表
  13. YARN学习总结-第九节-YARN-Web-App-Proxy
  14. wps表格l制作甘特图_如何制作甘特图(横道图)
  15. SPSS Modeler 数据整理之变量设定 (指南 第三章)
  16. 【揭秘】CSDN博客上,超过百万访问量的Android牛人都是谁?
  17. 微信屏蔽跳去App Store链接的解决方法
  18. 人物渲染篇(二) —— 基础卡通渲染 下
  19. 亚马逊测评到底是一个什么样的项目流程?测评新风口,深度解析
  20. 2022-05-08 基于卷积神经网络ResNet的车型识别(实验)

热门文章

  1. 罗永浩与他的锤子手机!
  2. windows10升级windows11后微信等软件无法连接网络
  3. 深剖函数重载——C++基础篇
  4. 一文看懂未来加密行业如何应对监管?
  5. eclipse使用总结
  6. 【linux】容器之代码自动发布-docker
  7. STM32使用DMA在Normal模式下二次传输
  8. HDU 6304 Chiaki Sequence Revisited(找规律)
  9. 一年级古诗风语文知识心田花开汇总
  10. 红灯三秒亮一次,绿灯一秒亮一次,黄灯2秒亮一次;如何让三个灯不断交替重复亮灯?