From 4d9d8d22e3666076988c30afb4e7c6fe365c19aa Mon Sep 17 00:00:00 2001
From: chenluhua1980 <Chenluhua@qq.com>
Date: 星期二, 06 一月 2026 18:53:04 +0800
Subject: [PATCH] 1.修复一个回复错误的问题;
---
SourceCode/Bond/Servo/CExpandableListCtrl.cpp | 135 ++++++++++++++++++++++++++++++++++++++++----
1 files changed, 122 insertions(+), 13 deletions(-)
diff --git a/SourceCode/Bond/Servo/CExpandableListCtrl.cpp b/SourceCode/Bond/Servo/CExpandableListCtrl.cpp
index ef21ed0..39831cc 100644
--- a/SourceCode/Bond/Servo/CExpandableListCtrl.cpp
+++ b/SourceCode/Bond/Servo/CExpandableListCtrl.cpp
@@ -95,26 +95,140 @@
m_rowColors.resize(GetItemCount());
SetRedraw(TRUE);
- Invalidate();
+ Invalidate(FALSE);
}
+// 鈥斺�� 浼樺寲鍚庣殑灞曞紑/鏀惰捣锛氬眬閮ㄦ彃鍏�/鍒犻櫎锛屼笉鍏ㄩ噺 RebuildVisible 鈥斺�� //
void CExpandableListCtrl::Expand(Node* n)
{
if (!n || n->children.empty()) return;
- if (!n->expanded) { n->expanded = true; RebuildVisible(); }
+ if (n->expanded) return;
+
+ // 鏈湴宸ュ叿锛氭壘鑺傜偣鍦� m_visible 涓殑琛屽彿
+ auto VisibleIndexOf = [&](Node* x)->int {
+ for (int i = 0; i < (int)m_visible.size(); ++i)
+ if (m_visible[i] == x) return i;
+ return -1;
+ };
+ // 閫掑綊鏀堕泦鈥滃簲褰撳彲瑙佲�濈殑瀛愭爲锛堝彈 expanded 褰卞搷锛�
+ std::vector<Node*> toInsert;
+ std::function<void(Node*)> CollectExpandedSubtree = [&](Node* x) {
+ if (!x) return;
+ for (auto& up : x->children) {
+ Node* ch = up.get();
+ toInsert.push_back(ch);
+ if (ch->expanded && !ch->children.empty())
+ CollectExpandedSubtree(ch);
+ }
+ };
+ // 浠� pos 璧锋彃鍏� nodes锛屽榻� m_visible / ListCtrl / m_rowColors
+ auto InsertRowsAt = [&](int pos, const std::vector<Node*>& nodes) {
+ if (nodes.empty()) return;
+ const int colCount = GetHeaderCtrl() ? GetHeaderCtrl()->GetItemCount() : 1;
+
+ SetRedraw(FALSE);
+
+ // 1) 鍏堟彃 m_visible
+ m_visible.insert(m_visible.begin() + pos, nodes.begin(), nodes.end());
+
+ // 2) 鍐嶆彃 ListCtrl
+ for (int i = 0; i < (int)nodes.size(); ++i) {
+ Node* cur = nodes[i];
+ LVITEM lvi{}; lvi.mask = LVIF_TEXT;
+ lvi.iItem = pos + i;
+ lvi.iSubItem = 0;
+ lvi.pszText = const_cast<LPTSTR>((LPCTSTR)(cur->cols.empty() ? _T("") : cur->cols[0]));
+ InsertItem(&lvi);
+
+ for (int col = 1; col < colCount; ++col) {
+ CString txt = (col < (int)cur->cols.size()) ? cur->cols[col] : _T("");
+ SetItemText(pos + i, col, txt);
+ }
+ }
+
+ // 3) 琛屽彿棰滆壊鏁扮粍鍚屾鎻掑叆榛樿鑹�
+ m_rowColors.insert(m_rowColors.begin() + pos, nodes.size(), RowColor{});
+
+ SetRedraw(TRUE);
+ Invalidate(FALSE);
+ };
+
+ // 鈥斺�� 鏍囪灞曞紑
+ n->expanded = true;
+
+ // 鈥斺�� 鍦� UI 閲屾彃鍏ュ叾鈥滃簲褰撳彲瑙佲�濈殑瀛愭爲
+ const int pos = VisibleIndexOf(n);
+ if (pos < 0) { RebuildVisible(); return; }
+
+ CollectExpandedSubtree(n);
+ InsertRowsAt(pos + 1, toInsert);
}
void CExpandableListCtrl::Collapse(Node* n)
{
if (!n || n->children.empty()) return;
- if (n->expanded) { n->expanded = false; RebuildVisible(); }
+ if (!n->expanded) return;
+
+ // 鏈湴宸ュ叿锛氭壘鑺傜偣琛屽彿
+ auto VisibleIndexOf = [&](Node* x)->int {
+ for (int i = 0; i < (int)m_visible.size(); ++i)
+ if (m_visible[i] == x) return i;
+ return -1;
+ };
+ // 璁$畻鈥滃綋鍓嶅彲瑙佺殑鎵�鏈夊悗浠f暟閲忊�濓紙鍩轰簬 level 閫掑噺鍒ゆ柇锛�
+ auto CountDescendantsInVisible = [&](Node* x)->int {
+ if (!x) return 0;
+ const int start = VisibleIndexOf(x);
+ if (start < 0) return 0;
+ const int baseLevel = x->level;
+ int cnt = 0;
+ for (int i = start + 1; i < (int)m_visible.size(); ++i) {
+ if (!m_visible[i]) break;
+ if (m_visible[i]->level <= baseLevel) break;
+ ++cnt;
+ }
+ return cnt;
+ };
+ // 浠� UI 鍒犻櫎 pos 寮�濮嬬殑 count 琛岋紝骞跺悓姝� m_visible/m_rowColors
+ auto DeleteRowsAt = [&](int pos, int count) {
+ if (count <= 0) return;
+
+ SetRedraw(FALSE);
+
+ // 鍒� ListCtrl锛氫竴鐩村垹 pos锛屽洜涓哄垹涓�琛屽悗鍚庣画涓婄Щ
+ for (int i = 0; i < count; ++i) {
+ DeleteItem(pos);
+ }
+ // 鍒� m_visible
+ m_visible.erase(m_visible.begin() + pos, m_visible.begin() + pos + count);
+ // 鍒犻鑹�
+ if (pos >= 0 && pos <= (int)m_rowColors.size()) {
+ int end = min((int)m_rowColors.size(), pos + count);
+ m_rowColors.erase(m_rowColors.begin() + pos, m_rowColors.begin() + end);
+ }
+
+ SetRedraw(TRUE);
+ Invalidate(FALSE);
+ };
+
+ // 鈥斺�� 鏍囪鏀惰捣
+ n->expanded = false;
+
+ // 鈥斺�� 鍙垹闄ゅ叾鈥滃綋鍓嶅彲瑙佲�濈殑鎵�鏈夊悗浠�
+ const int pos = VisibleIndexOf(n);
+ if (pos < 0) { RebuildVisible(); return; }
+
+ const int cnt = CountDescendantsInVisible(n);
+ if (cnt > 0) {
+ DeleteRowsAt(pos + 1, cnt);
+ }
}
void CExpandableListCtrl::Toggle(Node* n)
{
if (!n || n->children.empty()) return;
- n->expanded = !n->expanded;
- RebuildVisible();
+ if (n->expanded) Collapse(n);
+ else Expand(n);
}
CExpandableListCtrl::Node* CExpandableListCtrl::GetNodeByVisibleIndex(int i) const
@@ -136,7 +250,6 @@
for (int i = 0; i < (int)m_visible.size(); ++i) {
if (m_visible[i] == n) {
RedrawItems(i, i);
- UpdateWindow();
return;
}
}
@@ -151,7 +264,6 @@
for (int i = 0; i < (int)m_visible.size(); ++i) {
if (m_visible[i] == n) {
RedrawItems(i, i);
- UpdateWindow();
return;
}
}
@@ -183,7 +295,6 @@
m_rowColors[row] = rc;
RedrawItems(row, row);
- UpdateWindow();
}
CRect CExpandableListCtrl::expanderRectForRow(int row) const
@@ -256,11 +367,11 @@
// 鈥斺�� 鑻ョ偣鍑诲埌闇�瑕佲�滃叏鏂囨樉绀衡�濈殑鍒楋紝鍒欏悜鐖剁獥鍙e彂閫佽嚜瀹氫箟閫氱煡 鈥斺�� //
if (!m_popupCols.empty()) {
- LPNMITEMACTIVATE pia = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
+ LPNMITEMACTIVATE pia2 = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
// 鐢� SubItemHitTest 鏇寸簿鍑嗘嬁鍒板垪
LVHITTESTINFO ht{};
- ht.pt = pia->ptAction;
+ ht.pt = pia2->ptAction;
int hit = SubItemHitTest(&ht);
if (hit >= 0 && ht.iItem >= 0 && ht.iSubItem >= 0) {
const int row = ht.iItem;
@@ -474,7 +585,7 @@
DeleteAllItems();
SetRedraw(TRUE);
- Invalidate();
+ Invalidate(FALSE);
}
void CExpandableListCtrl::SetPopupFullTextColumns(const std::vector<int>& cols)
@@ -501,5 +612,3 @@
const int kPadding = 8; // 棰勭暀涓�鐐硅竟璺�/鐪佺暐鍙蜂綑閲�
return sz.cx > (rcCell.Width() - kPadding);
}
-
-
--
Gitblit v1.9.3