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

MFC 多定時器處理:SetTimer nIDEvent 與 OnTimer switch-case 實戰

     編輯:程式設計綜合問答

在一個對話框中使用多個定時器:ID 識別與分發處理完整指南

MFC 允許同一窗口創建多個定時器,關鍵在於 SetTimer 的 nIDEvent 參數與 OnTimer 中的 switch-case 分發。

SetTimer 原型與參數詳解

UINT_PTR SetTimer(
    UINT_PTR nIDEvent,   // 定時器唯一標識,自定義非 0 值
    UINT uElapse,        // 間隔,毫秒
    TIMERPROC lpTimerFunc // 回調函數,NULL 表示使用 WM_TIMER 消息
);

創建多個定時器(如儀表雙指針)

// 在 OnInitDialog 或按鈕處理中啟動
void CMyDialog::StartTimers()
{
    // 定時器 1:秒針,每 1000ms
    SetTimer(1, 1000, NULL);  
    
    // 定時器 2:分鐘針,每 60000ms
    SetTimer(2, 60000, NULL);
    
    // 定時器 3:動畫幀,每 30ms
    SetTimer(3, 30, NULL);
}

OnTimer 中 switch 分發

void CMyDialog::OnTimer(UINT_PTR nIDEvent)
{
    switch (nIDEvent)
    {
        case 1:  // 秒針
            UpdateSecondHand();
            break;
            
        case 2:  // 分鐘針
            UpdateMinuteHand();
            break;
            
        case 3:  // 動畫
            AnimateGauge();
            break;
            
        default:
            CDialogEx::OnTimer(nIDEvent);  // 基類處理
    }
}

停止定時器

void CMyDialog::StopTimers()
{
    KillTimer(1);
    KillTimer(2);
    KillTimer(3);
}

// 或在 OnDestroy 統一清理
void CMyDialog::OnDestroy()
{
    KillTimer(1); KillTimer(2); KillTimer(3);
    CDialogEx::OnDestroy();
}

進階:動態分配 ID 避免衝突

若定時器數量動態,可用成員變量記錄:

class CMyDialog : public CDialogEx
{
    UINT_PTR m_timerIds[3];  // 存儲返回的真實 ID
    
    void StartDynamicTimer(int interval, std::function<void()> callback)
    {
        // 尋找空槽
        for (int i = 0; i < 3; ++i) {
            if (m_timerIds[i] == 0) {
                m_timerIds[i] = SetTimer(i + 100, interval, NULL); // 基礎 ID 100
                m_callbacks[i] = callback;
                break;
            }
        }
    }
    
    void OnTimer(UINT_PTR nIDEvent) override
    {
        for (int i = 0; i < 3; ++i) {
            if (m_timerIds[i] == nIDEvent && m_callbacks[i]) {
                m_callbacks[i]();
                return;
            }
        }
        CDialogEx::OnTimer(nIDEvent);
    }
    
    std::function<void()> m_callbacks[3];
};

常見錯誤

錯誤後果修正
多次調用 SetTimer(1,...) 未 KillTimer定時器疊加,回調頻率倍增啟動前先 KillTimer(1)
在 OnTimer 執行耗時操作阻塞 UI 線程,導致定時器積壓、界面卡頓耗時任務拋給工作線程
銷毀對話框前未 KillTimer定時器觸發時訪問已銷毀對象,崩潰OnDestroy 中統一清理

總結

nIDEvent 是多定時器的核心:創建時指定唯一 ID,OnTimer 中 switch(nIDEvent) 分發邏輯,銷毀時 KillTimer(ID) 清理。掌握此模式,即可輕鬆實現複雜的多時序 UI 控制。

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