Windowを表示するだけのクラス
- スクリーンショットは都合上、300x200の大きさにしています。
ウィンドウを複数作れるように、基本となるクラスを作ってみた。まあ、ウィンドウをたくさん作ることもあまりないし、細かいことをしようと思うとどうせプロシージャをいじる必要が出てくるのであまり使えないですが、次のように継承することで簡単にウィンドウを生成できます。ただし、ウィンドウクラスは自分で登録する必要があり、コンストラクタを呼び出す前に作らないといけません;
テストケース
int WINAPI WinMain(HINSTANCE h_instance, HINSTANCE h_prev_instance, LPSTR command_line, int command_show) { try { EditWindow::Register(); EditWindow ew; ew.show(); } catch(WindowException& e) { return -1; } return Application::Run(); }
定義
- edit_window.h
#pragma once #include "window.h" class EditWindow : public Window<EditWindow> { public: EditWindow(); void onLButtonUp() override; static void Register(); };
- edit_window.cpp
#include "edit_window.h" EditWindow::EditWindow() { create("window name", 100, 100, 100, 100); } void EditWindow::onLButtonUp() { MessageBox(h_wnd, "TEST", "TEST", MB_OK); } void EditWindow::Register() { WNDCLASS wndc; wndc.style = CS_HREDRAW | CS_VREDRAW; wndc.lpfnWndProc = WindowProc; wndc.cbClsExtra = wndc.cbWndExtra = 0; wndc.hInstance = GetModuleHandle(NULL); wndc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndc.hCursor = LoadCursor(NULL, IDC_ARROW); wndc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndc.lpszMenuName = NULL; class_name = wndc.lpszClassName = "MainWindow"; if(!RegisterClass(&wndc)) { throw WindowException::RegisterException(); } }
実装
- window.h
#pragma once #include <Windows.h> #include <exception> template <typename DerivedWindow> class Window { public: Window() = default; void create(const char* title, int x, int y, int width, int height) { CreateWindow( class_name, title, WS_OVERLAPPEDWINDOW, x, y, width, height, NULL, NULL, GetModuleHandle(NULL), this); // ここに来るのはWM_CREATEメッセージの処理の後 if(h_wnd == NULL) { throw std::exception(); } } void show() { ShowWindow(h_wnd, SW_SHOW); } protected: virtual void onCreate() { }; virtual void onPaint() { }; virtual void onLButtonUp() { }; virtual void onCommand(WPARAM wp, LPARAM lp) { }; static LRESULT CALLBACK WindowProc(HWND h_wnd, UINT msg, WPARAM wp, LPARAM lp) { auto self = (DerivedWindow*)(GetWindowLongPtr(h_wnd, GWLP_USERDATA)); if(self == NULL) { if(msg == WM_CREATE) { self = (DerivedWindow*)(((LPCREATESTRUCT)lp)->lpCreateParams); SetWindowLongPtr(h_wnd, GWLP_USERDATA, (LONG_PTR)self); self->h_wnd = h_wnd; self->onCreate(); } return DefWindowProc(h_wnd, msg, wp, lp); } else { return self->mainProc(h_wnd, msg, wp, lp); } } LRESULT mainProc(HWND h_wnd, UINT msg, WPARAM wp, LPARAM lp) { switch(msg) { case WM_DESTROY: PostQuitMessage(0); return 0; case WM_LBUTTONUP: onLButtonUp(); break; case WM_PAINT: onPaint(); break; case WM_COMMAND: onCommand(wp, lp); break; } return DefWindowProc(h_wnd, msg, wp, lp); } HWND h_wnd; static const char* class_name; }; class WindowException : std::exception { public: class RegisterException; }; class WindowException::RegisterException { }; template <typename DerivedWindow> const char* Window<DerivedWindow>::class_name;