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

ATL 復合控件開發實戰:定時關機控件完整製作流程

     編輯:關於VC++

什麼是復合控件?

復合控件將多個標準控件 (按鈕、編輯框、單選鈕等) 組合在一個對話框模板中,封裝為單一 ActiveX 控件。開發體驗近似 MFC 對話框程式,適合建構複雜 UI 組件。

完整製作步驟

1. 建立 ATL DLL 專案

  • 專案名:TrueShutDown
  • 其餘預設

2. 插入復合控件對象

  • 選單 插入 → ATL Object Wizard
  • 選擇 Composite Control (復合控件)
  • 短名稱:ShutDownCtrl

插入復合控件精靈

3. 設計對話框介面

自動生成對話框模板 (IDD_SHUTDOWNCTRL),拖放控件:

  • 編輯框:IDC_HOUR (時)、IDC_MINUTE (分)
  • 按鈕:IDC_OK (確定/重設)
  • 靜態文字:IDC_TIME (當前時間)、IDC_STIME (剩餘時間)
  • 單選鈕:IDC_RADIO1 (關機)、IDC_RADIO2 (重啟)、IDC_RADIO3 (強制關機)

對話框設計介面

4. 類別向導添加訊息處理

在 ClassView 右鍵 CShutDownCtrl → Add Window Message Handler:

  • IDC_OK + BN_CLICKED → OnClickedOk
  • WM_TIMER → OnTimer
  • WM_INITDIALOG → OnInitDialog
  • 三個 Radio 的 BN_CLICKED → OnClickedRadio1/2/3

5. 核心邏輯實作

成員變數


protected:
  int IsOK;      // 0=未設定, 1=倒數中
  int m_nType;   // 1=關機, 2=重啟, 3=強制關機

建構子初始化


CShutDownCtrl() { IsOK = 0; m_nType = 0; }

OnInitDialog:啟動兩個定時器


LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) {
  ::SetTimer(m_hWnd, 0, 5000, NULL); // 5秒檢查關機時間
  ::SetTimer(m_hWnd, 1, 1000, NULL); // 1秒更新顯示時間
  return 0;
}

OnTimer:核心邏輯


LRESULT OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) {
  SYSTEMTIME str;
  CHAR str1[20], str_h[10], str_m[10];
  ::GetLocalTime(&str);

  // 更新當前時間顯示 (Timer 1)
  sprintf(str1, "%2d時%2d分%2d秒", str.wHour, str.wMinute, str.wSecond);
  SetDlgItemText(IDC_TIME, str1);

  // 讀取設定關機時間
  GetDlgItemText(IDC_HOUR, str_h, sizeof(str_h));
  GetDlgItemText(IDC_MINUTE, str_m, sizeof(str_m));

  // 計算並顯示剩餘時間
  if(IsOK == 1)
    GetSTime(str.wHour, str.wMinute, atoi(str_h), atoi(str_m), str.wSecond);

  // 檢查是否到達關機時間 (Timer 0)
  if(wParam == 0 && IsOK == 1 &&
     str.wHour == atoi(str_h) && str.wMinute == atoi(str_m)) {
    switch(m_nType) {
      case 1: ExitWindowsEx(EWX_SHUTDOWN, 0); break;  // 關機
      case 2: ExitWindowsEx(EWX_REBOOT, 0); break;    // 重啟
      case 3: ExitWindowsEx(EWX_FORCE, 0); break;     // 強制關機
    }
  }
  return 0;
}

GetSTime:計算剩餘時間


void CShutDownCtrl::GetSTime(int H, int M, int h, int m, int s) {
  CHAR str[20];
  m -= 1; // 秒數調整
  if(h < H) h += 24;       // 跨午夜
  if(m < M) { m += 60; h -= 1; } // 分鐘借位
  sprintf(str, "%2d時%2d分%2d秒", h-H, m-M, 60-s);
  SetDlgItemText(IDC_STIME, str);
}

OnClickedOk:切換設定/運行狀態


LRESULT OnClickedOk(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) {
  if(IsOK == 0) { // 進入倒數模式
    ::EnableWindow(::GetDlgItem(m_hWnd, IDC_HOUR), FALSE);
    ::EnableWindow(::GetDlgItem(m_hWnd, IDC_MINUTE), FALSE);
    SetDlgItemText(IDC_OK, "重設");
    IsOK = 1;
  } else { // 重設模式
    ::EnableWindow(::GetDlgItem(m_hWnd, IDC_HOUR), TRUE);
    ::EnableWindow(::GetDlgItem(m_hWnd, IDC_MINUTE), TRUE);
    SetDlgItemText(IDC_OK, "確定");
    SetDlgItemText(IDC_STIME, "");
    IsOK = 0;
  }
  return 0;
}

單選鈕處理


LRESULT OnClickedRadio1(...) { m_nType = 1; return 0; } // 關機
LRESULT OnClickedRadio2(...) { m_nType = 2; return 0; } // 重啟
LRESULT OnClickedRadio3(...) { m_nType = 3; return 0; } // 強制

6. 測試方法

  1. F7 編譯專案。
  2. 開啟專案目錄,雙擊 ShutDownCtrl.htm (ATL 自動生成的測試頁) 即可在 IE 中測試。

關鍵技術點總結

  • 對話框模板即 UI 定義:所見即所得,無需手寫 CreateWindow。
  • 訊息映射機制:ATL 用 MESSAGE_HANDLER/COMMAND_HANDLER 宏,類似 MFC 但更輕量。
  • 計時器識別:wParam 對應 SetTimer 的 nIDEvent (0 和 1)。
  • 系統關機 API:ExitWindowsEx 需適當權限 (通常需 SE_SHUTDOWN_NAME)。
  • 跨午夜邏輯:GetSTime 處理「設定時間 < 當前時間」視為次日。

總結

復合控件開發本質上是「對話框程式組件化」。掌握 ATL 專案結構、對話框資源、訊息處理、COM 介面導出四大塊,即可將任意 MFC 對話框功能封裝為可重用 ActiveX 控件。本範例展示完整生命週期:初始化 → 使用者互動 → 定時檢查 → 系統操作。

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