CreateWindowEx()でウィンドウを作成

CreateWindowEx()関数で実際にウィンドウを作成する。作成時は、ウィンドウクラス、ウィンドウタイトル、ウィンドウスタイル、X座標、Y座標、ウィンドウ幅、ウィンドウ高さなどを指定する。これが基本的な目に見えるウィンドウになる。なお、明示的に表示を指定しなかった場合、ShowWindow()関数を呼ばない限りウィンドウは表示されない。

CreateWindowEx()関数によるウィンドウの作成部分

    // ウィンドウを作成
    HWND hwnd = CreateWindowEx(
        0,                   // 拡張ウィンドウスタイル
        CLASS_NAME,          // ウィンドウクラス名
        WINDOW_TITLE,        // ウィンドウタイトル
        WS_OVERLAPPEDWINDOW, // ウィンドウスタイル

        // サイズとポジション
        CW_USEDEFAULT,       // X座標
    CW_USEDEFAULT,       // Y座標
    1200,                // 幅
    800,                 // 高さ

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

今回は特にCreateWindowEx()関数の4つ目の引数であるウィンドウスタイルをいじっていく。これはウィンドウの基本的な振る舞いをフラグで指定するものだ。上記のサンプルではWS_OVERLAPPEDWINDOWが指定されているが、これは、実際にはWS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_SIZEBOX | WS_MINIMIZEBOX | WS_MAXIMIZEBOXと指定されて内容と同じで、それぞれに意味がある。

細かな指定ではあるが、この指定がWindowsにおけるウィンドウの基本的な挙動や装飾を定めているところなので、実際にこの部分を書き換えて動作がどのように変わるのかをみてみよう。指定できるウィンドウスタイルとその説明を次にまとめておく。

ウィンドウスタイル 内容
WS_BORDER 細い境界線を持つウィンドウ
WS_CAPTION タイトルバーを持つウィンドウ(WS_BORDERも含む)
WS_CHILD チャイルドウィンドウ。メニューバーを持つことはできない。WS_POPUPと併用することもできない
WS_CHILDWINDOW WS_CHILDと同じ
WS_CLIPCHILDREN 親ウィンドウを描画する際に子ウィンドウが占有する領域は除外するという指定。親ウィンドウを作成するときに使用する
WS_CLIPSIBLINGS 子ウィンドウがWM_PAINTメッセージを受信した場合にその子ウィンドウの領域から重複するほかのウィンドウをクリップして更新を行う。このスタイルが指定されなかった場合、隣接する子ウィンドウのクライアント領域内にも描画される可能性がある
WS_DISABLED ウィンドウを無効化。EnableWindwo()関数を使用するまで無効化のままでユーザからの入力を受け取らない。
WS_DLGFRAME ダイアログボックスで使われるボーダーを使用。タイトルバーを持つことはできない
WS_GROUP コントロールグループの最初のコントロール。ユーザは方向キーを使ってグループ内のコントロールから次のコントロールへフォーカスの意向が可能。ウィンドウ作成後にSetWindowLong()関数を使用する
WS_HSCROLL 水平方向のスクロールバーを持つ
WS_ICONIC 初期状態が最小化。WS_MAXIMIZEと同じ
WS_MAXIMIZE 初期状態で最大化
WS_MAXIMIZEBOX ウィンドウに最大化ボタンを表示。WS_EX_CONTEXTHELPと組み合わせることはできない。WS_SYSMENUも同時に指定する必要あり
WS_MINIMIZE 初期状態が最小化。WS_ICONICと同じ
WS_MINIMIZEBOX ウィンドウに最小化ボタンを表示。WS_EX_CONTEXTHELPと組み合わせることはできない。WS_SYSMENUも同時に指定する必要あり
WS_OVERLAPPED オーバーラップウィンドウ。タイトルバーとボーダーを持つ。WS_TILEDと同じ
WS_OVERLAPPEDWINDOW オーバーラップウィンドウ。WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOXと同じ。WS_TILEDWINDOWと同じ
WS_POPUP ポップアップウィンドウ。WS_CHILDと併用はできない
WS_POPUPWINDOW ポップアップウィンドウ。WS_POPUP | WS_BORDER | WS_SYSMENUと同じ。ウィンドウメニューを表示する場合はWS_CAPTIONとWS_POPUPWINDOWも指定する必要がある
WS_SIZEBOX ウィンドウにサイズ調整用のボーダーを表示。WS_THICKFRAMEと同じ
WS_SYSMENU タイトルバーにウィンドウメニューを表示。WS_CAPTIONも同時に指定する必要がある
WS_TABSTOP ユーザがタブキーを押したときにキーボードをフォーカスを受け取ることができるコントロール。タブキーが押されるとWS_TABSTOPを持つ次のコントロールにキーボードフォーカスを変更する。スタイルを変更するにはSetWindowLog()関数を使用する。ユーザが作成したウィンドウやモデルレスダイアログをタブストップで動作させるにはIsDialogMessage()関数を呼び出すようにメッセージループを変更する
WS_THICKFRAME ウィンドウにサイズ調整用のボーダーを表示。WS_SIZEBOXと同じ
WS_TILED オーバーラップウィンドウ。タイトルバーとボーダーが表示される。WS_OVERLAPPEDと同じ
WS_TILEDWINDOW オーバーラップウィンドウ。WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOXと同じ。WS_OVERLAPPEDWINDOWと同じ
WS_VISIBLE ウィンドウは表示されている。状態を変更するにはShowWindow()関数またはSetWindowPos()関数を使用する
WS_VSCROLL 縦方向のスクロールバーを持つ

この説明は次のページにまとまっている。

それでは実際に試してみよう。