初めてのウィンドウプログラミング

前回、Windows APIを使ってシンプルなウィンドウを作成するサンプルコードを紹介した。ダイアログを作成する場合と比べるとだいぶソースコードが増えたが、前回取り上げたサンプルソースコードは、Windowsにおけるウィンドウプログラミングのエッセンスが詰まっており、ウィンドウプログラミングを理解するうえでとても大切なものだ。

以下が、前回に取り上げたサンプルコードだ(今後説明しやすいようにいくらか変更してある)。

winmain.c

#ifndef UNICODE
#define UNICODE
#endif 

#include <windows.h>

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

/*
 * ウィンドウプログラムエントリポイント関数
 */
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
    // ウィンドウクラス名
    const wchar_t CLASS_NAME[]  = L"ウィンドウ作成の学習用プログラムクラス";

    // ウィンドウクラス構造体を用意
    WNDCLASS wc;

    wc.style         = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc   = WindowProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInstance;
    wc.hIcon         = NULL;
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = CLASS_NAME;

    // ウィンドウクラス構造体を登録
    RegisterClass(&wc);

    // ウィンドウを作成
    HWND hwnd = CreateWindowEx(
        0,                               // ウィンドウスタイル(オプション)
        CLASS_NAME,                      // ウィンドウクラス名
        L"ウィンドウプログラミング学習", // ウィンドウタイトル
        WS_OVERLAPPEDWINDOW,             // ウィンドウスタイル

        // サイズとポジション
        CW_USEDEFAULT, 
    CW_USEDEFAULT, 
    CW_USEDEFAULT, 
    CW_USEDEFAULT,

        NULL,       // 親ウィンドウ
        NULL,       // メニュー
        hInstance,  // インスタンスハンドル
        NULL        // 追加のアプリケーションデータ
        );

    if (hwnd == NULL)
    {
        return 0;
    }

    // ウィンドウを表示
    ShowWindow(hwnd, nCmdShow);

    // メッセージループを実行
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return 0;
}

/*
 * ウィンドウプロシージャ関数
 */
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;

    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hwnd, &ps);

            FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW+1));

            EndPaint(hwnd, &ps);
        }
        return 0;
    }
    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
  • winmain.cの実行サンプル

    winmain.cの実行サンプル

上記のサンプルソースコードは、MicrosoftがWindows APIを使ったウィンドウプログラミングのチュートリアルとして提供している次のドキュメントから、本連載でセットアップした開発環境でビルドして使用できるように多少の変更を加えたものだ。

このサンプルソースコードはWindowsにおけるウィンドウプログラミングのエッセンスが詰まっている。一度にすべてを説明することはできないので、最初に構造を示した上で、最初から順に説明を行っていく。