8
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

DXlibのウィンドウサイズを可変に、Aeroスナップとか最大化も

Posted at

DXlibでエディタのようなものを作った時のメモです。
本来はDXlibでやるようなことではないのですが、わけあって触ることになったので...
#標準の場合
DXlibではウィンドウのサイズが固定されていて、端にカーソルをやってもサイズを変更することはできません。
その辺の設定をする関数もあるのですが、最大化ボタンを押すと全画面表示になったり、ウィンドウの枠が太かったりと気になるところがあります。
色々と試してみたのですが、サイズは変更できるけどAeroスナップ時にサイズがおかしくなる、といった事件が起きたので別の方法を取ることにしました。
もしかしたら見落としているだけで、ちゃんと設定できるのかもしれません(小声)
#じゃあどうすればええの?
DXlibくんにはSetUserWindowという関数があります。
本来はDXlibの初期化時に自動でウィンドウが生成されるのですが、
この関数を初期化の前に呼んでおくことで、自分で作ったウィンドウをDXlibで扱えるようになります。
あとは少し設定をするだけで、問題なく動作します~~(すると思います)~~
#実装してみる
たぶん見るまでもないと思うのですが、無駄に長いソースを貼っておきます。
要はウィンドウは自分で作ればええやんということなので、参考程度に。

長いので分割しています
#include "DxLib.h"
#include <string>
using namespace std;

const int null = NULL;

// DXLib はエラーが発生した場合 -1 を返します
const int dxLibError = -1;
inline bool DXLibError(int result) {
	return result == dxLibError ? true : false;
}

// ちょっとだけ使います
struct Size {
	int width, height;
};
ウィンドウ関連です(最低限だけ実装しています)
// ウィンドウのクラスです
class Window{
	HWND windowHandle = null;
	MSG message = {};
public:

	// ウィンドウプロシージャ
	static LRESULT CALLBACK Procedure(HWND handle, UINT message, WPARAM wParam, LPARAM lParam) {
		switch (message) {
		// 一応終了処理だけ
		case WM_DESTROY:
			PostQuitMessage(0);
			return 0;
		}
		return DefWindowProc(handle, message, wParam, lParam);
	}

	// ウィンドウハンドルを取得する
	HWND GetHandle() {
		return windowHandle;
	}

	// ウィンドウを生成する
	void Create(string title, string className) {
		// クラス情報を登録する
		WNDCLASS windowClass = {};
		windowClass.lpfnWndProc = Procedure;
		windowClass.hInstance = GetModuleHandle(null);
		windowClass.lpszClassName = className.c_str();
		windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
		RegisterClass(&windowClass);
		// ウィンドウを生成する
		windowHandle = CreateWindowEx(0, className.c_str(), title.c_str(), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, null, null, GetModuleHandle(null), null);

	}

	// ウィンドウのサイズを取得する
	Size GetSize() {
		Size result;
		GetWindowSize(&result.width, &result.height);
		return result;
	}

	// メッセージ処理
	bool Loop() {
		while (true) {
			if (message.message == WM_QUIT) return false;
			if (PeekMessage(&message, NULL, 0, 0, PM_REMOVE)) {
				TranslateMessage(&message);
				DispatchMessage(&message);
			}
			else return true;
		}
	}

	// ウィンドウを表示する
	void Show() {
		ShowWindow(windowHandle, SW_SHOW);
	}
};

こ↑こ↓から実際に使ってみます

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {

	// ウィンドウを生成
	Window window;
	window.Create("ヌッ!", "DXlib");
	
	// 使用するウィンドウを設定
	SetUserWindow(window.GetHandle());

	// メッセージ処理は自分でやるよ
	SetUserWindowMessageProcessDXLibFlag(false);

	// 描画可能サイズをディスプレイのサイズに(最大化した時に描画できるように)
	SetGraphMode(GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), 16);

	// 初期化
	if (DXLibError(DxLib_Init())) return dxLibError;

	// ウィンドウを表示
	window.Show();

	// メインループ
	while (window.Loop()) {

		// 試しに枠を描画してみる
		ClearDrawScreen();
		auto &windowSize = window.GetSize();
		DrawBox(0, 0, windowSize.width, windowSize.height, 0xffffff, false);
		ScreenFlip();

	}
	return DxLib_End();
}

#おわり!
ちょっと長かったんとちゃう? ウィンドウ関連のソースを載せる必要はありましたか...?
こんな感じになりましたが、SetGraphModeあたりをもう少し効率よくできる気がしないでもないです。
何かありましたら教えてください何でもしますから!

8
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?