サンプルコードの実行結果

実行すると次のようなシンプルなウィンドウが表示される。

  • winmain.exeの実行サンプル

    winmain.exeの実行サンプル

チュートリアルのソースコードとしては長くなってきているが、基本的には次の流れで処理を行っているだけだ。

  1. ウィンドウクラスの作成・登録
  2. ウィンドウの作成・表示
  3. ウィンドウメッセージループを実行

前回はこの「ウィンドウクラスの作成」について説明を行った。Windows APIでは「ウィンドウクラス」といっても実態はC++のクラスではなく、WNDCLASSという構造体だ。この構造体に各種データやポインタを配置しておいて、ウィンドウの共有データとして利用する。

上記のサンプルソースコードで、該当する部分は次の部分だ。

ウィンドウクラス構造体にデータを設定

    // ウィンドウクラス構造体を用意
    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;

ウィンドウクラス構造体には、複数のウィンドウに共通する動作セットがまとめられている。このアプリケーションで表示されるウィンドウは、共通の動作としてこのウィンドウクラス構造体の記述に従うということだ。

まずは、この構造体に設定している内容を書き換えることで、どのような違いが出るのかを試して体感してみてほしい。今回は、わかりやすい例として、次の行を書き換えることで動作を変えてみる。

基本となるマウスカーソル(矢印)を指定

    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);

上記コードはマウスカーソルとして「矢印」のマウスカーソルを指定している。Windowsで最も基本的なマウスカーソルだ。

カーソルの書き換えと実行サンプル

もう一度、該当するソースコードを見てみよう。

基本となるマウスカーソルを指定

    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);

「IDC_ARROW」が、マウスカーソルとして「矢印」を指定している部分だ。この部分を変更すると別のマウスカーソルになる。

指定できるマウスカーソルは、次の通りとなっている(参考「LoadCursorA function (winuser.h) - Win32 apps | Microsoft Docs」)。

マウスカーソル 内容
IDC_APPSTARTING 矢印と砂時計
IDC_ARROW 矢印
IDC_CROSS 十字
IDC_HAND
IDC_HELP 矢印と?
IDC_IBEAM Iビーム
IDC_NO スラッシュサークル
IDC_SIZEALL 東西南北矢印
IDC_SIZENESW 北東と南西の二重矢印
IDC_SIZENS 南北の二重矢印
IDC_SIZENWSE 北西と南東の二重矢印
IDC_SIZEWE 西と東の二重矢印
IDC_UPARROW 垂直矢印
IDC_WAIT 砂時計

シンプルな書き換えだが、実際に起きる変化がひと目でわかる。書き換えの演習としては取り組みやすく結果もわかりやすい。早速書き換えてビルドし、実行結果を見てみよう。

マウスカーソル:矢印 IDC_ARROW

    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
  • 実行サンプル - IDC_ARROW

    実行サンプル - IDC_ARROW

マウスカーソル:十字 IDC_CROSS

    wc.hCursor       = LoadCursor(NULL, IDC_CROSS);
  • 実行サンプル - IDC_CROSS

    実行サンプル - IDC_CROSS

マウスカーソル:手 IDC_HAND

    wc.hCursor       = LoadCursor(NULL, IDC_HAND);
  • 実行サンプル - IDC_HAND

    実行サンプル - IDC_HAND

マウスカーソル:北東と南西の二重矢印 IDC_SIZENESW

    wc.hCursor       = LoadCursor(NULL, IDC_SIZENESW);
  • 実行サンプル - IDC_SIZENESW

    実行サンプル - IDC_SIZENESW

マウスカーソル:砂時計 IDC_WAIT

    wc.hCursor       = LoadCursor(NULL, IDC_WAIT);
  • 実行サンプル - IDC_WAIT

    実行サンプル - IDC_WAIT

このように、ウィンドウクラスで指定するデフォルトのマウスカーソル指定を変更することで、ウィンドウ全体のマウスカーソルを変更できることがわかる。特定のエリアのマウスカーソルだけを変更したり、状態に応じてマウスカーソルを変更したりという操作をどのようにやるのかも、こうした部分に触れておくと理解しやすくなる。

なお、IDC_WAITで表示されるマウスカーソルは以前は砂時計だったが、現在のデザインはもう砂時計ではなくなっている。処理に時間がかかっていることを示すマウスカーソルは、「ローディング中」を意味するようなアニメーションアイコンに変わっている。この辺りはオペレーティングが表示するものなので、オペレーティングシステムの使いが変わると表示されるマウスカーソルも変わることになる。