diff --git a/server/2015Remote/2015RemoteDlg.cpp b/server/2015Remote/2015RemoteDlg.cpp index 9d25a72..b605f2c 100644 --- a/server/2015Remote/2015RemoteDlg.cpp +++ b/server/2015Remote/2015RemoteDlg.cpp @@ -1419,6 +1419,7 @@ VOID CMy2015RemoteDlg::InitControl() g_Column_Online_Width+=g_Column_Data_Online[i].nWidth; } m_CList_Online.InitColumns(); + LoadSortPreference(); // 加载上次记忆的排序偏好 // 隐藏空标题列(内部数据槽,不允许用户拖拽显示) for (int i = 0; i < g_Column_Count_Online; ++i) { if (g_Column_Data_Online[i].szTitle[0] == '\0') { @@ -3486,6 +3487,7 @@ void CMy2015RemoteDlg::OnTimer(UINT_PTR nIDEvent) // 虚拟列表:重建过滤索引并更新项目计数 if (hasListChange) { + ApplySort(); // 有排序偏好时重排,让新上线主机落到排序位置 RebuildFilteredIndices(); m_CList_Online.SetItemCountExV((int)m_FilteredIndices.size(), LVSICF_NOINVALIDATEALL | LVSICF_NOSCROLL); } @@ -3880,8 +3882,6 @@ void CMy2015RemoteDlg::SortByColumn(int nColumn) // 缩略图列点击表头不参与排序 —— 没有可比较的数据维度,避免误触发 if (ColumnToDataSlot(nColumn) < 0) return; - static int m_nSortColumn = 0; - static bool m_bSortAscending = false; if (nColumn == m_nSortColumn) { // 如果点击的是同一列,切换排序顺序 m_bSortAscending = !m_bSortAscending; @@ -3891,8 +3891,25 @@ void CMy2015RemoteDlg::SortByColumn(int nColumn) m_bSortAscending = true; } - // 虚拟列表:对数据源进行排序(列号映射到底层数据槽) EnterCriticalSection(&m_cs); + ApplySort(); + RebuildFilteredIndices(); + LeaveCriticalSection(&m_cs); + + // 刷新列表 + m_CList_Online.Invalidate(); + + SaveSortPreference(); +} + +void CMy2015RemoteDlg::ApplySort() +{ + // 无有效排序偏好或列不合法(缩略图/越界)时保持列表原始顺序 + if (m_nSortColumn <= COL_THUMBNAIL || m_nSortColumn >= g_Column_Count_Online) { + return; + } + + // 虚拟列表:对数据源进行排序(列号映射到底层数据槽),调用方需持有 m_cs int slot = ColumnToDataSlot(m_nSortColumn); bool asc = m_bSortAscending; std::sort(m_HostList.begin(), m_HostList.end(), @@ -3903,19 +3920,38 @@ void CMy2015RemoteDlg::SortByColumn(int nColumn) return asc ? (result < 0) : (result > 0); }); - // 重建索引映射 + // 排序后 clientID -> 索引映射已改变,需重建 m_ClientIndex.clear(); for (size_t i = 0; i < m_HostList.size(); ++i) { if (m_HostList[i]) { m_ClientIndex[m_HostList[i]->GetClientID()] = i; } } - // 重建过滤索引 - RebuildFilteredIndices(); - LeaveCriticalSection(&m_cs); +} - // 刷新列表 - m_CList_Online.Invalidate(); +void CMy2015RemoteDlg::LoadSortPreference() +{ + std::string val = THIS_CFG.GetStr("list", "OnlineListSort", ""); + if (val.empty()) { + m_nSortColumn = -1; // 无偏好:保持列表原始顺序 + m_bSortAscending = true; + return; + } + + auto arr = StringToVector(val, ','); + if (arr.size() >= 2) { + m_nSortColumn = atoi(arr[0].c_str()); + m_bSortAscending = (atoi(arr[1].c_str()) != 0); + } else { + m_nSortColumn = -1; + m_bSortAscending = true; + } +} + +void CMy2015RemoteDlg::SaveSortPreference() +{ + std::string val = std::to_string(m_nSortColumn) + "," + (m_bSortAscending ? "1" : "0"); + THIS_CFG.SetStr("list", "OnlineListSort", val); } void CMy2015RemoteDlg::OnHdnItemclickList(NMHDR* pNMHDR, LRESULT* pResult) diff --git a/server/2015Remote/2015RemoteDlg.h b/server/2015Remote/2015RemoteDlg.h index aea004a..fa2ae8e 100644 --- a/server/2015Remote/2015RemoteDlg.h +++ b/server/2015Remote/2015RemoteDlg.h @@ -173,6 +173,9 @@ protected: DECLARE_MESSAGE_MAP() public: void SortByColumn(int nColumn); + void ApplySort(); // 按偏好重排 m_HostList(调用方需持有 m_cs) + void LoadSortPreference(); + void SaveSortPreference(); afx_msg VOID OnHdnItemclickList(NMHDR* pNMHDR, LRESULT* pResult); static int CALLBACK CompareFunction(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort); template LRESULT OpenDialog(WPARAM wParam, LPARAM lParam) @@ -342,6 +345,8 @@ public: std::vector m_HostList; // 虚拟列表数据源(全部客户端) std::unordered_map m_ClientIndex; // clientID -> m_HostList 索引映射 std::vector m_FilteredIndices; // 当前分组过滤后的索引列表 + int m_nSortColumn = -1; // 当前排序列,-1 表示未排序 + bool m_bSortAscending = true; // 排序方向(true=升序) std::set m_GroupList; std::string m_selectedGroup; std::string m_v2KeyPath; // V2 密钥文件路径