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

VC 擴充 Edit 控件實現日期輸入格式限制

     編輯:關於VC++

子類化實現自訂輸入格式

預設 Edit 控件無法限制「YYYY-MM-DD」格式。解決方案:衍生 CMyEdit 類別,透過子類化攔截 WM_CHAR、WM_KEYDOWN 訊息,過濾輸入字元並自動維護分隔符號。

核心邏輯

  1. 初始化:SetLimitText(10)、SetWindowText(_T(" - - ")) 顯示範本。
  2. 字元訊息處理(OnChar):
    • 數字鍵:僅允許在年/月/日位置輸入,自動跳過分隔符。
    • Backspace:刪除數字時自動補入空格,維持格式;刪到分隔符則跳過。
  3. 按鍵訊息處理(OnKeyDown):
  4. Delete:刪除數字後自動補空格;刪除分隔符則忽略。

關鍵程式碼片段

void CMyEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) {
    int pos = LOWORD(GetSel());
    CString str; GetWindowText(str);
    if (nChar >= '0' && nChar <= '9') {
        if (pos < 4 || (pos > 4 && pos < 7) || pos > 7) {
            str.Delete(pos, 1); SetWindowText(str);
            SetSel(FormatPos(pos, pos));
            CEdit::OnChar(nChar, nRepCnt, nFlags);
            if (LOWORD(GetSel()) == 4 || LOWORD(GetSel()) == 7)
                SetSel(FormatPos(pos+1, pos+1)); // 跳過分隔符
        } else if (pos == 4 || pos == 7) { // 在分隔符位置
            SetSel(FormatPos(pos+1, pos+1));
            str.Delete(pos, 1); SetWindowText(str);
            SetSel(FormatPos(pos, pos));
            CEdit::OnChar(nChar, nRepCnt, nFlags);
        }
    } else if (nChar == VK_BACK) { /* 類似邏輯 */ }
}

int CMyEdit::FormatPos(int start, int end) { return MAKELONG(start, end); }

動態子類化與反子類化

  • SubclassDlgItem(IDC_EDIT, this):對話框初始化時動態子類化。
  • SubclassWindow(hWnd) / UnsubclassWindow():運行時切換。
  • 注意:若已用 DDX_Control 靜態關聯,不可重複子類化;反子類化後原物件無法再操作控件。

執行畫面

日期輸入控件

應用延伸

同樣原理可實現 IP 位址、電話號碼、貨幣金額等固定格式輸入控件,核心在於 FormatPos 輔助函式管理游標位置與範本字元的對應關係。

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