C++

2025/4/30 作成

ウィンドウの作成

お手軽プログラミングシリーズのNo.2です。JavaScriptでは円を描いて動かしていましたが、C++のウィンドウの表示だけでも長いので、今回はそのことについて書いていきます。ちなみに、自分も作ってから説明するので、1時間くらいで書いていく予定です。

開発環境の構築についての説明は飛ばして、新しいプロジェクトの作成からやっていきます。事前にVisual Studio Communityをダウンロードしておきましょう。ここでは2022版を使っていきます。ワークロードで[C++によるデスクトップ開発]の環境をインストールしていることを前提に話を進めます。

Visual Studio 2022を起動したら、[新しいプロジェクトの作成]をクリックし、言語選択から[C++]を選び、[Windows デスクトップウィザード]をダブルクリックします。

画像

そしたら、プロジェクト名を書き、好きな保存場所を選び、[ソリューションとプロジェクトを同じディレクトリに配置する]にチェックを入れ、[作成]をクリックします。

画像

アプリケーションの種類を[デスクトップアプリケーション]にして、[空のプロジェクト]にチェックを入れ、[OK]をクリックしましょう。

画像

そうすると、ウィンドウを使ったアプリを作れるプロジェクトが作成されます。

最初は手順が多くて面倒だと思いますが、何回も使っているうちに何も考えなくてもすぐにプロジェクトを立ち上げられるようになります。

最初にやることは、コードを書くファイルを追加することです。ソリューション エクスプローラーのソースファイルを右クリックして、[追加]→[新しい項目]から、「main.cpp」というファイルを作りましょう。そして、一気に次のコードを書きます。

#include <windows.h>

const int WIDTH = 800;
const int HEIGHT = 600;
const wchar_t TITLE[] = L"ウィンドウの表示";

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

int WINAPI wWinMain(_In_ HINSTANCE hInst, _In_opt_ HINSTANCE hPrev, _In_ PWSTR pCmd, _In_ int nCmd)
{
    WNDCLASS wc = {};
    wc.lpfnWndProc = WindowProc;
    wc.hInstance = hInst;
    wc.lpszClassName = L"Window Class";
    RegisterClass(&wc);

    RECT rc = { 0, 0, WIDTH, HEIGHT };
    AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);
    HWND hwnd = CreateWindowEx(0, wc.lpszClassName, TITLE,
        WS_OVERLAPPEDWINDOW ^ WS_SIZEBOX ^ WS_MAXIMIZEBOX,
        CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top,
        NULL, NULL, hInst, NULL);
    if (hwnd == NULL) return 0;

    ShowWindow(hwnd, nCmd);

    MSG msg = {};
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessageW(&msg);
    }

    return 0;
}

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

一見すると難しいコードのように思えますが、単にウィンドウを表示しているだけです。一つ一つのコードについて書くと長くなり、自分の使える時間的に厳しいので、大体で説明します。詳しくは関数などをググって調べてみてください。

さて、上から説明していきましょう。#inlucdeでwindows.hというヘッダーファイルを読み込んでいます。このヘッダーファイルには、ウィンドウを扱うための機能がたくさん入っています。

constと書いている部分は、いつでも簡単にウィンドウの幅、高さ、タイトルを変更できるようにしたものです。このように書くといつでも値を変更して遊ぶことができます。

LRESULTの部分は、関数の前方宣言です。関数の実行順からいうと、wWinMainが先になり、WindowProcが後になります。ただ、事前に関数を宣言していないとwWinMainの中で読み込めないので前方宣言しているのです。

wWinMain関数が、プログラムが起動したら最初に実行されるものになります。WNDCLASS構造体でウィンドウの設定をして、CreateWindowEx関数でウィンドウを作成し、ShowWindow関数でウィンドウを表示し、GetMessage関数を使ってMSG構造体にOSからのメッセージを受け取っています。何気に重要なのはDispatchMessage関数で、これを使うことにより、ウィンドウプロシージャにメッセージを送っています。

ウィンドウプロシージャというのは、イベントを入れておく部分のことです。ここでは、WindowProc関数がそれを担っています。wWinMainでwhileループによりウィンドウプロシージャにメッセージを送っていますが、PostQuitMessage関数が呼ばれるとmsgに終了の合図が送られ、whileループが終了することになり、ウィンドウが閉じられます。ここでは、メッセージ(msg)がWM_DESTROY、ウィンドウの×ボタンを押すことによりPostQuitMessageが呼ばれ、ウィンドウが終了することになります。

以上がウィンドウ作成の大雑把な説明です。細かく見ようとするとそれだけ時間がかかるので、なんとなく覚えておきましょう。特に、コードの真ん中のほうにあるCreateWindowEx関数では、ウィンドウの幅や高さ、タイトル、スタイルなどを決めています。それは個人的にググればある程度把握できるでしょう。突っ込んで学ぼうとすると大変なのがC++プログラミングとなっています。楽しむことを第一に、C++プログラミングを楽しんでいきましょう。