VC 多屏控制显示文章整理
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 多屏控制显示文章整理相关推荐
- 使用Python控制1602液晶屏实时显示时间(附PyCharm远程调试)
前言 原创文章,转载引用务必注明链接.水平有限,如有疏漏,欢迎指正. 本文介绍一下UP板的GPIO资源使用,以及一个使用Python演示一个简单的demo. 本文使用Markdown写成,为获得更好的 ...
- FPGA实现图像任意位置显示,串口协议控制显示位置,提供工程源码和技术支持
目录 1.图像任意位置显示理论基础 2.设计思路和架构 3.OV5640图像采集 4.图像DDR3三帧缓存 5.图像任意位置输出显示 6.串口协议控制显示位置 7.vivado工程介绍 8.上板调试验 ...
- Android QQ音乐/酷狗音乐锁屏控制实现原理,酷狗锁屏
混乱的锁屏控制 Android自4.0版本, 也就是API level 14开始, 加入了锁屏控制的功能, 相关的类是RemoteControlClient, 这个类在API level 21中被标记 ...
- 【STM32标准库】【自制库】0.96寸OLED显示屏(SSD1306)(2)全屏动画显示
文章目录 链接 需求分析 取模 pr操作 修改大小 python操作 显示动画 前期准备 动画帧发送 动画实现 成品 文章基于适用于STM32F4系列,作者使用STM32F401CCU6开发板. 本文 ...
- QQ音乐/酷狗音乐锁屏控制实现原理
我实现的效果 混乱的锁屏控制 Android自4.0版本, 也就是API level 14开始, 加入了锁屏控制的功能, 相关的类是RemoteControlClient, 这个类在API level ...
- 利用c51进行数模转换并在液晶屏上显示_基于C51单片机的智能计算器、矩阵键盘、lcd1602...
目录 1绪论.............................................................................................. ...
- 云优后台提交显示parsererror_微信现场大屏实时显示结果现场投票活动制作方法...
原标题:微信现场大屏实时显示结果现场投票活动制作方法 在文艺晚会上,才艺节目竞赛中,当表演者表演完之后,可能会在现场进行投票表决.因为表演者想要评比出名次,自然需要在现场活动中通过观众或者是评委来进行 ...
- STF简单修改实现安卓多机同屏控制
背景: STF是一个非常优秀的安卓真机管理平台,近期团队同学在看安卓真机适配方面的事情,想到如果采用STF来进行多机同屏控制那将是一件非常nice的事情. 动手: 初步看了一下STF的代码,前端主要是 ...
- winform,wpf全屏 还显示任务栏的解决方法
winform,wpf全屏 还显示任务栏的解决方法 参考文章: (1)winform,wpf全屏 还显示任务栏的解决方法 (2)https://www.cnblogs.com/Viki/archive ...
最新文章
- 在VS2010中创建自定义的代码段
- Linux图形分区编辑器 GParted Live 1.0 Beta 发布
- osfmount 命令加载虚拟光驱_OSFMount挂载虚拟磁盘工具下载
- xmpp muc 群聊协议 1
- java的配置文件后缀,Java - 敏感配置文件位置
- web图片铺满网页_html5的video的背景图片poster铺满全屏大小方法
- 《SQL Server 必知必会》读书笔记
- 深度学习在植物种类及病害识别领域的研究
- 凸函数与简森不等式(Jensen's inequality)
- 【java学习之旅】——JSP入门
- 迅为4412开发板上的步进电机小知识
- 4g内存 mysql_mysql 4G内存配置表
- YARN学习总结-第九节-YARN-Web-App-Proxy
- wps表格l制作甘特图_如何制作甘特图(横道图)
- SPSS Modeler 数据整理之变量设定 (指南 第三章)
- 【揭秘】CSDN博客上,超过百万访问量的Android牛人都是谁?
- 微信屏蔽跳去App Store链接的解决方法
- 人物渲染篇(二) —— 基础卡通渲染 下
- 亚马逊测评到底是一个什么样的项目流程?测评新风口,深度解析
- 2022-05-08 基于卷积神经网络ResNet的车型识别(实验)