クライアント領域でウィンドウサイズを変更する

WinAPIでウィンドウをクライアント領域の矩形でウィンドウの位置とサイズを変更する方法についてのメモです。

ウィンドウの位置とサイズはSetWindowPos()関数で変更します。

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

しかし、この関数で指定する位置とサイズはウィンドウの外側のサイズです。
クライアントからウィンドウの外側へのサイズ変更はAdjustWindowRect()関数で行えます。

BOOL AdjustWindowRect(
  LPRECT lpRect,  // クライアント領域の座標が入った構造体へのポインタ
  DWORD dwStyle,  // ウィンドウスタイル
  BOOL bMenu      // メニューを持つかどうかの指定
);

この関数を実行し、lpRectで受け取ったRECT構造体の値をSetWindowPos()のcxとcyに指定すればOKです。
プログラムは以下のような感じになります。

void SetClientBound(int x, int y, int width, int height) {
    RECT clientRect, windowRect;
    GetClientRect(hWnd, &clientRect);
    GetWindowRect(hWnd, &windowRect);

    windowRect.left = x;
    windowRect.top = y;
    clientRect.right = width;
    clientRect.bottom = height;


    AdjustWindowRect(
        &clientRect,
        static_cast<dword>(GetWindowLongPtr(m_hWnd, GWL_STYLE)),
        FALSE
    );

    SetWindowPos(
        hWnd,
        0,
        windowRect.left + clientRect.left,
        windowRect.top + clientRect.top,
        clientRect.right - clientRect.left,
        clientRect.bottom - clientRect.top,
        0
    );
}

上記で自作したSetClientBound()関数を実行すると、クライアント領域の矩形指定でウィンドウの位置とサイズが変更されます。
処理自体はもっとスマートに出来そうですが、力尽きたのでこの辺にしておきます・・・

■参考文献
SetWindowPos
AdjustWindowRect