【发布时间】:2016-11-15 21:20:13
【问题描述】:
在 Windows 和其他桌面操作系统中,显示设置中的组合框始终显示所有可用的显示分辨率。
我在 Qt 或 C++ 中需要这种组合框,但我被卡住了。
我在这里找到了 C# 方法:How to list available video modes using C#?
我找到了一个 C++ 方法:How to Detect Maximize event on multi-monitor system
MSDN 在EnumDisplaySettingsEx function 文档中说,所有显示分辨率都可以通过迭代参数 iModeNum 来获得:
图形模式索引从零开始。要获取显示设备的所有图形模式的信息,请对 EnumDisplaySettingsEx 进行一系列调用,如下所示: 第一次调用时将 iModeNum 设置为零,并为每个后续调用将 iModeNum 增加一。继续调用函数,直到返回值为零。
我已经修改了 C++ 方法以在 Windows 中实现我的目标:
#include <QCoreApplication>
#include <windows.h>
#include <stdio.h>
#define DEFAULT_DISPLAY_WIDTH 0
#define DEFAULT_DISPLAY_HEIGHT 0
#define DEFAULT_DISPLAY_FREQUENCY 60
#define DEFAULT_DISPLAY_SOURCE 0
struct DisplayResolution
{
DisplayResolution( int _width = DEFAULT_DISPLAY_WIDTH,
int _height = DEFAULT_DISPLAY_HEIGHT,
int _frequency = DEFAULT_DISPLAY_FREQUENCY,
int _defaultSource = DEFAULT_DISPLAY_SOURCE )
{
width = _width;
height = _height;
frequency = _frequency;
defaultSource = _defaultSource;
}
int width;
int height;
int frequency;
int defaultSource;
};
typedef std::vector<DisplayResolution>::iterator DisplayResolutionIterator;
std::vector<DisplayResolution> getAvailableDisplayResolutions( )
{
DISPLAY_DEVICE disp;
DISPLAY_DEVICE adapter;
DEVMODE mode;
std::vector<DisplayResolution> displayResolutions;
int i = 0, j = 0, display_count = 0, k = 0;
// Initialize win32 structs.
memset(&disp, 0, sizeof(DISPLAY_DEVICE));
disp.cb = sizeof(DISPLAY_DEVICE);
memset(&adapter, 0, sizeof(DISPLAY_DEVICE));
adapter.cb = sizeof(DISPLAY_DEVICE);
memset(&mode, 0, sizeof(DEVMODE));
mode.dmSize = sizeof(DEVMODE);
//memset(the_displays, 0, sizeof(the_displays));
// adapter loop:
while(EnumDisplayDevices(NULL, i, &adapter, 0))
{ // multiple displays on single adapter loop:
j = 0;
qDebug() << (TCHAR*)&adapter.DeviceName;
while(EnumDisplayDevices((TCHAR*)&adapter.DeviceName, j, &disp, 0))
{
// The device must be active, attached to desktop and not a mirroring device.
if((disp.StateFlags & DISPLAY_DEVICE_ACTIVE)
&& (disp.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)
&& !(disp.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER))
{
// read display settings.
k = 0;
while(EnumDisplaySettingsEx((TCHAR*)&adapter.DeviceName, k, &mode, 0))
{
displayResolutions.push_back( DisplayResolution(mode.dmPelsWidth,
mode.dmPelsHeight,
mode.dmDisplayFrequency,
mode.dmDefaultSource) );
// Reset
memset(&mode, 0, sizeof(DEVMODE));
mode.dmSize = sizeof(DEVMODE);
++display_count;
++k;
}
}
// Reset
memset(&disp, 0, sizeof(DISPLAY_DEVICE));
disp.cb = sizeof(DISPLAY_DEVICE);
++j;
}
// Reset
memset(&adapter, 0, sizeof(DISPLAY_DEVICE));
adapter.cb = sizeof(DISPLAY_DEVICE);
++i;
}
return displayResolutions;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
std::vector<DisplayResolution> displayResolutions = getAvailableDisplayResolutions( );
DisplayResolutionIterator it = displayResolutions.begin();
DisplayResolutionIterator itEnd = displayResolutions.end();
for( it; it != itEnd; ++it )
{
printf( "Resolution: " );
printf( "%i x %i", (*it).width, (*it).height );
printf( " (%iHz)", (*it).frequency );
printf( " @Source:%i", (*it).defaultSource );
printf( "\n" );
}
return a.exec();
}
希望它可以帮助 Windows 中的人们阅读本文,但 Unix?
我知道 Qt 中的一种方法,但这只会通过QDesktopWidget::availableGeometry 收集当前显示分辨率。
Qt 有接收所有可用显示分辨率的方法吗?
亲切的问候,
皮克斯
【问题讨论】:
-
如果你在 X11 上运行,那么有 X 特定的机制可以做到这一点。对于其他一切,您需要一种特定于后端的方法。
-
所以你的意思是XOpenDisplay 和DefaultScreenOfDisplay。据我了解 - 这将使我只能访问当前的显示分辨率,而不是所有可用的分辨率。
-
这只给你当前的分辨率。无论如何,这是一个单独的问题——也许搜索一下,你会发现它已经被问到并得到了回答。
标签: c++ qt cross-platform desktop-application screen-resolution