Win32APIでウィンドウの表示

はじめに

Win32APIを使用したウィンドウの表示(よく使うけどよく忘れるため)
一応,WINMAINとmainの両方

環境

WINMAINの方

設定

ソリューションエクスプローラー > プロジェクト名 > 構成プロパティ > リンカー > システム > サブシステム > Windows(/SUBSYSTEM:WINDOWS)を選択 > OK

コード

main.cpp

#include <Windows.h>
#include <string>
#include <cstdint>

std::wstring WindowClassName = L"MainWindow";
uint32_t wWidth = 1080;
uint32_t wHeight = 720;

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    switch (msg)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd, msg, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, int nCmdShow) {
    HWND hwnd;
    WNDCLASSEX wc = {};
    MSG msg = {};

    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WndProc;
    wc.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
    wc.hCursor = LoadCursor(hInstance, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    wc.hInstance = hInstance;
    wc.lpszMenuName = nullptr;
    wc.lpszClassName = WindowClassName.c_str();
    wc.hIconSm = LoadIcon(hInstance, IDI_APPLICATION);

    RegisterClassEx(&wc);

    hwnd = CreateWindowEx(
        0,
        WindowClassName.c_str(),
        L"Title",
        WS_OVERLAPPEDWINDOW,
        0, 0,
        wWidth, wHeight,
        nullptr, nullptr,
        hInstance,
        nullptr
    );

    ShowWindow(hwnd, SW_SHOWNORMAL);
    UpdateWindow(hwnd);
    SetFocus(hwnd);

    while (WM_QUIT != msg.message)
    {
        if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE == true))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else
        {
            //ここに処理を追加


            UpdateWindow(hwnd);
        }
    }

    return 0;
}

mainの方

設定

ソリューションエクスプローラー > プロジェクト名 > 構成プロパティ > リンカー > システム > サブシステム > コンソール(/SUBSYSTEM:CONSOLE)を選択 > OK

ファイル構成

コード

App.h

#pragma once

#include <Windows.h>
#include <cstdint>
#include <string>

class App {
public:
    App();
    void Run();

private:
    bool InitApp();
    bool InitWindow();
    void MainLoop();

    static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);

private:
    const std::wstring WindowClassName = L"MainWindow";

    uint32_t _width;
    uint32_t _height;

    HWND _hwnd;
    HINSTANCE _hInstance;
};

WindowClassNameは何でもいい

App.cpp

#include "App.h"

App::App() {
    _width = 1080;
    _height = 720;
    _hwnd = nullptr;
    _hInstance = nullptr;
}

void App::Run() {
    if (!InitApp()) {
        return;
    }

    MainLoop();
}

//初期化
bool App::InitApp() {

    if (!InitWindow()) {
        return false;
    }

    return true;
}

//ウィンドウの初期化
bool App::InitWindow() {
    _hInstance = GetModuleHandle(nullptr);
    if (_hInstance == nullptr) {
        return false;
    }

    //ウィンドウの設定
    WNDCLASSEX wc = {};
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = CS_HREDRAW | CS_VREDRAW;     //水平方向と垂直方向のサイズ変更で再描画
    wc.lpfnWndProc = WndProc;   //ウィンドウプロシージャの登録
    wc.hIcon = LoadIcon(_hInstance, IDI_APPLICATION);    //アイコン
    wc.hCursor = LoadCursor(_hInstance, IDC_ARROW);      //マウスカーソル
    wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); //背景色は黒
    wc.hInstance = _hInstance;  //インスタンスハンドル
    wc.lpszMenuName = nullptr;  //メニュー
    wc.lpszClassName = WindowClassName.c_str();      //ウィンドウクラスの名前
    wc.hIconSm = LoadIcon(_hInstance, IDI_APPLICATION);      //小さいアイコン

    RegisterClassEx(&wc);    //ウィンドウクラスの登録

    _hwnd = CreateWindowEx(
        0,
        WindowClassName.c_str(),
        L"Title",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT,
        _width, _height,
        nullptr, nullptr,
        _hInstance,
        nullptr
    );

    ShowWindow(_hwnd, SW_SHOWNORMAL);
    UpdateWindow(_hwnd);

    SetFocus(_hwnd);

    return true;
}

//メインループ
void App::MainLoop() {
    MSG msg = {};
    while (WM_QUIT != msg.message)
    {
        if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE == true))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else
        {
            //ここに処理を追加


            UpdateWindow(_hwnd);
        }
    }
}

//ウィンドウプロシージャ
LRESULT CALLBACK App::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    switch (msg) {
    case WM_DESTROY:
        PostQuitMessage(0);
        break;

    default:
        break;
    }

    return DefWindowProc(hwnd, msg, wParam, lParam);
}

main.cpp

#include "App.h"

int main() {
    App app = App();
    app.Run();
}

参考資料

wisdom.sakura.ne.jp