关于获取多个屏幕分辨率以及进行一些设置

Windows下提示显示器信息主要通过两个函数实现。一个是EnumDisplayDevices(), 另一个是EnumDisplayMonitors().
EnumDisplayDevices()枚举所有显示设备,而EnumDisplayMonitors枚举的是所有显示器。
显示设备和显示器不一样,比如显卡算显示设备,但是不是显示器。
EnumDisplayMonitors()还会枚举出不可见的伪显示器,如果只是想得到实际的显示器数目的话可以用GetSystemMetrics(SM_CMONITORS),该函数不包括虚拟显示器。

MonitorInfoex 和MonitorInfo 在这两个结构中保存着相应显示器的相关信息,如坐标、是否为主显示器等
GetMonitorInfo ( )  取得指定显示器的相关信息,如物理显示区大小等
MonitorFromPoint ( )  取得指定点所在的显示器句柄
MonitorFromRect ( )  取得指定矩形所在的显示器句柄
MonitorFromWindow( )  取得指定窗口所在的显示器句柄
MonitorEnumProc( ) 当应用程序调用EnumDisplayMonitors ( )查询显示器个数时,系统自动为每一个显示器调用一次该函数。应用程序可以依此判断显示器的个数、位置及显示区域的大小等信息

函数名:MonitorEnumProc()
输入参数:HMONITOR hMonitor ---显示器句柄
          HDC hdcMonitor  ----显示器DC句柄
        LPRECT lprcMonitor-----
        LPARAM dwData-----EnumDisplayMonitors传来的数据
返回:bool
功能:若返回为真,EnumDisplayMonitors继续枚举,
      若返回为假,EnumDisplayMonitors停止枚举,从而获得显示器信息

MonitorAdapter.h
#include <atlstr.h>
#include <vector>
#include <WinDef.h>
#include <tchar.h>
using std::vector;

using namespace std;

#define MAX_MONITOR_NAME 256

static std::vector<HMONITOR> g_hMonitorGroup;  

// 显示器模式信息
typedef struct MonitorModeInfo_t
{
	unsigned int m_nWidth;			    
	unsigned int m_nHeight;

	MonitorModeInfo_t(int nWidth, int nHeight) : m_nWidth(nWidth), m_nHeight(nHeight) {}
}MonitorModeInfo;

// 显示器信息
struct MonitorInfo
{
	TCHAR szDevice[MAX_MONITOR_NAME];					// 显示器名称
	std::vector<MonitorModeInfo> m_vecModeInfo;			// 当前名称的显示器支持的分辨率模式
};

typedef std::vector<MonitorInfo> VEC_MONITORMODE_INFO;  // 所有的显示器信息	


class MonitorAdapter
{
public:
	MonitorAdapter();
	~MonitorAdapter();
	// 回调函数
	static int CALLBACK MonitorEnumProc(HMONITOR hMonitor, 
		HDC hdc,
		LPRECT lpRMonitor,
		LPARAM dwData);

	// 得到所有显示器的名称
	void GetAllMonitorName(VEC_MONITORMODE_INFO& m_vecMonitorListInfo);

	// 得到所有显示器的模式
	void GetAllDisplayMode(VEC_MONITORMODE_INFO& m_vecMonitorListInfo);

	//得到屏幕当前分辨率
	void GetCurrentReselotion(int& nWidth,int& nHeight,int& nFreq,int& nBits);

	//根据屏幕ID取获取屏幕的对应分辨率
	void GetCurrentReselotion(LPCWSTR lpszDeviceName, int& nWidth, int& nHeight, int& nFreq, int& nBits);

	//修改分辨率
	int ChangMonitorReselotion(HMONITOR hMonitor,const int nWidth,const int nHight,const int nFre,const int nColorBits);
};

MonitorAdapter.cpp
#include "stdafx.h"
#include "MonitorAdapter.h"

MonitorAdapter::MonitorAdapter(void)
{
}

MonitorAdapter::~MonitorAdapter(void)
{
}


int CALLBACK MonitorAdapter::MonitorEnumProc(HMONITOR hMonitor, 
											 HDC hdc,
											 LPRECT lpRMonitor,
											 LPARAM dwData)
{
	g_hMonitorGroup.push_back(hMonitor);
	return 1;
}


// 得到所有显示器的名称
void MonitorAdapter::GetAllMonitorName(VEC_MONITORMODE_INFO& vecMonitorListInfo)
{
	g_hMonitorGroup.clear();
	::EnumDisplayMonitors(NULL, NULL, MonitorEnumProc, 0);

	//vector<HMONITOR>::iterator ithMoniter = g_hMonitorGroup.begin();
	for(int i = 0; i < g_hMonitorGroup.size();i++)
	{
		MONITORINFOEX mixTemp;
		memset(&mixTemp, 0, sizeof(MONITORINFOEX));
		mixTemp.cbSize = sizeof(MONITORINFOEX);

		GetMonitorInfo(g_hMonitorGroup[i], &mixTemp);
		VEC_MONITORMODE_INFO::iterator itBeg = vecMonitorListInfo.begin();
		VEC_MONITORMODE_INFO::iterator itEnd = vecMonitorListInfo.end();
		for(; itBeg != itEnd; ++itBeg)
		{
			if( 0 == _tcscmp(mixTemp.szDevice, itBeg->szDevice))
			{
				break;
			}
		}

		//没有在列表中找到,则需要添加
		if (itBeg == itEnd)	   
		{
			MonitorInfo tmpMonitorInfo;
			_tcscpy_s(tmpMonitorInfo.szDevice, sizeof(tmpMonitorInfo.szDevice), mixTemp.szDevice);
			vecMonitorListInfo.push_back(tmpMonitorInfo);
		}
	} 
}


// 得到所有显示器的模式
void MonitorAdapter::GetAllDisplayMode(VEC_MONITORMODE_INFO& vecMonitorListInfo)
{
	GetAllMonitorName(vecMonitorListInfo);

	bool		 bRetVal;
	DEVMODE 	 devmode;

	VEC_MONITORMODE_INFO::iterator itBeg = vecMonitorListInfo.begin();
	VEC_MONITORMODE_INFO::iterator itEnd = vecMonitorListInfo.end();
	for (NULL; itBeg != itEnd; ++itBeg)
	{
		int iMode = 0;
		do
		{
			bRetVal = ::EnumDisplaySettings(itBeg->szDevice, iMode, &devmode);
			iMode++;
			if (bRetVal)
			{
				bool bFind = false;

				vector<MonitorModeInfo>::iterator itBeg_Mode = itBeg->m_vecModeInfo.begin();
				vector<MonitorModeInfo>::iterator itEnd_Mode = itBeg->m_vecModeInfo.end();
				for (NULL; itBeg_Mode != itEnd_Mode; ++itBeg_Mode)
				{
					// 如果已经在列表中找到,则结束本次循环
					if ((itBeg_Mode->m_nWidth == devmode.dmPelsWidth) && (itBeg_Mode->m_nHeight == devmode.dmPelsHeight))
					{
						bFind = true;
						break;
					}

					// 插入数据时,从 大到小排列 (按windows 分辨率设置,优先比较 宽) 
					if (
						(itBeg_Mode->m_nWidth < devmode.dmPelsWidth) ||
						((itBeg_Mode->m_nWidth == devmode.dmPelsWidth) && (itBeg_Mode->m_nHeight < devmode.dmPelsHeight))
						)
					{ 							
						break;
					}
				}

				if(!bFind)
				{
					if (itBeg_Mode == itEnd_Mode)
					{
						itBeg->m_vecModeInfo.push_back(MonitorModeInfo(devmode.dmPelsWidth, devmode.dmPelsHeight)); 
					}
					else
					{
						itBeg->m_vecModeInfo.insert(itBeg_Mode, MonitorModeInfo(devmode.dmPelsWidth, devmode.dmPelsHeight)); 
					}
				}
			}
		}
		while (bRetVal); 
	} 
}


int MonitorAdapter::ChangMonitorReselotion(HMONITOR hMonitor,const int nWidth,const int nHight,const int nFre,const int nColorBits)
{
	if ( NULL == hMonitor )
	{
		return -1;
	}
	MONITORINFOEX mi;
	mi.cbSize = sizeof(mi);
	GetMonitorInfo( hMonitor , &mi);
	DEVMODE DeviceMode;
	ZeroMemory(&DeviceMode, sizeof(DEVMODE));
	DeviceMode.dmSize = sizeof(DEVMODE); 

	BOOL bFlag = TRUE;
	bFlag = EnumDisplaySettings(mi.szDevice, ENUM_CURRENT_SETTINGS, &DeviceMode);
	if ( bFlag != TRUE )
	{
		return -1;
	}	
	if (DeviceMode.dmPelsWidth == nWidth && DeviceMode.dmPelsHeight == nHight )
	{
		return 0;
	}
	DeviceMode.dmDisplayFlags = 0;
	DeviceMode.dmPelsWidth= nWidth;		
	DeviceMode.dmPelsHeight = nHight;

	DeviceMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY ;

	int nRet = ChangeDisplaySettingsEx(mi.szDevice, &DeviceMode, NULL, CDS_GLOBAL | CDS_NORESET | CDS_UPDATEREGISTRY, NULL);
	if (DISP_CHANGE_BADMODE == nRet)
	{
		ChangeDisplaySettingsEx(mi.szDevice, &DeviceMode, NULL, CDS_GLOBAL | CDS_NORESET | CDS_UPDATEREGISTRY, NULL);		

	}
	if ( DISP_CHANGE_SUCCESSFUL == nRet )
	{
		return 0;
	}
	return -1;
}

void MonitorAdapter::GetCurrentReselotion(int& nWidth,int& nHeight,int& nFreq,int& nBits)
{
	DEVMODE DeviceMode;
	EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &DeviceMode);
	nWidth = DeviceMode.dmPelsWidth;
	nHeight = DeviceMode.dmPelsHeight;
	nFreq = DeviceMode.dmDisplayFrequency;
	nBits = DeviceMode.dmBitsPerPel;
}

void MonitorAdapter::GetCurrentReselotion(LPCWSTR lpszDeviceName, int& nWidth, int& nHeight, int& nFreq, int& nBits)
{
	DEVMODE DeviceMode;
	EnumDisplaySettings(lpszDeviceName, ENUM_CURRENT_SETTINGS, &DeviceMode);
	nWidth = DeviceMode.dmPelsWidth;
	nHeight = DeviceMode.dmPelsHeight;
	nFreq = DeviceMode.dmDisplayFrequency;
	nBits = DeviceMode.dmBitsPerPel;
}

test

#include "stdafx.h"
#include "MonitorAdapter.h"

int _tmain(int argc, _TCHAR* argv[])
{
	MonitorAdapter			m_monitorAdapter;		//显示器
	VEC_MONITORMODE_INFO vecMointorListInfo;
	m_monitorAdapter.GetAllDisplayMode(vecMointorListInfo);

	int nWidth = 0, nHeight = 0, nFreq = 0, nBits = 0;
	VEC_MONITORMODE_INFO::iterator itBeg = vecMointorListInfo.begin();
	for (int i = 0; i < vecMointorListInfo.size();i++)
	{
		//得到当前显示器分辨率 刷新率 色位
		m_monitorAdapter.GetCurrentReselotion(itBeg->szDevice, nWidth, nHeight, nFreq, nBits);
		itBeg++;
		nWidth = 0, nHeight = 0, nFreq = 0, nBits = 0;
	}
	
	return 0;
}



  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值