< CDialog より派生したダイアログにステータスバーをつける | Windows AP にコンソール出力を提供するクラス >

July 3, 2005

システムメニューを持たない CDialog で、タイトルバーをダブルクリックされたら最大化 <-> 元のサイズに戻す

MFC CDialog ネタをもいっちょ。前回サンプル作ったので、その続きに実装しちゃいます。

今回のお題は、システムメニューを持たないダイアログに、「タイトルバーをダブルクリックされたら最大化 <-> 元のサイズに戻す」の機能を実装せよと言うもの。当然、最大化、最小化ボタンもありません。

ところで、VB6 でサイズ変更可能な Form を作成して、ControlBox プロパティに False を設定すると、システムメニューも最大化・最小化ボタンないウインドウができますが、ちゃあんとタイトルバーダブルクリックが効くんですよね。Spy++ でメッセージをキャプチャすると、WM_NCLBUTTONDBLCLK nHitTest = HTCAPTION が落ちてきているのが見えます。そこで、AP 内でもそれを判断させてみることにしてみました。

StatusDialog.cpp 内のメッセージマップ部分に1行追加します。

BEGIN_MESSAGE_MAP(CStatusDialog, CDialog)
    //{{AFX_MSG_MAP(CStatusDialog)
    ON_WM_SIZE()
    ON_WM_NCLBUTTONDBLCLK()
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

CStatusDialog クラスに OnNcLButtonDblClk を追加します。

// StatusDialog.h: CStatusDialog クラスの宣言の中。
// どこでもいいんだけど、他のメッセージハンドラと同じ位置に追加しておくと、後で見やすいかも。

protected:

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

// StatusDialog.cpp

void CStatusDialog::OnNcLButtonDblClk (UINT nHitTest, CPoint point)
{
    if (HTCAPTION == nHitTest)
    {// ダブルクリックされたのはタイトルバー
        if (IsZoomed ())
        {// 最大化中
            SendMessage (WM_SYSCOMMAND, SC_RESTORE, 0);
        }
        else
        {// 最大化されてない
            SendMessage (WM_SYSCOMMAND, SC_MAXIMIZE, 0);
        }
        return;
    }

    CDialog::OnNcLButtonDblClk (nHitTest, point);
}

実行してみると、なかなか期待したとおりの動き。でもよく見ると、なぜか最大化した時にタスクバーと重なってしまいます。前回ステータスバーを付けてなかったら気付かないかもですが、とにかく、タスクバーのサイズを無視して、デスクトップいっぱいいっぱいまで最大化してしまっているようです。

もう一度、VB で作成したダイアログにもどって、今度は Spy++ でウインドウスタイルを確認します。

WS_CAPTION | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_THICKFRAME | WS_OVERLAPPED | WS_MINIMIZEBOX | WS_MAXIMIZEBOX 、MFC のダイアログと比較・・・特に一番後ろのが気になります。じゃあ、と言うわけで、ウインドウスタイルを変更すると、うまくいきました。ちゃんとタスクバーの上部にステータスバーが出てます。

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

    DWORD dwStyle = GetWindowLong (*this, GWL_STYLE);
    dwStyle |= WS_MAXIMIZEBOX;
    SetWindowLong (*this, GWL_STYLE, dwStyle);
    
    // 前回のステータスバーの実装部分・・・
    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 となります
}

トラックバック

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

コメント

コメントする

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

name:
email:

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

url:
情報を保存する ?