在 MFC 中實現 CTreeCtrl 的多選功能(按住 Ctrl 點選),需手動管理焦點與選取狀態。嘗試以下程式碼序列:
CTreeCtrl::SelectItem(hItem);
CTreeCtrl::SetItemState(hFocus, TVIS_SELECTED, TVIS_SELECTED);
CTreeCtrl::SelectItem(hItem);
雖能保留多選高亮,但按住 Ctrl 取消選取時,會同時清除前一項與其上一次選中項的高亮。參考的單文檔範例在對話框專案中無法直接套用。
最終採用策略:
void OnNMClickTree(NMHDR* pNMHDR, LRESULT* pResult) {
UINT flags;
HTREEITEM hItem = tree.GetHitTest(point, &flags);
if (hItem && (flags & TVHT_ONITEM)) {
if (GetKeyState(VK_CONTROL) < 0) { // Ctrl 鍵按下:多選
tree.SetItemState(hItem, TVIS_SELECTED, TVIS_SELECTED);
// 不呼叫 SelectItem,焦點不動
} else { // 單選
tree.SelectItem(hItem); // 同時設定焦點與選取
}
}
*pResult = 0;
}
優點:邏輯簡單、穩定,避免焦點跳動導致的視覺閃爍。缺點:多選時焦點虛線框固定在首項,不符合 Windows 標準行為,但功能可用。
MFC 樹狀控件多選需自行處理狀態,若標準行為難以完美實現,採用「焦點固定、狀態分離」的折中方案可快速交付可用功能。