Compare commits
3
Commits
c8973282cb
...
d0bad75284
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d0bad75284 | ||
|
|
9d2e9ec8ca | ||
|
|
2d7f224a22 |
No files matched your search
@@ -1419,6 +1419,7 @@ VOID CMy2015RemoteDlg::InitControl()
|
|||||||
g_Column_Online_Width+=g_Column_Data_Online[i].nWidth;
|
g_Column_Online_Width+=g_Column_Data_Online[i].nWidth;
|
||||||
}
|
}
|
||||||
m_CList_Online.InitColumns();
|
m_CList_Online.InitColumns();
|
||||||
|
LoadSortPreference(); // 加载上次记忆的排序偏好
|
||||||
// 隐藏空标题列(内部数据槽,不允许用户拖拽显示)
|
// 隐藏空标题列(内部数据槽,不允许用户拖拽显示)
|
||||||
for (int i = 0; i < g_Column_Count_Online; ++i) {
|
for (int i = 0; i < g_Column_Count_Online; ++i) {
|
||||||
if (g_Column_Data_Online[i].szTitle[0] == '\0') {
|
if (g_Column_Data_Online[i].szTitle[0] == '\0') {
|
||||||
@@ -3486,6 +3487,7 @@ void CMy2015RemoteDlg::OnTimer(UINT_PTR nIDEvent)
|
|||||||
|
|
||||||
// 虚拟列表:重建过滤索引并更新项目计数
|
// 虚拟列表:重建过滤索引并更新项目计数
|
||||||
if (hasListChange) {
|
if (hasListChange) {
|
||||||
|
ApplySort(); // 有排序偏好时重排,让新上线主机落到排序位置
|
||||||
RebuildFilteredIndices();
|
RebuildFilteredIndices();
|
||||||
m_CList_Online.SetItemCountExV((int)m_FilteredIndices.size(), LVSICF_NOINVALIDATEALL | LVSICF_NOSCROLL);
|
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;
|
if (ColumnToDataSlot(nColumn) < 0) return;
|
||||||
|
|
||||||
static int m_nSortColumn = 0;
|
|
||||||
static bool m_bSortAscending = false;
|
|
||||||
if (nColumn == m_nSortColumn) {
|
if (nColumn == m_nSortColumn) {
|
||||||
// 如果点击的是同一列,切换排序顺序
|
// 如果点击的是同一列,切换排序顺序
|
||||||
m_bSortAscending = !m_bSortAscending;
|
m_bSortAscending = !m_bSortAscending;
|
||||||
@@ -3891,8 +3891,25 @@ void CMy2015RemoteDlg::SortByColumn(int nColumn)
|
|||||||
m_bSortAscending = true;
|
m_bSortAscending = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 虚拟列表:对数据源进行排序(列号映射到底层数据槽)
|
|
||||||
EnterCriticalSection(&m_cs);
|
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);
|
int slot = ColumnToDataSlot(m_nSortColumn);
|
||||||
bool asc = m_bSortAscending;
|
bool asc = m_bSortAscending;
|
||||||
std::sort(m_HostList.begin(), m_HostList.end(),
|
std::sort(m_HostList.begin(), m_HostList.end(),
|
||||||
@@ -3903,19 +3920,38 @@ void CMy2015RemoteDlg::SortByColumn(int nColumn)
|
|||||||
return asc ? (result < 0) : (result > 0);
|
return asc ? (result < 0) : (result > 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
// 重建索引映射
|
// 排序后 clientID -> 索引映射已改变,需重建
|
||||||
m_ClientIndex.clear();
|
m_ClientIndex.clear();
|
||||||
for (size_t i = 0; i < m_HostList.size(); ++i) {
|
for (size_t i = 0; i < m_HostList.size(); ++i) {
|
||||||
if (m_HostList[i]) {
|
if (m_HostList[i]) {
|
||||||
m_ClientIndex[m_HostList[i]->GetClientID()] = i;
|
m_ClientIndex[m_HostList[i]->GetClientID()] = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 重建过滤索引
|
}
|
||||||
RebuildFilteredIndices();
|
|
||||||
LeaveCriticalSection(&m_cs);
|
|
||||||
|
|
||||||
// 刷新列表
|
void CMy2015RemoteDlg::LoadSortPreference()
|
||||||
m_CList_Online.Invalidate();
|
{
|
||||||
|
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)
|
void CMy2015RemoteDlg::OnHdnItemclickList(NMHDR* pNMHDR, LRESULT* pResult)
|
||||||
|
|||||||
@@ -173,6 +173,9 @@ protected:
|
|||||||
DECLARE_MESSAGE_MAP()
|
DECLARE_MESSAGE_MAP()
|
||||||
public:
|
public:
|
||||||
void SortByColumn(int nColumn);
|
void SortByColumn(int nColumn);
|
||||||
|
void ApplySort(); // 按偏好重排 m_HostList(调用方需持有 m_cs)
|
||||||
|
void LoadSortPreference();
|
||||||
|
void SaveSortPreference();
|
||||||
afx_msg VOID OnHdnItemclickList(NMHDR* pNMHDR, LRESULT* pResult);
|
afx_msg VOID OnHdnItemclickList(NMHDR* pNMHDR, LRESULT* pResult);
|
||||||
static int CALLBACK CompareFunction(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
|
static int CALLBACK CompareFunction(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
|
||||||
template<class T, int id, int Show = SW_SHOW> LRESULT OpenDialog(WPARAM wParam, LPARAM lParam)
|
template<class T, int id, int Show = SW_SHOW> LRESULT OpenDialog(WPARAM wParam, LPARAM lParam)
|
||||||
@@ -342,6 +345,8 @@ public:
|
|||||||
std::vector<context*> m_HostList; // 虚拟列表数据源(全部客户端)
|
std::vector<context*> m_HostList; // 虚拟列表数据源(全部客户端)
|
||||||
std::unordered_map<uint64_t, size_t> m_ClientIndex; // clientID -> m_HostList 索引映射
|
std::unordered_map<uint64_t, size_t> m_ClientIndex; // clientID -> m_HostList 索引映射
|
||||||
std::vector<size_t> m_FilteredIndices; // 当前分组过滤后的索引列表
|
std::vector<size_t> m_FilteredIndices; // 当前分组过滤后的索引列表
|
||||||
|
int m_nSortColumn = -1; // 当前排序列,-1 表示未排序
|
||||||
|
bool m_bSortAscending = true; // 排序方向(true=升序)
|
||||||
std::set<std::string> m_GroupList;
|
std::set<std::string> m_GroupList;
|
||||||
std::string m_selectedGroup;
|
std::string m_selectedGroup;
|
||||||
std::string m_v2KeyPath; // V2 密钥文件路径
|
std::string m_v2KeyPath; // V2 密钥文件路径
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ BOOL CSystemDlg::OnInitDialog()
|
|||||||
SetWindowText(str);//设置对话框标题
|
SetWindowText(str);//设置对话框标题
|
||||||
|
|
||||||
m_ControlList.SetExtendedStyle(LVS_EX_FLATSB | LVS_EX_FULLROWSELECT);
|
m_ControlList.SetExtendedStyle(LVS_EX_FLATSB | LVS_EX_FULLROWSELECT);
|
||||||
|
LoadSortPreference(); // 加载上次记忆的排序偏好
|
||||||
if (m_bHow==TOKEN_PSLIST) { //进程管理初始化列表
|
if (m_bHow==TOKEN_PSLIST) { //进程管理初始化列表
|
||||||
m_ControlList.InsertColumnL(0, "映像名称", LVCFMT_LEFT, 180);
|
m_ControlList.InsertColumnL(0, "映像名称", LVCFMT_LEFT, 180);
|
||||||
m_ControlList.InsertColumnL(1, "PID", LVCFMT_LEFT, 70);
|
m_ControlList.InsertColumnL(1, "PID", LVCFMT_LEFT, 70);
|
||||||
@@ -227,6 +228,8 @@ void CSystemDlg::ShowWindowsList(void)
|
|||||||
lvc.pszText = str.GetBuffer(0);
|
lvc.pszText = str.GetBuffer(0);
|
||||||
lvc.cchTextMax = str.GetLength();
|
lvc.cchTextMax = str.GetLength();
|
||||||
m_ControlList.SetColumn(1, &lvc);
|
m_ControlList.SetColumn(1, &lvc);
|
||||||
|
|
||||||
|
ApplySort(); // 应用记忆的排序偏好
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSystemDlg::ShowProcessList(void)
|
void CSystemDlg::ShowProcessList(void)
|
||||||
@@ -260,8 +263,8 @@ void CSystemDlg::ShowProcessList(void)
|
|||||||
m_ControlList.SetItemText(i, 1, str);
|
m_ControlList.SetItemText(i, 1, str);
|
||||||
m_ControlList.SetItemText(i, 2, szProcessFullPath);
|
m_ControlList.SetItemText(i, 2, szProcessFullPath);
|
||||||
m_ControlList.SetItemText(i, 3, arr[1].empty() ? "N/A" : arr[1].c_str());
|
m_ControlList.SetItemText(i, 3, arr[1].empty() ? "N/A" : arr[1].c_str());
|
||||||
// ItemData 为进程ID
|
// ItemData 为进程ID;Data[3] 需与第 4 列"架构"一致,否则按架构排序拿到空串而无意义
|
||||||
auto data = new ItemData{ *PID, {arr[0].c_str(), str, szProcessFullPath}, arr[1].c_str() };
|
auto data = new ItemData{ *PID, {arr[0].c_str(), str, szProcessFullPath, arr[1].empty() ? "N/A" : arr[1].c_str()}, arr[1].c_str() };
|
||||||
m_ControlList.SetItemData(i, DWORD_PTR(data));
|
m_ControlList.SetItemData(i, DWORD_PTR(data));
|
||||||
|
|
||||||
dwOffset += sizeof(DWORD) + lstrlen(szExeFile) + lstrlen(szProcessFullPath) + 2; //跳过这个数据结构 进入下一个循环
|
dwOffset += sizeof(DWORD) + lstrlen(szExeFile) + lstrlen(szProcessFullPath) + 2; //跳过这个数据结构 进入下一个循环
|
||||||
@@ -273,6 +276,8 @@ void CSystemDlg::ShowProcessList(void)
|
|||||||
lvc.pszText = str.GetBuffer(0);
|
lvc.pszText = str.GetBuffer(0);
|
||||||
lvc.cchTextMax = str.GetLength();
|
lvc.cchTextMax = str.GetLength();
|
||||||
m_ControlList.SetColumn(2, &lvc); //在列表中显示有多少个进程
|
m_ControlList.SetColumn(2, &lvc); //在列表中显示有多少个进程
|
||||||
|
|
||||||
|
ApplySort(); // 应用记忆的排序偏好
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -319,8 +324,6 @@ int CALLBACK CSystemDlg::CompareFunction(LPARAM lParam1, LPARAM lParam2, LPARAM
|
|||||||
|
|
||||||
void CSystemDlg::SortByColumn(int nColumn)
|
void CSystemDlg::SortByColumn(int nColumn)
|
||||||
{
|
{
|
||||||
static int m_nSortColumn = 0;
|
|
||||||
static bool m_bSortAscending = false;
|
|
||||||
if (nColumn == m_nSortColumn) {
|
if (nColumn == m_nSortColumn) {
|
||||||
// 如果点击的是同一列,切换排序顺序
|
// 如果点击的是同一列,切换排序顺序
|
||||||
m_bSortAscending = !m_bSortAscending;
|
m_bSortAscending = !m_bSortAscending;
|
||||||
@@ -330,11 +333,56 @@ void CSystemDlg::SortByColumn(int nColumn)
|
|||||||
m_bSortAscending = true;
|
m_bSortAscending = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ApplySort();
|
||||||
|
SaveSortPreference();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSystemDlg::ApplySort()
|
||||||
|
{
|
||||||
|
// 无有效排序偏好时保持列表原始顺序
|
||||||
|
if (m_nSortColumn < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 防御:配置被手动修改导致列索引越界时跳过排序
|
||||||
|
CHeaderCtrl* pHeader = m_ControlList.GetHeaderCtrl();
|
||||||
|
if (pHeader && m_nSortColumn >= pHeader->GetItemCount()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 创建排序信息
|
// 创建排序信息
|
||||||
std::pair<int, bool> sortInfo(m_nSortColumn, m_bSortAscending);
|
std::pair<int, bool> sortInfo(m_nSortColumn, m_bSortAscending);
|
||||||
m_ControlList.SortItems(CompareFunction, reinterpret_cast<LPARAM>(&sortInfo));
|
m_ControlList.SortItems(CompareFunction, reinterpret_cast<LPARAM>(&sortInfo));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSystemDlg::LoadSortPreference()
|
||||||
|
{
|
||||||
|
// 进程管理 / 窗口管理 分别记忆各自的排序偏好
|
||||||
|
const char* key = (m_bHow == TOKEN_PSLIST) ? "ProcessListSort" : "WindowListSort";
|
||||||
|
std::string val = THIS_CFG.GetStr("list", key, "");
|
||||||
|
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 CSystemDlg::SaveSortPreference()
|
||||||
|
{
|
||||||
|
const char* key = (m_bHow == TOKEN_PSLIST) ? "ProcessListSort" : "WindowListSort";
|
||||||
|
std::string val = std::to_string(m_nSortColumn) + "," + (m_bSortAscending ? "1" : "0");
|
||||||
|
THIS_CFG.SetStr("list", key, val);
|
||||||
|
}
|
||||||
|
|
||||||
void CSystemDlg::OnHdnItemclickList(NMHDR* pNMHDR, LRESULT* pResult)
|
void CSystemDlg::OnHdnItemclickList(NMHDR* pNMHDR, LRESULT* pResult)
|
||||||
{
|
{
|
||||||
LPNMHEADER pNMHeader = reinterpret_cast<LPNMHEADER>(pNMHDR);
|
LPNMHEADER pNMHeader = reinterpret_cast<LPNMHEADER>(pNMHDR);
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ public:
|
|||||||
void OnReceiveComplete(void);
|
void OnReceiveComplete(void);
|
||||||
CWnd* m_pParent;
|
CWnd* m_pParent;
|
||||||
BOOL m_bHow;
|
BOOL m_bHow;
|
||||||
|
int m_nSortColumn = -1; // 当前排序列,-1 表示未排序
|
||||||
|
bool m_bSortAscending = true; // 排序方向(true=升序)
|
||||||
// 对话框数据
|
// 对话框数据
|
||||||
enum { IDD = IDD_DIALOG_SYSTEM };
|
enum { IDD = IDD_DIALOG_SYSTEM };
|
||||||
|
|
||||||
@@ -32,6 +34,9 @@ public:
|
|||||||
|
|
||||||
void DeleteAllItems();
|
void DeleteAllItems();
|
||||||
void SortByColumn(int nColumn);
|
void SortByColumn(int nColumn);
|
||||||
|
void ApplySort();
|
||||||
|
void LoadSortPreference();
|
||||||
|
void SaveSortPreference();
|
||||||
afx_msg VOID OnHdnItemclickList(NMHDR* pNMHDR, LRESULT* pResult);
|
afx_msg VOID OnHdnItemclickList(NMHDR* pNMHDR, LRESULT* pResult);
|
||||||
static int CALLBACK CompareFunction(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
|
static int CALLBACK CompareFunction(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user