windows API更改系统分辨率支持扩展屏

7 篇文章 0 订阅
2 篇文章 1 订阅

前面介绍了如何使用api更改widnows系统的分辨率。只能更改主屏幕分辨率,这节介绍如何更改多个屏幕的分辨率

要更改多个屏幕的分辨我们需要使用如下函数:

WINUSERAPI LONG WINAPI ChangeDisplaySettingsEx(
    _In_opt_ LPCWSTR lpszDeviceName,
    _In_opt_ DEVMODEW* lpDevMode,
    _Reserved_ HWND hwnd,
    _In_ DWORD dwflags,
    _In_opt_ LPVOID lParam);

ChangeDisplaySettings函数虽然也有lpszDeviceName参数,但是经过测试并不生效,始终改变的是主屏的分辨率。

要更改屏幕分辨率我们需要枚举出这个屏幕支持的分辨率是多少,不支持的分辨率设置是会失败的。

QVector<DisplayInfo> MainWindow::enumSupportDisplayByScreenNumber(int screenNumber, int minDisplayWidth, int minDisplayHeight)
{
    DEVMODE mode;
    ZeroMemory(&mode, sizeof(mode));
    mode.dmSize = sizeof(mode);
    int i = 0;
    QString deviceName = QApplication::screens()[screenNumber]->name();
    bool result = EnumDisplaySettingsEx(deviceName.toStdWString().c_str(), i, &mode, 0);
    QString str = "%1*%2";
    QVector<DisplayInfo>  ret;

    while (result)
    {
         DisplayInfo info;
         strcpy((char *)info.mode.dmDeviceName, deviceName.toStdString().c_str());
         info.width = mode.dmPelsWidth;
         info.height = mode.dmPelsHeight;
         info.name = deviceName;
         info.mode = mode;
         qDebug()<<"ddddddd:"<<QString::fromWCharArray(mode.dmDeviceName);

        if(!ret.contains(info) && mode.dmPelsWidth>= minDisplayWidth && mode.dmPelsHeight>=minDisplayHeight)
        {
            ret.push_back(info);
        }
        result = EnumDisplaySettingsEx(deviceName.toStdWString().c_str(), ++i, &mode, 0);
    }
    return ret;

}

该函数根据屏幕序号获取支持的分辨率并可以将太小的分辨率抛弃。DisplayInfo用于保存屏幕基本信息

struct DisplayInfo
{
    int width;
    int height;
    QString name;
    DEVMODE mode;

};

然后根据选择的屏幕需要进行分辨率更改

  DisplayInfo info = findDisplayInfoByScreenNumber(ui->comboBox_2->currentText(), ui->comboBox->currentText());
    DEVMODE lpDevMode = info.mode;
    lpDevMode.dmPelsWidth=info.width;
    lpDevMode.dmPelsHeight=info.height;
    LONG result;
    result=ChangeDisplaySettingsEx(info.name.toStdWString().c_str(), &lpDevMode,0, 0, 0);
    if (result==DISP_CHANGE_SUCCESSFUL)
    {
        qDebug()<<QStringLiteral("修改成功!");
        //使用CDS_UPDATEREGISTRY表示次修改是持久的
        ChangeDisplaySettingsEx(info.name.toStdWString().c_str(), &lpDevMode,0, CDS_UPDATEREGISTRY, 0);
    }
    else
    {
        qDebug()<<QStringLiteral("修改失败,恢复原有设置!");
        ChangeDisplaySettingsEx(info.name.toStdWString().c_str(), NULL,0, 0, 0);
    }

 

完整代码:

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <qt_windows.h>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

struct DisplayInfo
{
    int width;
    int height;
    QString name;
    DEVMODE mode;

};

bool operator==(const DisplayInfo info1, const DisplayInfo info2);

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void on_pushButton_clicked();

    void on_pushButton_2_clicked();

    void slotscreennumberchanged(const QString &number);


private:
    QVector<DisplayInfo> enumSupportDisplayByScreenNumber(int screenNumber, int minDisplayWidth = 800, int minDisplayHeight = 600);

    DisplayInfo findDisplayInfoByScreenNumber(const QString screenNumber, const QString &display);

private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <qt_windows.h>
#include <QDebug>
#include <QApplication>
#include <QDesktopWidget>
#include <QScreen>
#include <QComboBox>


bool operator==(const DisplayInfo info1, const DisplayInfo info2)
{
    return (info1.width == info2.width) && (info1.height == info2.height);
}


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    connect(ui->comboBox_2, SIGNAL(currentIndexChanged(QString)), this, SLOT(slotscreennumberchanged(QString)));
    for(int i=0; i<QApplication::screens().count(); ++i)
        ui->comboBox_2->addItem(QString::number(i));
    slotscreennumberchanged(ui->comboBox_2->currentText());
}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::on_pushButton_clicked()
{
    DisplayInfo info = findDisplayInfoByScreenNumber(ui->comboBox_2->currentText(), ui->comboBox->currentText());
    DEVMODE lpDevMode = info.mode;
    lpDevMode.dmPelsWidth=info.width;
    lpDevMode.dmPelsHeight=info.height;
    LONG result;
    result=ChangeDisplaySettingsEx(info.name.toStdWString().c_str(), &lpDevMode,0, 0, 0);
    if (result==DISP_CHANGE_SUCCESSFUL)
    {
        qDebug()<<QStringLiteral("修改成功!");
        //使用CDS_UPDATEREGISTRY表示次修改是持久的
        ChangeDisplaySettingsEx(info.name.toStdWString().c_str(), &lpDevMode,0, CDS_UPDATEREGISTRY, 0);
    }
    else
    {
        qDebug()<<QStringLiteral("修改失败,恢复原有设置!");
        ChangeDisplaySettingsEx(info.name.toStdWString().c_str(), NULL,0, 0, 0);
    }
}

QVector<DisplayInfo> MainWindow::enumSupportDisplayByScreenNumber(int screenNumber, int minDisplayWidth, int minDisplayHeight)
{
    DEVMODE mode;
    ZeroMemory(&mode, sizeof(mode));
    mode.dmSize = sizeof(mode);
    int i = 0;
    QString deviceName = QApplication::screens()[screenNumber]->name();
    bool result = EnumDisplaySettingsEx(deviceName.toStdWString().c_str(), i, &mode, 0);
    QString str = "%1*%2";
    QVector<DisplayInfo>  ret;

    while (result)
    {
         DisplayInfo info;
         strcpy((char *)info.mode.dmDeviceName, deviceName.toStdString().c_str());
         info.width = mode.dmPelsWidth;
         info.height = mode.dmPelsHeight;
         info.name = deviceName;
         info.mode = mode;
         qDebug()<<"ddddddd:"<<QString::fromWCharArray(mode.dmDeviceName);

        if(!ret.contains(info) && mode.dmPelsWidth>= minDisplayWidth && mode.dmPelsHeight>=minDisplayHeight)
        {
            ret.push_back(info);
        }
        result = EnumDisplaySettingsEx(deviceName.toStdWString().c_str(), ++i, &mode, 0);
    }
    return ret;

}

DisplayInfo MainWindow::findDisplayInfoByScreenNumber(const QString screenNumber, const QString &display)
{
    QVector<DisplayInfo> rets = enumSupportDisplayByScreenNumber(screenNumber.toInt(), 800, 600);
    foreach(DisplayInfo info, rets)
    {
        QString str = QString::number(info.width) + "*" + QString::number(info.height);
        if(display == str)
            return info;
    }
    return DisplayInfo();
}


void MainWindow::on_pushButton_2_clicked()
{
    enumSupportDisplayByScreenNumber(1, 800, 600);
}


void MainWindow::slotscreennumberchanged(const QString &number)
{
    ui->comboBox->clear();
    QVector<DisplayInfo> rets = enumSupportDisplayByScreenNumber(number.toInt(), 800, 600);
    foreach(DisplayInfo str, rets)
    {
        ui->comboBox->addItem(QString::number(str.width) + "*" + QString::number(str.height));
    }
}

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值