Last Updated 2004/06/30
Programming Tips Visual C++ MFC MDI  索 引 
MDI 子ウィンドウの閉じるボタン無効
2004/06/30

MDI 子ウィンドウの閉じるボタンを無効にする.
通常だと以下の方法が思いつく.

class CMdiFrame : public CMDIChildWnd
{
    void DisableCloseButton();
    void EnableCloseButton();
};

void CMdiFrame::DisableCloseButton()
{
    CMenu*  pSysMenu = GetSystemMenu(FALSE);
    pSysMenu->EnableMenuItem(SC_CLOSE, MF_BYCOMMAND | MF_GRAYED);
    TRACE( "SC_CLOSE -> MF_GRAYED (MDI子)\n" );
}

void CMdiFrame::EnableCloseButton()
{
    CMenu*  pSysMenu = GetSystemMenu(FALSE);
    pSysMenu->EnableMenuItem(SC_CLOSE, MF_BYCOMMAND | MF_ENABLED);
    TRACE( "SC_CLOSE -> MF_ENABLED (MDI子)\n" );
}

だが,これでは子ウィンドウが最大化した場合に閉じるボタンが無効にならない.

そこで子ウィンドウが最大化した時にもちゃんと無効にするは以下を付け加える.

void CMdiFrame::DisableCloseButton()
{
    CMenu*  pSysMenu = GetSystemMenu(FALSE);
    pSysMenu->EnableMenuItem(SC_CLOSE, MF_BYCOMMAND | MF_GRAYED);
    TRACE( "SC_CLOSE -> MF_GRAYED (MDI子)\n" );

    // ここからが、Xボタン概観更新部分
    if( IsZoomed() ) {
        GetMDIFrame()->SetRedraw(FALSE);
        MDIRestore();
        MDIMaximize();
        GetMDIFrame()->SetRedraw(TRUE);
        GetMDIFrame()->DrawMenuBar();
    }
}

void CMdiFrame::OnClose()
{
    CMenu* pSysMenu = GetSystemMenu(FALSE);
    UINT   sts = pSysMenu->GetMenuState(SC_CLOSE, MF_BYCOMMAND);

    // 終了していけなければ、何もしない
    if( LOBYTE(sts) != MF_ENABLED ) {
        return;
    }
    CMDIChildWnd::OnClose();
}

閉じるボタンが無効化されるのは外見(見た目)だけなので,実際にボタンを押下してしまうと終了してしまう.
そこで,WM_CLOSE なりに閉じない仕組みを入れることになる.


参照
MDI 子ウィンドウの最大化ボタン無効
コントロールボタン無効
前後のTips
MDI 子ウィンドウの閉じるボタン無効

DSS ProgrammingTipsCGI Ver2.01