1. 程式人生 > 實用技巧 >MFC表單驗證的簡單解決方案

MFC表單驗證的簡單解決方案

介紹 許多程式設計師的任務之一是處理無效資料輸入的運算子。MFC形式(如對話方塊、表格檢視),是否儘快執行驗證控制元件失去焦點或驗證整個表單當用戶單擊OK按鈕以及如何顯示錯誤(s)阻止使用者單擊OK按鈕繼續爭論的主題。 2001年我曾在一個數據庫應用程式,有一個極其複雜的輸入驗證。首先,我想用更有可能做驗證的驗證編輯控制元件的WM_KILLFOCUS (OnKillFocus)事件,但是它沒有讓你離開編輯框,直到你答對了。很不方便,你有欄位的驗證取決於其他欄位,可以修改。更糟的是,我遇到最惱人的問題很多使用者要求:他們想要儘可能快地輸入資料,有時使用鍵盤輸入數字和按Enter鍵集中下一個欄位,如果他們犯錯誤,彈出一個訊息框告訴關於錯誤的資訊,他們可以解決這個問題,而無需先去掉一個錯誤訊息框。 它可以解決所有的問題在不改變形式的標準行為?答案是肯定的。嘗試各種方法之後,我想出了一個完整的解決方案,會讓我容易做到形式的驗證。 現在我剝奪了這些類從一個執行的程式;我不得不做一些微小的變化,它將依賴於我的應用程式以及我希望它能幫助很多人。 特性 以下是一些特點: 資料將被驗證當你點選/按下OK按鈕,任何錯誤將阻止表單關閉。重點將被設定為第一個錯誤的領域。 單擊OK按鈕時如果有任何錯誤或者當前的重點領域是第一個錯誤的欄位,當按下OK按鈕,錯誤訊息將顯示在一個小視窗(類似於工具提示)錯誤的欄位上方一定圈的時間(預設5 s)。 如果你按任意鍵或單擊滑鼠按鈕,錯誤訊息會阻止使用者單擊OK按鈕消失,仍然把這個“道”傳好 如果你想要顯示的錯誤訊息很長一段時間,只是移動滑鼠游標。 你可以隨時離開形式使用取消按鈕或ESC鍵,即使當前欄位的錯誤,就像一個對話方塊的正常行為。 使用的程式碼 使用類是非常簡單和舒適。讓我們以一個對話方塊為例,從CDialogExt派生類,覆蓋OnValidate函式。就是這樣。 TestDialog.h:頭fileHide,複製Code

#include "DialogExt.h"
class CTestDialog : public CDialogExt
{
// Construction
public:
......
// Overrides
    virtual void OnValidate (UINT &nCtrlID, CString &strError);
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CTestDialog)
protected:
    virtual void DoDataExchange(CDataExchange* pDX); 
//}}AFX_VIRTUAL
......
}

TestDialog.cpp:實現fileHide,複製Code

void CTestDialog::OnValidate(UINT &nCtrlID, CString &strError)
{
    UpdateData();
    CString strEdit;
    GetDlgItemText(IDC_SINGLELINE_EDIT, strEdit);
    if (strEdit.IsEmpty()){
        strError = "Single-line edit cannot be empty string.";
        nCtrlID = IDC_SINGLELINE_EDIT;
        return;
    }
}

技術細節 CMessageTip CMessagTip來源於CWnd。使用工具簡單地呼叫建立(…)並指定父視窗。當顯示(…)成員函式叫做我安裝鉤和使用SetWindowPos顯示訊息框(…),然後啟動一個計時器在0.5秒的時間間隔。任何時候我鉤鉤proc事件,我直接釋出WM_CLOSE訊息。在OnClose()處理程式,我就叫隱藏()成員函式殺死計時器,解僱和刪除的訊息框鉤。計時器proc,我一直遞減計數間隔和定期檢查滑鼠是否仍在視窗範圍內或切換到其他應用程式。當計數為0或切換到其他應用程式隱藏()成員函式。 CDialogExt CDialogExt來源於CDialog。我宣佈一個CMessagTip成員變數m_tip並覆蓋WM_COMMAND訊息處理程式OnCmdMsg(…)。等於在OnCmdMsg(…),當國家免疫日IDOK(點選/按下OK按鈕)我叫虛擬函式OnValidate(…)得到錯誤的控制元件ID和錯誤訊息文字中指定覆蓋OnValidate(…)功能。 值得一提的是當顯示錯誤訊息。 1001年是相關聯的編輯控制元件的ID值組合框。組合框的ID值,假設國家免疫日“下拉”風格設定。如果combobox控制元件專注,您可以使用GetDlgItem)(國家免疫日→GetDlgItem(1001)獲得焦點的視窗。 對於多行編輯控制元件,回車鍵可以傳送,但只有在編輯控制元件是一個多行編輯控制元件,如果“返回”風格設定。如果你在多行編輯控制元件按回車鍵,你可以在PreTranslateMessage視窗處理程式:隱藏,複製Codeif (pMsg→資訊= = WM_KEYDOWN,, pMsg→按鈕= = VK_RETURN) { CWnd * pWnd = FromHandle (pMsg→hwnd); 如果(pWnd ! = GetDlgItem (IDOK)) m_pWndFrom = pWnd; } 為了模仿的行為按回車鍵集中第二場,我只有在當前游標顯示錯誤訊息仍在第一個錯誤的欄位,當按下OK按鈕。 CFormViewExt CFormViewExt來源於CFormView。這是如果CDialogExt聚酯薄膜。我添加了兩個虛擬函式OnOK()和OnCancel()。您可以覆蓋它們並新增額外的程式碼,就像dialog一樣。 CPropertyPageExt CPropertyPageExt派生自CPropertyPage。我聲明瞭一個CMessagTip成員變數m_tip並提供了一個虛擬函式OnValidate()。ShowMessage(…)和HideMessage()將在CPropertySheetExt類中被呼叫。 CPropertySheetExt CPropertySheetExt派生自CPropertySheet。我重寫WM_COMMAND訊息處理程式OnCmdMsg(…)在這裡。在OnCmdMsg(…)中,我計算頁面的數量並像CDialogExt一樣處理所有的頁面。我注意到,Enter鍵不能從多行編輯控制元件傳送。所以在顯示錯誤訊息時與CDialogExt有一點不同。 總結 本文所介紹的技術在我們的應用中已經廣泛應用了近3年。我還沒有在其他地方或類似的任何產品中見過這種想法,所以我希望這種技術對後者有很大的貢獻。 本文轉載於:http://www.diyabc.com/frontweb/news4991.html