CStatic,可置於任何 CWnd 衍生視窗。TaskListBox (CStatic 衍生) // 對外介面、視窗掛載
└─ TaskList (核心邏輯) // 版面計算、繪製、滑鼠處理
├─ TaskFrame // 標題列、邊框繪製
├─ PuckerBtn // 摺疊/展開按鈕 (三角箭頭動畫)
└─ Item 基類
├─ TaskItem // 一般圖示+文字項目
└─ ColorItem // 彩色條狀項目 (擴充範例)
bool CTaskListBox::CreateTaskList()
{
UINT id = GetDlgCtrlID();
CString str; GetWindowText(str);
m_pTaskList = new CTaskList(this,
new CTaskFrame(str),
new CPuckerBtn(this),
new CTaskItem(this, id));
return m_pTaskList != nullptr;
}
bool CTaskListBox::CreateColorList() // 擴充範例
{
// ... 同樣流程,傳入 CColorItem
}
// 1. 建立控制項 (資源編輯器放置 Static, ID=IDC_TASKLIST, 類別關聯 CTaskListBox)
m_lbTask.CreateTaskList();
// 2. 準備圖示清單
CImageList m_imgList;
m_imgList.Create(IDB_BITMAP1, 16, 1, RGB(255,255,255));
// 3. 批次新增項目
ItemInfo item;
item.type = II_ICONTEXT;
CString tasks[] = { _T("Explorer 7.0"), _T("WINRAR 4.0"), _T("MediaPlayer"),
_T("Reader 7.0"), _T("PowerDesigner"), _T("Word 2000"),
_T("EXCEL 2000"), _T("RealPlayer 10"), _T("AutoCAD 2004"),
_T("ACCESS 2003") };
for (int i = 0; i < 10; ++i)
{
item.index = i;
item.text = tasks[i];
item.icon = m_imgList.ExtractIcon(i % 10);
m_lbTask.AddItem(item);
}
m_lbTask.ReSize(); // 重新計算版面
| 功能 | 實現要點 |
|---|---|
| 自繪 | TaskList::OnPaint 使用 CDC 繪製標題背景、分隔線、項目圖示/文字、摺疊按鈕 |
| 滑鼠互動 | OnMouseMove/OnLButtonDown 命中測試 → 設定熱項目/按下狀態 → InvalidateRect 觸發重繪 |
| 摺疊動畫 | PuckerBtn 繪製旋轉三角形;TaskList::Toggle 調整項目可見區域高度 + SetWindowPos 縮放控制項高度 |
| 事件通知 | 父視窗接收 WM_COMMAND (ID=控制項 ID, NotifyCode=自訂如 TLN_ITEMCLICK),lParam 傳遞項目索引 |
| 版面計算 | ReSize() 依字型高度、項目數、摺疊狀態計算總高度,配合 MoveWindow 調整 |
Draw, HitTest, GetHeight — 新增項目類型只需繼承並覆寫。TaskFrame/PuckerBtn,支援主題切換。ItemInfo.icon 接受 HICON,可來自 CImageList、LoadImage、GDI+ 繪製等。VC6.0 / VS2005+ / MFC 專案,需啟用 RTTI 與例外處理 (或移除 dynamic_cast 相容無 RTTI 環境)。
完整原始碼含 TaskListBox.h/cpp, TaskList.h/cpp, TaskItem.h/cpp 等檔案,可直接整合至專案。