< VSS エクスプローラの起動時にデータベースを指定する | システムメニューを持たない CDialog で、タイトルバーをダブルクリックされたら最大化 <-> 元のサイズに戻す >

July 2, 2005

CDialog より派生したダイアログにステータスバーをつける

MFC ネタ。 CDialog より派生したダイアログウインドウに、ステータスバーをつけなきゃならなくなりました。とりあえずは AppWizard で SDI アプリケーションを作ってみて、それを参考にダイアログクラスに CStatusBar 型のメンバ変数を追加し、OnInitDialog に初期化コードを書いてみました。

#if !defined(AFX_STATUSDIALOG_H__815300F5_01CC_433D_9286_4C8CEEC28D27__INCLUDED_)
#define AFX_STATUSDIALOG_H__815300F5_01CC_433D_9286_4C8CEEC28D27__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// StatusDialog.h : ヘッダー ファイル
//

/////////////////////////////////////////////////////////////////////////////
// CStatusDialog ダイアログ

class CStatusDialog : public CDialog
{
// コンストラクション
public:
    CStatusDialog(CWnd* pParent = NULL);   // 標準のコンストラクタ

// ダイアログ データ
    //{{AFX_DATA(CStatusDialog)
    enum { IDD = IDD_STATUSDIALOG };
        // メモ: ClassWizard はこの位置にデータ メンバを追加します。
    //}}AFX_DATA


// オーバーライド
    // ClassWizard は仮想関数のオーバーライドを生成します。
    //{{AFX_VIRTUAL(CStatusDialog)
    protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV サポート
    //}}AFX_VIRTUAL

// インプリメンテーション
protected:

    // 生成されたメッセージ マップ関数
    //{{AFX_MSG(CStatusDialog)
    virtual BOOL OnInitDialog();
    afx_msg void OnSize(UINT nType, int cx, int cy);
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()

    CStatusBar m_StatusBar;
};

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ は前行の直前に追加の宣言を挿入します。

#endif // !defined(AFX_STATUSDIALOG_H__815300F5_01CC_433D_9286_4C8CEEC28D27__INCLUDED_)
// CStatusDialog.cpp の OnInitDialog
/////////////////////////////////////////////////////////////////////////////
// CStatusDialog メッセージ ハンドラ

BOOL CStatusDialog::OnInitDialog() 
{
    CDialog::OnInitDialog();
    
    // TODO: この位置に初期化の補足処理を追加してください

    if (!m_StatusBar.Create (this))
    {
        MessageBox (_T ("CStatusBar::Create failed"));
    }
    
    return TRUE;  // コントロールにフォーカスを設定しないとき、戻り値は TRUE となります
                  // 例外: OCX プロパティ ページの戻り値は FALSE となります
}

実行してみましたが・・あれ?効いてませんね・・

スクリーンショット (失敗編)

ながーいことググってわかったことは、どうやらダイアログの場合は、サイズに合わせてステータスバーが再配置されないのが原因らしいです。OnInitDialog と、WM_SIZE のハンドラ (OnSize)の最後で、以下の一行を呼んでやればいい感じに表示されるようになりました。

RepositionBars (AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0);

200507スクリーンショット (成功編)

ソースはこんな感じに。

/////////////////////////////////////////////////////////////////////////////
// CStatusDialog メッセージ ハンドラ

BOOL CStatusDialog::OnInitDialog() 
{
    CDialog::OnInitDialog();
    
    // TODO: この位置に初期化の補足処理を追加してください

    if (!m_StatusBar.Create (this))
    {
        MessageBox (_T ("CStatusBar::Create failed"));
    }
    
    RepositionBars (AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0);

    return TRUE;  // コントロールにフォーカスを設定しないとき、戻り値は TRUE となります
                  // 例外: OCX プロパティ ページの戻り値は FALSE となります
}

void CStatusDialog::OnSize(UINT nType, int cx, int cy) 
{
    CDialog::OnSize(nType, cx, cy);
    
    // TODO: この位置にメッセージ ハンドラ用のコードを追加してください

    RepositionBars (AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0);

}

ただし、そのままではダイアログのサイズがダイアログリソースのサイズとなり、リソースの下の部分とステータスバーが重なってしまいます。MSDN ライブラリには、ちゃあんと再計算してダイアログのサイズを再設定するサンプルコードがありましたが、要するにダイアログリソースとステータスバーが重なっても困らなければいいわけで、私はダイアログリソースを、ステータスバーの高さくらい(目分量 笑)下に伸ばしてしまいました。

トラックバック

このエントリーにトラックバック:
http://frog.raindrop.jp/cgi-bin/mt/mt-tb.cgi/981

コメント

コメントする

※ コメントスパム対策のため、コメント本文はおはよう、こんにちわ、こんばんわのいずれかより始めるようにしてください。

name:
email:

※ 必要ですが、表示しません。

url:
情報を保存する ?