参考: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;
}