参考:http://www.codeproject.com/Articles/2518/Enumerate-and-Change-Display-Modes
http://support.microsoft.com/kb/306399/zh-cn
缘由: 通过远程桌面的形式控制一台电脑屏幕分辨率等设置 .. (说白了,就是想用远程模仿一个, 类似于右击弹出的,"屏幕分辨率" 的功能)
简单 demo 程序:
#include "stdafx.h"
#include <atlstr.h>
#include <stdio.h>
#include <vector>
struct displayMode
{
int m_nWidth;
int m_nHeight;
displayMode(int nWidth_, int nHeight_) :
m_nWidth(nWidth_), m_nHeight(nHeight_)
{
}
};
// 得到所有显示器的模式
void GetAllDisplayMode(std::vector<displayMode>& vecDisplayMode_)
{
vecDisplayMode_.clear();
BOOL bRetVal;
CString sDevMode;
int iMode = 0;
DEVMODE devmode;
do
{
bRetVal = ::EnumDisplaySettings(NULL, iMode, &devmode);
iMode++;
if (bRetVal)
{
// 这里显示出更多的信息.. 没有用到.故注释掉
//printf("%d x %d, %d bits %dhtz \n",
// devmode.dmPelsWidth, devmode.dmPelsHeight,
// devmode.dmBitsPerPel, devmode.dmDisplayFrequency);
std::vector<displayMode>::iterator itBeg = vecDisplayMode_.begin();
std::vector<displayMode>::iterator itEnd = vecDisplayMode_.end();
for (NULL; itBeg != itEnd; ++itBeg)
{
if ((itBeg->m_nWidth == devmode.dmPelsWidth) && (itBeg->m_nHeight == devmode.dmPelsHeight))
{
break;
}
}
if (itBeg == itEnd)
{
vecDisplayMode_.push_back(displayMode(devmode.dmPelsWidth, devmode.dmPelsHeight));
}
}
}
while (bRetVal);
}
int _tmain(int argc, _TCHAR* argv[])
{
std::vector<displayMode> vecDisplayMode_;
GetAllDisplayMode(vecDisplayMode_);
int nSize = vecDisplayMode_.size();
for (int i = 0; i < nSize; ++i)
{
printf("%d x %d \n", vecDisplayMode_[i].m_nWidth, vecDisplayMode_[i].m_nHeight);
}
return 0;
}
===========================================================================================================================
略作完善的 Demo :
工程文件,可在资源那里找到
/***********************************************
文件名: GetMonitorAllResolution.h
创建/修改者: benben
创建/修改时间: 2013.01.14
功能: 获取所有显示器的所有分辨率的组合
***********************************************/
// 属性: 设置为字符为:未设定 ,如果是 UNICODE时,改cout 为wcout 才能正确输出设备名称
#include "stdafx.h"
#include <atlstr.h>
#include <stdio.h>
#include <vector>
#include <WinDef.h>
#include <iostream>
using std::vector;
static std::vector<HMONITOR> hMonitorGroup; // 声明为静态变量,限定为本文件作用域
// 定义结构体
//
// 显示器模式信息
struct MonitorModeInfo
{
unsigned int m_nWidth;
unsigned int m_nHeight;
MonitorModeInfo(int nWidth_, int nHeight_) : m_nWidth(nWidth_), m_nHeight(nHeight_) {}
};
// 显示器信息
struct MonitorInfo
{
TCHAR szDevice[CCHDEVICENAME]; // 显示器名称
vector<MonitorModeInfo> m_vecModeInfo; // 当前名称的显示器支持的分辨率模式
};
typedef std::vector<MonitorInfo> VEC_MONITORMODE_INFO; // 所有的显示器信息
class MonitorMode
{
private:
// 回调函数
static int CALLBACK MonitorEnumProc(HMONITOR hMonitor,
HDC hdc,
LPRECT lpRMonitor,
LPARAM dwData)
{
hMonitorGroup.push_back(hMonitor);
return 1;
}
// 得到所有显示器的名称
void GetAllMonitorName(VEC_MONITORMODE_INFO& m_vecMonitorListInfo)
{
::EnumDisplayMonitors(NULL, NULL, MonitorEnumProc, 0);
for(vector<HMONITOR>::iterator itehMoniter = hMonitorGroup.begin(); itehMoniter != hMonitorGroup.end(); itehMoniter++)
{
MONITORINFOEX mixTemp;
memset(&mixTemp, 0, sizeof(MONITORINFOEX));
mixTemp.cbSize = sizeof(MONITORINFOEX);
GetMonitorInfo(*itehMoniter, &mixTemp);
VEC_MONITORMODE_INFO::iterator itBeg = m_vecMonitorListInfo.begin();
VEC_MONITORMODE_INFO::iterator itEnd = m_vecMonitorListInfo.end();
for (NULL; itBeg != itEnd; ++itBeg)
{
if( 0 == _tcscmp(mixTemp.szDevice, itBeg->szDevice) ) // 比较字符串,相等
{
break;
}
}
if (itBeg == itEnd) // 没有在列表中找到,则需要添加
{
MonitorInfo tmpMonitorInfo;
_tcscpy_s(tmpMonitorInfo.szDevice, sizeof(tmpMonitorInfo.szDevice)/sizeof(tmpMonitorInfo.szDevice[0]), mixTemp.szDevice);
m_vecMonitorListInfo.push_back(tmpMonitorInfo);
}
}
}
public:
// 得到所有显示器的模式
void GetAllDisplayMode(VEC_MONITORMODE_INFO& m_vecMonitorListInfo)
{
GetAllMonitorName(m_vecMonitorListInfo);
BOOL bRetVal;
CString sDevMode;
DEVMODE devmode;
VEC_MONITORMODE_INFO::iterator itBeg = m_vecMonitorListInfo.begin();
VEC_MONITORMODE_INFO::iterator itEnd = m_vecMonitorListInfo.end();
for (NULL; itBeg != itEnd; ++itBeg)
{
int iMode = 0;
do
{
bRetVal = ::EnumDisplaySettings(itBeg->szDevice, iMode, &devmode);
iMode++;
if (bRetVal)
{
// 这里显示出更多的信息.. 没有用到.故注释掉
//printf("%d x %d, %d bits %dhtz \n",
// devmode.dmPelsWidth, devmode.dmPelsHeight,
// devmode.dmBitsPerPel, devmode.dmDisplayFrequency);
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 _tmain(int argc, _TCHAR* argv[])
{
VEC_MONITORMODE_INFO vecMointorListInfo;
MonitorMode monitorMode;
monitorMode.GetAllDisplayMode(vecMointorListInfo);
int nSize = vecMointorListInfo.size();
for (int i = 0; i < nSize; ++i)
{
std::cout << "-------------------------------" << std::endl;
std::cout << vecMointorListInfo[i].szDevice << std::endl;
vector<MonitorModeInfo>::iterator itBeg = vecMointorListInfo[i].m_vecModeInfo.begin();
vector<MonitorModeInfo>::iterator itEnd = vecMointorListInfo[i].m_vecModeInfo.end();
for (NULL; itBeg != itEnd; ++itBeg)
{
std::cout << " Width * Height = " << itBeg->m_nWidth << " x " << itBeg->m_nHeight << std::endl;
}
}
return 0;
}
简单测试下,设置屏幕位置
// 其他函数都和上一个相同.唯一修改的就是 main 函数
int _tmain(int argc, _TCHAR* argv[])
{
VEC_MONITORMODE_INFO vecMointorListInfo;
MonitorMode monitorMode;
monitorMode.GetAllDisplayMode(vecMointorListInfo);
int nSize = vecMointorListInfo.size();
for (int i = 0; i < nSize; ++i)
{
//std::wcout << "-------------------------------" << std::endl;
//std::wcout << vecMointorListInfo[i].szDevice << std::endl;
//
//vector<MonitorModeInfo>::iterator itBeg = vecMointorListInfo[i].m_vecModeInfo.begin();
//vector<MonitorModeInfo>::iterator itEnd = vecMointorListInfo[i].m_vecModeInfo.end();
//for (NULL; itBeg != itEnd; ++itBeg)
//{
// std::cout << " Width * Height = " << itBeg->m_nWidth << " x " << itBeg->m_nHeight << std::endl;
//}
// 测试 调整屏幕
int x = 0;
int y = 0;
POINTL pos = {x + i*1000, y + 1080*i};
std::wcout << vecMointorListInfo[i].szDevice << std::endl;
std::wcout << pos.x << " " << pos.y << std::endl << std::endl;
DEVMODE lpDevmode;
EnumDisplaySettings(NULL,0,&lpDevmode);
lpDevmode.dmPosition = pos;
lpDevmode.dmSize = sizeof(lpDevmode);
lpDevmode.dmFields = DM_POSITION;
ChangeDisplaySettingsEx(vecMointorListInfo[i].szDevice, &lpDevmode, NULL, CDS_UPDATEREGISTRY, NULL);
}
return 0;
}