03.ダイアログのサイズ変更

ダイアログのサイズを変更したとき、ダイアログに配置したコントロールの位置やサイズも連動して変わって欲しいです。でもMFCを使ったプログラムでは自前でその処理を実装しなければなりません。

リストコントロールを配置しただけでは、ダイアログのサイズを変更しても。。。

リストコントロールのサイズは変わりません。今回は、ダイアログのサイズ変更に合わせてリストコントロールにサイズも変える方法を書きます。
 
まず最初に、ダイアログのプロパティのBorderが「サイズ変更枠」になっていることを確認します。
この設定でないとダイアログの枠をマウスでつかんで、サイズを変更できません。

 
次にダイアログに配置したコントロールの位置を調整するAdjustLayout関数を定義します。

void CSlidePuzzleDlg::AdjustLayout()
{
    if(!m_LC.GetSafeHwnd()){
        return;
    }

    CRect rc;
    GetClientRect(&rc);

    m_LC.SetWindowPos(0, 0, 0, rc.Width(), rc.Height(), SWP_NOZORDER);
}

AdjustLayout関数は、m_LCのサイズをSetWindowPosで設定します。GetClientRect(&rc)で、ダイアログのサイズ(下図の青い枠の範囲)を取得し、m_LCをこのサイズに変更しているだけです。ただし、CSlidePuzzleDlgのOnInitDialog関数が呼び出されるまではm_LCが作成されていないので、m_LC.SetWindowPosは失敗します。このエラーを回避するためにm_LC.GetSafeHwnd()を調べて、条件を満たすまで何もしないで処理を抜けているのです。

 
ダイアログのサイズを変更するとWM_SIZEメッセージが届きます。このメッセージが届いたときにAdjustLayout関数を実行すればよいので、リソースエディタで、IDD_SLIDEPUZZLE_DIALOGダイアログのプロパティからOnSizeメッセージハンドラを追加して下さい。

 
あとは、AdjustLayout関数を追加するだけです。OnInitDialog関数(ダイアログを最初に表示したときのため)とOnSize関数(マウス等でダイアログのサイズを変更したときのため)にAdjustLayout関数を追加して下さい。

BOOL CSlidePuzzleDlg::OnInitDialog()
{
    CDialogEx::OnInitDialog();

    //...省略

    //レイアウトを調整します。
    AdjustLayout();

    return TRUE;
}

void CSlidePuzzleDlg::OnSize(UINT nType, int cx, int cy)
{
    CDialogEx::OnSize(nType, cx, cy);
    AdjustLayout();
}

 
それでは、実行して動作を確認してみましょう。ダイアログのサイズを変更するとリストコントロールのサイズも変わりましたね。