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

VC++ 實作電子式數位時鐘:位圖數碼管 + 定時器驅動

     編輯:VC 教學

前言

延續七段顯示器主題,本文採用預渲染位圖數碼圖示而非向量繪圖,實作桌面電子時鐘。優點:繪製極快、支援任意字體風格(LCD、LED、點陣)、易於美工替換素材。核心類別 `CTimeDisplay` 管理 `CImageList` 載入數碼位圖(含 0-9、冒號、空白),動態建立 `CStatic` 陣列顯示各位,定時器每秒更新時間字串並逐位設定圖示。

一、資源準備

  1. 建立位圖資源 `IDB_DIGITS`:寬度 = 10 位數碼寬度總和(如 12px × 10 = 120px),高度固定(如 20px),包含 0-9、冒號、空白共 12 個影格,橫向排列。
  2. 屬性設定:類型 = Bitmap,色彩 = 256 色或真彩色,背景色設為透明色(如 RGB(255,255,255))。

二、CTimeDisplay 類別設計


class CTimeDisplay
{
public:
    CTimeDisplay();
    ~CTimeDisplay();

    // 初始化:父對話框、顯示位數、起始座標、間距
    void Initialize(CDialog* pParent, int nDigits, int x, int y, int nSpace);

    // 更新顯示:傳入 "HH:MM:SS" 格式字串
    void UpdateTime(const CString& strTime);

private:
    CDialog* m_pParent;
    CImageList m_imgList;           // 數碼位圖清單
    CArray m_pStatics;    // 每位一個靜態圖示控制項
    int m_nDigits;
    int m_x, m_y, m_nSpace;
};

三、核心實作


void CTimeDisplay::Initialize(CDialog* pParent, int nDigits, int x, int y, int nSpace)
{
    m_pParent = pParent;
    m_nDigits = nDigits;
    m_x = x; m_y = y; m_nSpace = nSpace;

    // 載入位圖:每格 12px 寬,透明色白色
    m_imgList.Create(IDB_DIGITS, 12, 1, RGB(255,255,255));

    // 清除舊控制項
    for (auto p : m_pStatics) { delete p; }
    m_pStatics.RemoveAll();

    // 建立每位的 CStatic 圖示控制項
    for (int i = 0; i < nDigits; ++i)
    {
        CStatic* pStatic = new CStatic();
        CRect rc(m_x + i*(12 + nSpace), m_y, m_x + i*(12 + nSpace) + 12, m_y + 20);
        pStatic->Create(NULL, SS_ICON | WS_CHILD | WS_VISIBLE, rc, m_pParent, 1000 + i);
        m_pStatics.Add(pStatic);
    }
}

void CTimeDisplay::UpdateTime(const CString& strTime)
{
    int len = strTime.GetLength();
    // 前導空白填充
    for (int i = 0; i < m_nDigits - len; ++i)
    {
        HICON hIcon = m_imgList.ExtractIcon(10); // 索引 10 = 空白
        m_pStatics[i]->SetIcon(hIcon);
    }
    // 實際字元
    for (int i = 0; i < len; ++i)
    {
        TCHAR ch = strTime[i];
        int idx = 11; // 預設冒號索引
        if (ch >= _T('0') && ch <= _T('9')) idx = ch - _T('0');
        else if (ch == _T(':')) idx = 11;
        HICON hIcon = m_imgList.ExtractIcon(idx);
        m_pStatics[m_nDigits - len + i]->SetIcon(hIcon);
    }
}

四、對話方塊整合


class CClockDlg : public CDialog
{
    CTimeDisplay m_timeDisplay;
    // ...
    afx_msg void OnTimer(UINT nIDEvent);
};

BOOL CClockDlg::OnInitDialog()
{
    CDialog::OnInitDialog();
    // 8 位數:HH:MM:SS,起始 (20,20),間距 2px
    m_timeDisplay.Initialize(this, 8, 20, 20, 2);
    SetTimer(1, 1000, NULL); // 1 秒更新
    return TRUE;
}

void CClockDlg::OnTimer(UINT nIDEvent)
{
    if (nIDEvent == 1)
    {
        CTime now = CTime::GetCurrentTime();
        CString str = now.Format(_T("%H:%M:%S"));
        m_timeDisplay.UpdateTime(str);
    }
    CDialog::OnTimer(nIDEvent);
}

void CClockDlg::OnDestroy()
{
    KillTimer(1);
    CDialog::OnDestroy();
}

五、擴充:顏色切換

準備多組不同顏色的位圖資源(`IDB_DIGITS_RED`、`IDB_DIGITS_GREEN`、`IDB_DIGITS_BLUE`),在 `CTimeDisplay` 加入 `SetColorScheme(UINT nBitmapID)` 重新 `Create` ImageList 並刷新所有圖示。搭配 `CColorDialog` 讓使用者自訂顏色。

六、執行效果

電子式數位時鐘示範

位圖數碼管風格清晰,每秒精確更新,CPU 佔用極低(僅圖示指標切換),支援視窗移動、最小化還原後自動重繪(靜態控制項自動處理)。

七、結語

位圖數碼管方案以空間換時間:預先渲染所有字型狀態,執行期僅做 `SetIcon` 指標交換,極適合高頻率更新(時鐘、計數器、股票行情)。`CTimeDisplay` 封裝完整,可直接嵌入任何對話方塊、工具列、狀態列。若需向量縮放支援,可改用 GDI+ `DrawImage` 縮放單一高解析度位圖,但頻率更新時需注意效能。

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