Last Updated 2002/08/21
Programming Tips Visual C++ MFC ダイアログ プロパティシート  索 引 
OKボタンの無効
2002/08/21

CPropertySheet で OK ボタンを無効にするには,方法は2つある.
OK ボタン押下の時にエラーではじく方法とプロパティシートの内容により OK ボタンを無効にする方法である.


OK ボタン押下時にエラーではじくには OK ボタン押下のイベントをハンドルしなければならない.

OnCommand をオーバーライドして,(HIWORD(wParam) == BN_CLICKED) で (LOWORD(wParam) == IDOK) の時独自の処理をして,親クラスの OnCommand を呼ばない.

BOOL CTestSheet::OnCommand(WPARAM wParam, LPARAM lParam) 
{
    // TODO: この位置に固有の処理を追加するか、または基本クラスを呼び出してください
    if( HIWORD(wParam) == BN_CLICKED ) {
        if( LOWORD(wParam) == IDOK ) {
            AfxMessageBox(L"OK");
            return TRUE;
        } else if( LOWORD(wParam) == IDCANCEL ) { 
            AfxMessageBox(L"CANCEL");
            return TRUE;
        }
    }
    return CPropertySheet::OnCommand(wParam, lParam);
}

またタイトルバーの閉じるボタン(×)も考慮する.

OnSysCommand をオーバーライドして,(nID == SC_CLOSE) の時独自処理をして,親クラスの OnSysCommand を呼ばない.

    BEGIN_MESSAGE_MAP(MySheet, CPropertySheet)
    //{{AFX_MSG_MAP(MySheet)
    ON_WM_SYSCOMMAND()
    //}}AFX_MSG_MAP
    END_MESSAGE_MAP()

    void MySheet::OnSysCommand(UINT nID, LPARAM lParam)
    {
        if(nID != SC_CLOSE)
            CPropertySheet::OnSysCommand(nID, lParam);
    }

ちなみに OK ボタンは CPropertySheet であっても GetDlgItem(IDOK) でアクセス可能である.


2つ目の OK ボタンを無効にする方法は以下のとおり.
(参考文献「Inside Windows」の 98 年 5 月号)

CDialog の派生クラスの .h ファイルの次の部分に

    // 生成されたメッセージ マップ関数
    //{{AFX_MSG(CxxxDlg)
    afx_msg LRESULT OnKickIdle(WPARAM wParam, LPARAM lParam);

を追加する.
.cpp ファイルの次の部分に

    BEGIN_MESSAGE_MAP(CxxxDlg, CDialog)
        //{{AFX_MSG_MAP(CxxxDlg)
        ON_MESSAGE(WM_KICKIDLE, OnKickIdle)
        (以下略)
 
    LRESULT CxxxDlg::OnKickIdle(WPARAM wParam, LPARAM lParam)
    {
        UpdateDialogControls(this, FALSE);
 
        return FALSE;
    }

を追加する.
OK ボタンの使用可否をコントロールしようとするならば

    // 生成されたメッセージ マップ関数
    //{{AFX_MSG(CxxxDlg)
    (中略)
    afx_msg void OnUpdateOk(CCmdUI* pCmdUI);
    (以下略)
 
    BEGIN_MESSAGE_MAP(CxxxDlg, CDialog)
        //{{AFX_MSG_MAP(CxxxDlg)
        (中略)
        ON_UPDATE_COMMAND_UI(IDOK, OnUpdateOk)
        (以下略)
 
    void CxxxDlg::OnUpdateOk(CCmdUI* pCmdUI)
    {
        if (...) {
            pCmdUI->Enable(TRUE);
        }
        else {
            pCmdUI->Enable(FALSE);
        }
    }


ドキュメントクラスやビュークラスでは Class Wizard が作ってくれる OnUpdate...() と同様の書き方が可能である.
この方法は CPropertySheet の派生クラスでも有効である.


参照
前後のTips
OKボタンの無効

DSS ProgrammingTipsCGI Ver2.02