C++编程实现多显示器控制(复制、横屏、纵屏,显示器个数)等

需求的提出:

  最近做了个三维的程序,部署到客户机器上,客户看了后,现场提出这样的一个需求:程序能智能探测接入的显示器个数,当有新的显示器接入时,现有的只在一个显示器上显示的三维场景能投递到新插入的显示器上显示。类似在桌面上点击鼠标右键,选择“显示设置”菜单,弹出的如下界面:

然后在此界面,对显示器进行复制、横向、纵向等处理。

可以在程序中开启一个线程,进行探测,探测到显示器个数增加后,调用SetDisplayConfig(0, NULL, 0, NULL, SDC_TOPOLOGY_CLONE | SDC_APPLY);函数进行复制显示器,一旦显示器复制成功,三维程序就会投递到新插入的显示器上,代码如下:

void checkDisplayNumsChangedFun();

// 获取本机显卡接入的显示器个数
int getAllMonitors();

// 上次查询时显示器的个数
int g_nMonitorCount = 0;

int main(int argc, char *argv[])
{
	
	QApplication a(argc, argv);
	
	std::thread* pDisplay = new std::thread(checkDisplayNumsChangedFun);
	
    return a.exec();
}

// 检测显示器个数是否变化了,如果检测到显示器数目增多了,就复制显示器
void checkDisplayNumsChangedFun()
{
	while (true)
	{
		std::this_thread::sleep_for(std::chrono::milliseconds(5000));
		int nMonitorCount = getAllMonitors();

		// 显示器个数减少了,直接返回,不处理显示器减少的情况,也许是某个显示器被人拨掉了
		if (g_nMonitorCount >= nMonitorCount)
		{
			continue;
		}

		CLogToolKits::getInstance()->writeLog(L"有新的显示器插入到主机!");
       
        //change to the clone topology
		SetDisplayConfig(0, NULL, 0, NULL, SDC_TOPOLOGY_CLONE | SDC_APPLY); 
		g_nMonitorCount = nMonitorCount;
	}
}

int getAllMonitors()
{
	std::list<DISPLAY_DEVICE> devices;
	std::list<DEVMODE> modes;
	int devId = 0;
	bool ret = false;
	bool isPrimary = false;
	int nPrimaryNum = 0;

	//list all DisplayDevices (Monitors)
	do
	{
		DISPLAY_DEVICE displayDevice;
		ZeroMemory(&displayDevice, sizeof(DISPLAY_DEVICE));
		displayDevice.cb = sizeof(displayDevice);

		ret = EnumDisplayDevices(NULL, devId, &displayDevice, 0);
		if (ret == true)
		{
			if ((displayDevice.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) == DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)
			{
				devices.push_back(displayDevice);
				isPrimary = ((displayDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) == DISPLAY_DEVICE_PRIMARY_DEVICE);
				if (isPrimary)
				{
					nPrimaryNum = devId;
				}
			}
		}
		devId++;
	} while (ret);

	list<DISPLAY_DEVICE> dev_list;
	dev_list = devices;

	std::list<DISPLAY_DEVICE>::iterator it;
	for (it = dev_list.begin(); it != dev_list.end(); it++)
	{
		DEVMODE deviceMode;
		deviceMode.dmSize = sizeof(DEVMODE);
		deviceMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_POSITION | DM_DISPLAYFREQUENCY | DM_DISPLAYFLAGS; // | DM_DISPLAYORIENTATION;

		EnumDisplaySettings(it->DeviceName, (int)ENUM_REGISTRY_SETTINGS, &deviceMode);
		modes.push_back(deviceMode);
	}

	return modes.size();
}

setDisplayConfig是Windows API函数,搞过MFC开发就童鞋就应该知道,或者装个MSDN查下,在Winuser.h头文件中。

更多对显示器的操作,请参考《VC++编程实现多显示器控制(复制、横屏、纵屏,显示器个数)》

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值