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

C++ Builder 實作定時關機工具:從介面設計到系統 API 呼叫

     編輯:關於C++

專案概覽

本專案示範如何使用 C++ Builder (VCL 框架) 開發一款實用的定時關機工具。核心功能包含:即時顯示系統時間、日期時間選擇器設定關機時刻、倒數計時顯示、關機條件驗證、以及呼叫 Windows API 執行系統關機。適用於下載任務、排程備份、節能管理等場景。

介面元件佈局與屬性設定

元件類型名稱關鍵屬性用途
GroupBox1TGroupBoxgrpCurrentTimeCaption="目前系統時間"分組容器
DateTimePicker1TDateTimePickerdtpCurrDateKind=dtkDate, Mode=dmUpDown, Enabled=False顯示目前日期
DateTimePicker2TDateTimePickerdtpCurrTimeKind=dtkTime, Mode=dmUpDown, Enabled=False, Format="HH:mm:ss"顯示目前時間
GroupBox2TGroupBoxgrpShutdownTimeCaption="預設關機時間"分組容器
DateTimePicker3TDateTimePickerdtpSetDateKind=dtkDate, Mode=dmUpDown設定關機日期
DateTimePicker4TDateTimePickerdtpSetTimeKind=dtkTime, Mode=dmUpDown, Format="HH:mm:ss"設定關機時間
CheckBox1TCheckBoxchkEnableCaption="啟用定時關機", Enabled=False主開關
Timer1TTimertmrMainInterval=1000 (1秒), Enabled=True核心輪詢器
Edit1 (可選)TEditedtCountdownReadOnly=True, Alignment=taCenter倒數計時顯示

核心程式碼實作

1. 表單建立初始化

void __fastcall TForm1::FormCreate(TObject *Sender) {
    // 初始化狀態
    chkEnable->Checked = false;
    chkEnable->Enabled = false;

    // 以目前時間初始化所有選擇器
    TDateTime now = Now();
    dtpCurrDate->DateTime = now;
    dtpCurrTime->DateTime = now;
    dtpSetDate->DateTime = now;
    dtpSetTime->DateTime = now;
}

2. Timer 核心邏輯 (每秒執行)

void __fastcall TForm1::tmrMainTimer(TObject *Sender) {
    TDateTime now = Now();

    // 更新即時顯示
    dtpCurrDate->DateTime = now;
    dtpCurrTime->DateTime = now;

    // 合併使用者設定的日期與時間
    TDateTime targetDateTime = dtpSetDate->Date + dtpSetTime->Time;

    // 驗證目標時間有效性 (必須大於現在)
    bool isValid = (targetDateTime > now);
    chkEnable->Enabled = isValid;
    if (!isValid) chkEnable->Checked = false;

    // 檢查關機條件
    if (chkEnable->Checked && (targetDateTime <= now + (1.0/86400.0))) { // 1秒容差
        ExecuteShutdown();
    }

    // 選擇性:更新倒數計時顯示
    if (edtCountdown) {
        double diff = targetDateTime - now;
        if (diff > 0) {
            int seconds = (int)(diff * 86400); // 天轉秒
            edtCountdown->Text = FormatFloat("#,##0 秒", seconds);
        } else {
            edtCountdown->Text = "時間已到";
        }
    }
}

3. 日期/時間聯動同步

// 日期改變同步至時間選擇器 (保持時間部分)
void __fastcall TForm1::dtpSetDateChange(TObject *Sender) {
    dtpSetTime->Date = dtpSetDate->Date;
    ValidateTargetTime();
}

// 時間改變同步至日期選擇器 (保持日期部分)
void __fastcall TForm1::dtpSetTimeChange(TObject *Sender) {
    dtpSetDate->Date = dtpSetTime->Date;
    ValidateTargetTime();
}

void __fastcall TForm1::ValidateTargetTime() {
    TDateTime target = dtpSetDate->Date + dtpSetTime->Time;
    bool valid = (target > Now());
    chkEnable->Enabled = valid;
    if (!valid) chkEnable->Checked = false;
}

4. 執行系統關機

void __fastcall TForm1::ExecuteShutdown() {
    // 停止計時器避免重複觸發
    tmrMain->Enabled = false;

    // 使用 Windows API 安全關機
    // EWX_SHUTDOWN = 0x00000001 (關機)
    // EWX_POWEROFF = 0x00000008 (切斷電源,需硬體支援)
    // EWX_FORCE = 0x00000004 (強制關閉應用程式)
    // EWX_FORCEIFHUNG = 0x00000010 (僅強制無回應程式)
    DWORD dwFlags = EWX_SHUTDOWN | EWX_POWEROFF | EWX_FORCEIFHUNG;
    DWORD dwReason = 0; // 可選:SHTDN_REASON_MAJOR_APPLICATION | SHTDN_REASON_MINOR_INSTALLATION

    if (!ExitWindowsEx(dwFlags, dwReason)) {
        DWORD err = GetLastError();
        ShowMessage("關機失敗,錯誤碼: " + IntToStr(err) + "\n請嘗試以管理員身分執行。");
        tmrMain->Enabled = true; // 重新啟用
    }
    // 成功時系統將關機,程式自然結束
}

進階功能擴充建議

  • 多種關機模式:新增 RadioGroup 選擇「關機/重新開機/登出/休眠/睡眠」,對應 EWX_REBOOT、EWX_LOGOFF、SetSuspendState
  • 排程重複:加入 TCheckListBox 選擇星期幾,儲存設定至登錄檔/INI 檔
  • 啟動最小化至系統匣:搭配 Shell_NotifyIcon 實現背景常駐
  • 關機前警告:倒數 60 秒顯示模態對話框,提供取消機會
  • 命令列參數支援:支援 `/shutdown 22:30 /force` 等參數啟動
  • 權限提升:Manifest 設定 requireAdministrator 或程式碼檢測重啟提權

常見問題排查

現象可能原因解決方案
關機不生效權限不足 / 群組原則限制以管理員執行,檢查本機安全原則「關閉系統」權限
時間誤差超過 1 秒Timer 間隔非精確 / 系統負載使用多媒體計時器 timeSetEvent 或接受秒級誤差
日期時間選擇器顯示異常地區設定格式衝突明確設定 Format 屬性,避免依賴系統預設
應用程式關閉後排程失效無背景服務機制改寫為 Windows Service 或使用工作排程器
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved