您的位置:首页 > 其它

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

2017-02-04 23:13 537 查看
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: