Seaside Laboratory

Post

RegisterClass と CreateWindow の Ex 版

ウィンドウを作るときには RegisterClass と CreateWindow をセットで使っていたので、RegisterClassEx を使ったら CreateWindowEx を使わなければいけないと思っていたが、まったく関係なかった。なので、RegisterClassEx で登録した後に CreateWindow という組み合わせも可能。

通常版と Ex 版で何が違うか調査してみた。

RegisterClassEx

引数として渡す WNDCLASSEX 構造体に違いがある。

typedef struct tagWNDCLASSEX
{
    UINT      cbSize;        // 追加
    UINT      style;
    WNDPROC   lpfnWndProc;
    int       cbClsExtra;
    int       cbWndExtra;
    HINSTANCE hInstance;
    HICON     hIcon;
    HCURSOR   hCursor;
    HBRUSH    hbrBackground;
    LPCTSTR   lpszMenuName;
    LPCTSTR   lpszClassName;
    HICON     hIconSm;       // 追加
} WNDCLASSEX, *PWNDCLASSEX;

先頭のメンバは構造体のサイズで、末尾にあるのが小さいアイコン。

CreateWindoeEx

HWND CreateWindowEx
(
    DWORD dwExStyle,      // 追加
    LPCTSTR lpClassName,
    LPCTSTR lpWindowName,
    DWORD dwStyle, 
    int x,
    int y,
    int nWidth,
    int nHeight,
    HWND hWndParent,
    HMENU hMenu,
    HINSTANCE hInstance,
    LPVOID lpParam
);

先頭にある dwExStyle で拡張ウィンドウスタイルが指定できるようになっている。

CreateWindowEx と SetWindowLong の違い

拡張ウィンドウスタイルの WS_EX_TOPMOST (ウィンドウ最前面) だけは、CreateWindowEx の引数で指定するのと、後から SetWindowLong で変更するのとで挙動が異なる。この違いに気づくまで時間を要してしまったが、MSDN を調べてみたら解説に書かれていた。

ウィンドウデータの中には、キャッシュされており、SetWindowLong 関数を使って変更しても
SetWindowPos 関数を呼び出すまでは有効にならないものもあります。
特に、フレームスタイルを変更した場合は、SWP_FRAMECHANGED フラグをセットして
SetWindowPos 関数を呼び出すさなければ、キャッシュが正しく更新されません。

BOOL SetWindowPos
(
    HWND hWnd,            // ウィンドウのハンドル
    HWND hWndInsertAfter, // 配置順序のハンドル
    int X,                // 横方向の位置
    int Y,                // 縦方向の位置
    int cx,               // 幅
    int cy,               // 高さ
    UINT uFlags           // ウィンドウ位置のオプション
);

何故か SetWindowPos を実行しても反映されなかったので、SetWindowPos の第 2 引数 hWndInsertAfter に HWND_TOPMOST を指定て最前面表示を行うことにした。