設定 TVINSERTSTRUCT 的 iImage(未選中)與 iSelectedImage(選中)後,圖示僅在「展開/摺疊」子節點時切換,單純點選父節點不觸發圖示變化。
iSelectedImage 對應 TVIS_SELECTED 狀態,但樹形控制項預設行為:父節點被選中時不自動切換圖示,只有子節點被選中或父節點展開狀態改變時才更新。
在 ON_NOTIFY(TVN_SELCHANGED, ...) 處理器中,根據節點是否有子項、是否展開,呼叫 SetItemImage 強制更新:
void CMyTreeView::OnSelChanged(NMHDR* pNMHDR, LRESULT* pResult) {
LPNMTREEVIEW pNMTreeView = (LPNMTREEVIEW)pNMHDR;
CTreeCtrl& tree = GetTreeCtrl();
HTREEITEM hItem = pNMTreeView->itemNew.hItem;
if (hItem) {
// 判斷是否有子節點
HTREEITEM hChild = tree.GetChildItem(hItem);
bool hasChildren = (hChild != NULL);
bool expanded = (tree.GetItemState(hItem, TVIS_EXPANDED) & TVIS_EXPANDED);
int img = hasChildren ? (expanded ? 1 : 0) : 2; // 0=關閉資料夾, 1=開啟資料夾, 2=檔案
tree.SetItemImage(hItem, img, img); // 同步設定 iImage 與 iSelectedImage
}
*pResult = 0;
}
TVS_EX_AUTOHSCROLL 樣式。SetItemState 搭配 TVIS_STATEIMAGEMASK 自訂狀態圖示(如核取方塊),而非依賴預設選中圖示。OnInitialUpdate 插入節點時,根據層級預設正確圖示索引。TVN_SELCHANGED 中同步更新選中節點圖示,確保視覺一致性。TVN_GETDISPINFO 延遲載入圖示索引。