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

Windows 桌面程序開發實戰:從零構建模擬時鐘(GDI 繪圖 + 定時器機制)

     編輯:關於C語言

Windows 桌面程序開發實戰:從零構建模擬時鐘(GDI 繪圖 + 定時器機制)

本文完整演示如何用純 Win32 API(C 語言)實現一個模擬指針時鐘 + 數字時鐘的桌面程序。涵蓋窗口創建、定時器驅動、GDI 繪圖(畫筆/畫刷/文本/幾何)、WM_PAINT 重繪機制、按鈕控制啟停——是 Windows 圖形編程的優秀入門項目。

核心架構:七步走模塊化設計

  1. 按鈕事件:啟動/停止定時器(SetTimer/KillTimer)
  2. 定時器回調:每秒觸發 WM_TIMER,調用顯示更新
  3. 顯示時鐘總入口:協調數字時鐘、表盤、三根指針繪製
  4. 數字時鐘:FillRect 擦除舊文本 → DrawText 繪製新時間
  5. 表盤繪製:Ellipse 畫圓 + 三角函數計算 12 個刻度座標 + DrawText 寫數字
  6. 指針繪製:根據時/分/秒計算角度,MoveToEx/LineTo 畫線,區分粗細顏色
  7. WM_PAINT:窗口恢復/遮擋時自動重繪,保證畫面不丟失

關鍵代碼片段解析

1. 窗口類註冊與創建

WNDCLASS wc = {0};
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.lpszClassName = TEXT("AnalogClock");
RegisterClass(&wc);

HWND hwnd = CreateWindow(wc.lpszClassName, TEXT("Analog Clock"),
    WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 560, 360,
    NULL, NULL, hInstance, NULL);

2. 定時器啟停(按鈕命令)

case WM_COMMAND:
    switch (LOWORD(wParam)) {
        case ID_START: SetTimer(hwnd, TIMER_ID, 1000, NULL); break;
        case ID_STOP:  KillTimer(hwnd, TIMER_ID); break;
    }
    return 0;

3. 表盤繪製:極坐標轉直角座標

void DrawClockFace(HDC hdc) {
    HPEN hPen = CreatePen(PS_SOLID, 1, RGB(0,0,255));
    SelectObject(hdc, hPen);
    Ellipse(hdc, 180, 20, 340, 180);  // 圓心 (260,100) 半徑 80

    // 12 個刻度
    for (int i=0; i<12; i++) {
        double angle = i * M_PI / 6;
        int x1 = 260 + 70 * sin(angle);
        int y1 = 100 - 70 * cos(angle);
        int x2 = 260 + 80 * sin(angle);
        int y2 = 100 - 80 * cos(angle);
        MoveToEx(hdc, x1, y1, NULL);
        LineTo(hdc, x2, y2);
    }
    // 繪製 1~12 數字(略)
    DeleteObject(hPen);
}

4. 指針角度計算(核心數學)

指針角度公式(弧度)長度顏色/粗細
時針(hour%12)*π/6 + (min*60+sec)*π/(1800*12)30px紅色 5px
分針min*π/30 + sec*π/180045px綠色 3px
秒針sec*π/3065px黑色 1px

5. WM_PAINT 重繪保護

case WM_PAINT:
    hdc = BeginPaint(hwnd, &ps);
    DrawClockFace(hdc);
    GetLocalTime(&st);
    DrawClockHands(hdc, st.wHour, st.wMinute, st.wSecond);
    EndPaint(hwnd, &ps);
    return 0;

運行效果展示

模擬時鐘截圖1

模擬時鐘截圖2

模擬時鐘截圖3

模擬時鐘截圖4

完整代碼結構(關鍵函數清單)

  • WinMain:註冊類、創建窗口、消息循環
  • WndProc:處理 WM_CREATE/WM_COMMAND/WM_TIMER/WM_PAINT/WM_DESTROY
  • DrawClockFace、DrawClockHands、ShowTime、ShowClock:繪圖模塊
  • my_listen:示例中未用到的佔位函數

學習要點總結

  1. GDI 對象管理:CreatePen/SelectObject/DeleteObject 三部曲,防止 GDI 洩漏。
  2. 定時器精度:SetTimer(hwnd, id, 1000, NULL) 約 1 秒,非實時系統足夠。
  3. 坐標系:屏幕坐標原點左上,Y 向下;三角函數需 y = centerY - r*cos(angle)。
  4. 重繪機制:所有繪圖邏輯集中在 WM_PAINT 與定時器調用的公共函數,保證一致性。

這個項目雖小,卻串聯了 Windows 圖形編程的核心知識點,是進階學習 Direct2D、WPF、WinUI 3 等現代框架前的寶貴基石。

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