首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

VC++ MFC 按鈕啟動 OnTimer:SetTimer ID 不匹配導致定時器無法觸發的排查方法

     編輯:程式設計綜合問答

現象

按鈕處理器呼叫 SetTimer(2, 1000, NULL),OnTimer(UINT_PTR nIDEvent) 中用 case 2: 處理正常。改為 SetTimer(1, ...) + case 1: 後,OnTimer 不進入。

根本原因

定時器 ID 在進程內必須唯一。若同一視圖/對話框已有其他地方 (如 OnInitDialog、父類、其他控件) 呼叫 SetTimer(1, ...),後來的 SetTimer(1, ...) 會失敗並返回 0 (不會覆蓋舊定時器)。此時 OnTimer 收到的 nIDEvent 仍是舊定時器的 ID (可能是系統分配的其他值),導致 case 1: 永不匹配。

排查步驟

  1. 在 OnTimer 開頭加入追蹤:
    
        void CMyDlg::OnTimer(UINT_PTR nIDEvent) {
            TRACE(_T("OnTimer fired: nIDEvent = %d\n"), nIDEvent); // 輸出到 DebugView/Output 視窗
            // ...
        }
        
  2. 觀察實際觸發的 ID,若非預期值,說明 ID 衝突。
  3. 全域搜尋專案中所有 SetTimer 呼叫,確保 ID 不重複 (建議定義 enum { TIMER_AD_REFRESH = 100, TIMER_DATA_POLL = 101 };)。
  4. 若需動態分配 ID,使用 SetTimer(0, ...) 讓系統自動分配,並保存返回值:
    
        UINT_PTR timerId = SetTimer(0, 1000, NULL); // 返回實際 ID
        if (timerId) m_myTimerId = timerId;
        

最佳實踐

  • 定時器 ID 使用 類成員常量 或 枚舉,避免硬編碼數字。
  • 在 OnDestroy / OnCancel 中配對呼叫 KillTimer(id)。
  • 若多執行緒需定時,改用 CreateTimerQueueTimer (Win32) 或 std::thread + sleep_for。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved