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

MFC 動態顯示系統時間:按鈕控制編輯框啟停與多線程實現

     編輯:C++ 入門

需求描述

在 MFC 對話框中,點擊按鈕切換編輯框是否動態顯示當前系統時間(格式:年-月-日 時:分:秒 星期)。再次點擊停止並清空編輯框。

核心設計

  1. 標誌變量:bool flag 指示時間顯示線程是否運行。
  2. 工作線程:使用 AfxBeginThread 創建線程,執行 time 靜態成員函數。
  3. 線程函數:循環 Sleep(1000),獲取 CTime::GetCurrentTime(),格式化後用 SetWindowTextW 更新編輯框。
  4. 按鈕處理:切換 flag,啟動或停止線程。

關鍵代碼片段

頭文件聲明

class CMyDlg : public CDialogEx {
public:
    bool flag;
    static UINT time(LPVOID param);
    // ...
};

構造函數初始化

CMyDlg::CMyDlg() : flag(false) {}

按鈕點擊處理

void CMyDlg::OnBnClickedButtonToggle() {
    if (flag) {
        flag = false;
        // 嘗試清空編輯框(原代碼中提到可能失效)
        CEdit* pEdt = (CEdit*)GetDlgItem(IDC_ShowTime);
        pEdt->SetWindowText(_T(""));
    } else {
        flag = true;
        AfxBeginThread(time, this);
    }
}

線程函數實現

UINT CMyDlg::time(LPVOID param) {
    CMyDlg* dlg = (CMyDlg*)param;
    CEdit* pEdt = (CEdit*)dlg->GetDlgItem(IDC_ShowTime);
    CString str;
    while (dlg->flag) {
        Sleep(1000);
        CTime t = CTime::GetCurrentTime();
        str = t.Format(_T("%Y-%m-%d %H:%M:%S %A"));
        pEdt->SetWindowTextW(str);
    }
    return 0;
}

常見問題與改進

  • 編輯框無法清空:原代碼註釋提到 SetWindowText(_T("")) 後又恢復。原因可能是線程仍在運行並覆蓋了內容。解決:在設置 flag=false 後,稍作延遲或使用同步機制確保線程已退出再清空。
  • UI 線程安全:工作線程直接操作 UI 控件在 MFC 中通常可行,但更規範的做法是發送用戶定義消息(PostMessage)由主線程更新 UI。
  • 資源洩漏:對話框銷毀時需確保線程已結束,可在 OnDestroy 中設置 flag=false 並等待。

改進版線程函數(發送消息)

// 自定義消息
#define WM_UPDATE_TIME (WM_USER + 1)

UINT CMyDlg::time(LPVOID param) {
    CMyDlg* dlg = (CMyDlg*)param;
    CTime t = CTime::GetCurrentTime();
    CString str = t.Format(_T("%Y-%m-%d %H:%M:%S %A"));
    while (dlg->flag) {
        Sleep(1000);
        t = CTime::GetCurrentTime();
        str = t.Format(_T("%Y-%m-%d %H:%M:%S %A"));
        dlg->PostMessage(WM_UPDATE_TIME, 0, (LPARAM)(new CString(str)));
    }
    return 0;
}

// 主線程消息處理
LRESULT CMyDlg::OnUpdateTime(WPARAM, LPARAM lParam) {
    CString* pStr = (CString*)lParam;
    SetDlgItemText(IDC_ShowTime, *pStr);
    delete pStr;
    return 0;
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved