【C++】Windows環境で解像度の変更

2018年7月6日

個人的なメモとして、C++によるWindows環境での解像度変更処理について書き記します。

解像度の変更は、WindowsAPIを使用した方法になります。API自体はC言語でもほぼ同じように扱えます。

※サンプルコードはexeとして実行するとコンソール出力した内容がわからないので、

Sleep(ミリ秒);

で確認するのが良いかも・・・

主に使用する関数や構造体

DEVMODE

ディスプレイの設定情報を保持する構造体です。

EnumDisplaySettings

ディスプレイの設定情報などを取得できる関数。

EnumDisplaySettings(
  ディスプレイデバイス(基本NULLで問題ない)
  ,ディスプレイ情報インデックス(0以上)
  ,DEVMODE構造体へのポインタ(実行後に値が設定されます。)
);

戻り値は成功したかどうかを返します。0なら失敗。それ以外は成功。

ENUM_CURRENT_SETTINGSをインデックスへ指定することによって、現在の設定情報を取得します。

ChangeDisplaySettings

解像度の変更を実行する関数。

ChangeDisplaySettings(
  DEVMODE構造体へのポインタ(変更したいサイズや色数を指定して構造体を引き渡す)
  ,グラフィックスモードの変更方法
);

グラフィックスモードの変更方法にはCDS_FULLSCREENを指定すると、アプリケーション終了時に元の解像度に戻るようになる。

戻り値がDISP_CHANGE_SUCCESSFULである場合は設定の変更に成功したことを示す。

詳細はこちらの公式ドキュメントを参考に

インクルードヘッダ

ヘッダはwindows.hをインクルードしておくと、これらの関数などが利用できるようになる。

現在の解像度設定情報を表示する

現在の解像度設定情報を取得するにはEnumDisplaySettings関数を使用します。2番目の引数にENUM_CURRENT_SETTINGSを指定しましょう。

実行後にDEVMODE構造体に結果が取得されます。

#include <windows.h>
#include <iostream>
#include <string>

int main(void) {
	//画面情報構造体
	DEVMODE mode;

	//現在の画面情報を取得
	EnumDisplaySettings(nullptr, ENUM_CURRENT_SETTINGS, &mode);

	//横幅、縦幅、リフレッシュレート、色数を取得して表示処理
	std::string str = "";
	str += "横幅:" + std::to_string(mode.dmPelsWidth);
	str += ",縦幅:" + std::to_string(mode.dmPelsHeight);
	str += ",リフレッシュレート:" + std::to_string(mode.dmDisplayFrequency);
	str += ",色数:" + std::to_string(mode.dmBitsPerPel);
	std::cout << str << std::endl;

	return 0;
}
実行結果

横幅:1920,縦幅:1080,リフレッシュレート:60,色数:32

設定可能な解像度を取得して情報表示する

設定可能なすべての情報を取得するにはEnumDisplaySettingsで無限ループを実行し、取得失敗するまで回し続けます。

二番目の引数にはインデックスを渡します。

#include <windows.h>
#include <iostream>
#include <string>

int main(void) {

	for (int i = 0; i < 100000; i++) {

		//画面情報構造体
		DEVMODE mode;

		//現在の画面情報を取得
		BOOL res = EnumDisplaySettings(nullptr, i, &mode);
		if (!res)break;

		//横幅、縦幅、リフレッシュレート、色数を取得して表示処理
		std::string str = "";
		str += "横幅:" + std::to_string(mode.dmPelsWidth);
		str += ",縦幅:" + std::to_string(mode.dmPelsHeight);
		str += ",リフレッシュレート:" + std::to_string(mode.dmDisplayFrequency);
		str += ",色数:" + std::to_string(mode.dmBitsPerPel);
		std::cout << str << std::endl;

	}

	return 0;
}
実行結果(多すぎるため一部のみ)

横幅:1680,縦幅:1050,リフレッシュレート:60,色数:32
横幅:1680,縦幅:1050,リフレッシュレート:60,色数:32
横幅:1680,縦幅:1050,リフレッシュレート:60,色数:32
横幅:1920,縦幅:1080,リフレッシュレート:60,色数:8
横幅:1920,縦幅:1080,リフレッシュレート:60,色数:16
横幅:1920,縦幅:1080,リフレッシュレート:60,色数:32

解像度を変更する

解像度の変更するにはChangeDisplaySettings関数を呼び出す。

下記サンプルは現在の設定情報を取得し、そこに横幅と縦幅のみ変更し、ChangeDisplaySettingsを実行、解像度変更しています。

#include <windows.h>
#include <iostream>
#include <string>
#include <thread>

int main(void) {
	//画面情報構造体
	DEVMODE mode;

	//現在の画面情報を取得
	BOOL res = EnumDisplaySettings(nullptr, ENUM_CURRENT_SETTINGS, &mode);

	//640×480に変更
	mode.dmPelsWidth = 640;
	mode.dmPelsHeight = 480;

	//解像度の変更
	ChangeDisplaySettings(&mode, CDS_FULLSCREEN);

	//解像度変更を確認するために5秒スリープ
	std::this_thread::sleep_for(std::chrono::seconds(5));

	return 0;
}
実行結果(イメージ)

左右に黒い領域が追加され拡大されて表示されたかんじになります。

C++

Posted by nompor