首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

《VC++ 技術內幕》學習筆記(十):模態對話框進階——攔截 Enter/ESC 鍵防止意外關閉

     編輯:VC 教學

問題背景

模態對話框中,當焦點不在按鈕上時(如編輯框),按 Enter 或 ESC 會觸發預設 OnOK / OnCancel 導致對話框關閉。若需自行驗證或阻止關閉,必須覆寫這兩個虛函數。

解決方案:覆寫 OnOK 與 OnCancel

1. 標頭檔宣告

class CGuessDlg : public CDialog
{
    // ...
protected:
    virtual void OnOK();    // 覆寫 Enter 鍵行為
    virtual void OnCancel(); // 覆寫 ESC 鍵行為
    // ...
};

2. 實作檔

void CGuessDlg::OnOK()
{
    // 範例:驗證輸入後才允許關閉
    UpdateData(TRUE);  // 從控制項取得資料
    if (m_strInput.IsEmpty())
    {
        AfxMessageBox(_T("請輸入內容!"));
        return;  // 不呼叫 CDialog::OnOK(),對話框不關閉
    }
    // 驗證通過,呼叫基類關閉並回傳 IDOK
    CDialog::OnOK();
}

void CGuessDlg::OnCancel()
{
    // 範例:確認後才取消
    if (AfxMessageBox(_T("確定要放棄輸入嗎?"), MB_YESNO | MB_ICONQUESTION) == IDYES)
    {
        CDialog::OnCancel();  // 呼叫基類關閉並回傳 IDCANCEL
    }
    // 否則不處理,對話框保持開啟
}

原理說明

  • MFC 在 CDialog::PreTranslateMessage 中處理 Enter/ESC,分別呼叫 OnOK/OnCancel。
  • 預設 OnOK 執行 UpdateData(TRUE) 並 EndDialog(IDOK);OnCancel 直接 EndDialog(IDCANCEL)。
  • 覆寫時不呼叫基類即可阻止關閉;需關閉時明確呼叫基類。

進階技巧:設定預設按鈕與取消按鈕

  • 資源編輯器中,按鈕屬性 Default Button = True → 該按鈕成為 Enter 觸發目標(對應 IDOK)。
  • 按鈕 ID 設為 IDCANCEL → 自動成為 ESC 觸發目標。
  • 若對話框無 IDOK/IDCANCEL 按鈕,系統仍會呼叫 OnOK/OnCancel,故覆寫更為可靠。

配合體育彩票選號器範例

上一篇筆記的「體育彩票選號器」對話框僅有「選號」按鈕(非 IDOK),若使用者在編輯框按 Enter 會意外關閉。套用上述覆寫即可解決:

void CGuessDlg::OnOK()
{
    // 只有點擊「選號」按鈕才產生號碼,Enter 鍵不處理
    // 直接 return 防止關閉
    return;
}

void CGuessDlg::OnCancel()
{
    // ESC 鍵彈出確認對話框
    if (AfxMessageBox(_T("確定離開選號器?"), MB_YESNO) == IDYES)
        CDialog::OnCancel();
}

總結

  • 覆寫 OnOK/OnCancel 是控制模態對話框關閉行為的標準做法。
  • 務必在標頭檔加 virtual 宣告,實作檔中視邏輯決定是否呼叫基類。
  • 搭配 UpdateData、驗證邏輯、確認對話框,構建健壯的使用者互動流程。

掌握此技巧,即可避免使用者誤觸鍵盤導致資料遺失或流程中斷,提升應用程式專業度。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved