專案需求:在報表模式的列表控件中,支援滑鼠拖曳選取多個「子項目」(非整列),並對選取項目執行批次運算(加減乘除)。原版 CSortListCtrl 僅支援整列選取與排序,需擴充滑鼠拖曳多選邏輯。
CUIntArray 成員 ITEM(列索引)、SUBITEM(欄索引)。OnMouseMove 中判斷左鍵是否按下(拖曳狀態),呼叫 SubItemHitTest 取得游標下的列/欄,設定高亮顏色並記錄座標(避免重複)。if (nFlags == MK_LBUTTON) {
LVHITTESTINFO hitTestInfo; hitTestInfo.pt = point;
this->SubItemHitTest(&hitTestInfo);
// 設定選取顏色:白字深灰底
this->SetItemColor(hitTestInfo.iItem, hitTestInfo.iSubItem, RGB(255,255,255), RGB(50,50,50));
// 避免重複記錄
for (int i=0; i<ITEM.GetCount(); i++) {
if (hitTestInfo.iItem==ITEM[i] && hitTestInfo.iSubItem==SUBITEM[i]) return;
}
ITEM.Add(hitTestInfo.iItem);
SUBITEM.Add(hitTestInfo.iSubItem);
}
OnLvnBegindrag(開始新拖曳)與 OnNMClick(單點擊)中,將先前記錄的項目恢復預設顏色(黑字白底),並清空陣列。void CSortListCtrl::OnLvnBegindrag(NMHDR* pNMHDR, LRESULT* pResult) {
// 取消整列選取狀態
this->SetItemState(pNMLV->iItem, 0, LVIS_SELECTED);
// 恢復先前拖曳選取的顏色
for (int i=0; i<ITEM.GetCount(); i++)
this->SetItemColor(ITEM[i], SUBITEM[i], RGB(0,0,0), RGB(255,255,255));
ITEM.RemoveAll(); SUBITEM.RemoveAll();
*pResult = 0;
}
取得選取座標後,可於右鍵選單中執行批次運算:遍歷 ITEM/SUBITEM 陣列,取得各儲存格數值進行加減乘除,再寫回控件。完整邏輯見專案原始碼。
LVS_EX_FULLROWSELECT 與 LVS_EX_GRIDLINES 樣式。SetItemColor 為 CSortListCtrl 自訂函式,內部透過 NM_CUSTOMDRAW 實現單元格級著色。OnKeyDown 等訊息。