リストビューのサイズをダイアログのサイズ変更に合わせる

Visual C++プログラミングのメモ

【Visual C++ 2008】【MFC】

 ダイアログのサイズを変更した際、それに連動してリストビューのサイズを変更する方法。 CWnd::OnSizeをオーバーライドするとよい。

(1)
 リソースビューにて、ダイアログにList Controlを載せる。位置やサイズは適当でよい。 また、(今回のネタと直接関係無いが)[プロパティ]-[表示]-[View]をレポートにする(デフォルトはIcon)。 もしくは、rcファイルを直接書き換えるなら、該当するリストビューにLVS_REPORTを追加する。

(2)
 クラスヘッダのpublicに、リストビューのメンバ変数定義を追加。


    CListCtrl m_wndListCtrl;

 クラスヘッダのprotectedに、メンバ関数定義を追加。


    afx_msg void OnSize(UINT nType, int cx, int cy);

(3)
 DoDataExchangeのCDialog::DoDataExchange(pDX);より後にて、リストビューのコントロールIDとメンバ変数を結びつける。


    DDX_Control(pDX, IDC_LIST1, m_wndListCtrl);

(4)
 メッセージマップに、ON_WM_SIZE()を追加。

(5)
 OnInitDialogの「// TODO: 初期化をここに追加します。」より後にて、 ダイアログ初期表示時のリストビューのサイズを設定する。


    if (IsWindow(m_wndListCtrl.GetSafeHwnd()))
    {
        CRect rect;

        // ダイアログのサイズを取得
        GetClientRect(&rect);

        // ダイアログに合わせてリストビューのサイズ変更(初期)
        m_wndListCtrl.MoveWindow(0, 0, rect.Width(), rect.Height());
    }

(6)
 メンバ関数を記述。 ダイアログ右下をドラッグしてサイズ変更する度に、この関数が呼ばれる。


    void CXxxxDlg::OnSize(UINT nType, int cx, int cy)
    {
        CDialog::OnSize(nType, cx, cy);

        // OnSizeは、OnInitDialog前に一度呼ばれる。
        // その時点では、リストビューのウィンドウハンドルはNULLである。
        if (IsWindow(m_wndListCtrl.GetSafeHwnd()))
        {
            // ダイアログに合わせてリストビューのサイズ変更
            m_wndListCtrl.MoveWindow(0, 0, cx, cy);
        }

        return;
    }

(メモ)

  • 上記のサンプルソースでは、ダイアログ全体がリストビューになる。 他のコントロールを置く場合、(5)(6)にてMoveWindowの座標を調整する。
  • (関連項目) 【C++/MFC】リストビューの基本的な使い方
  • ダイアログにEdit Controlを載せて、CEditクラスを使用した場合、エディットコントロールでも同様の方法で可能
  • MSDNライブラリの「CListCtrl」「CWnd::OnSize」「CWnd::MoveWindow」「IsWindow」 「CWnd::GetSafeHwnd」「CRect」「CWnd::GetClientRect」を参照のこと