手里有一个软件,其中有一个功能需要读取windows系统的托盘程序。就是获取窗口句柄,读取托盘程序图标,然后遍历图标获取每个程序的信息。关键代码大概如下:
HWND hWnd,hWndPaper;
unsigned long lngPID;
long ret,lngButtons;
HANDLE hProcess;
LPVOID lngAddress;
long lngTextAdr,lngHwndAdr,lngHwnd,lngButtonID;
TCHAR strBuff[1024]={0};
TRAYDATA trayData = {0};
TBBUTTON btnData={0};
hWnd = FindWindow(_T("Shell_TrayWnd"), NULL);
hWnd = FindWindowEx(hWnd, 0, _T("TrayNotifyWnd"), NULL);
hWndPaper = FindWindowEx(hWnd, 0, _T("SysPager"), NULL);
if(!hWndPaper)
hWnd = FindWindowEx(hWnd, 0, _T("ToolbarWindow32"), NULL);
else
hWnd = FindWindowEx(hWndPaper, 0, _T("ToolbarWindow32"), NULL);
ret = GetWindowThreadProcessId(hWnd, &lngPID);
hProcess = OpenProcess(PROCESS_ALL_ACCESS|PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE,0,lngPID);
lngAddress = VirtualAllocEx(hProcess,0, 0x4096, MEM_COMMIT, PAGE_READWRITE);
lngButtons = SendMessage(hWnd, TB_BUTTONCOUNT, 0, 0);
RECT rc; POINT point;
LPVOID lngRect = VirtualAllocEx(hProcess,0,sizeof(RECT), MEM_COMMIT, PAGE_READWRITE);
CRect rect;
for(int i=0 ;i< lngButtons;i++)
{
int j = i;
ret = SendMessage(hWnd,TB_GETBUTTON,j,long(lngAddress));
ret = ReadProcessMemory(hProcess, LPVOID(long(lngAddress) + 16),&lngTextAdr,4,0);
if(lngTextAdr != -1)
{
ret = ReadProcessMemory(hProcess, LPVOID(lngTextAdr),strBuff,1024,0);
CString str(strBuff);
if (str.Compare(m_NotifyIconData.szTip) == 0)
{
::SendMessage(hWnd,TB_GETITEMRECT,(WPARAM)j,(LPARAM)lngRect);
ReadProcessMemory(hProcess,lngRect,&rc, sizeof(rc),0); //获取托盘图标区域
CWnd::FromHandle(hWnd)->ClientToScreen(&rc);
}
}
}
上面的程序只是示意,并非程序中的代码,程序中的代码还写了很多其他代码,就没复制。之前代码一直都是正常运行的,但是最近win11出了一个更新KB5018490,把托盘功能给改了,导致上面的代码不能正常读取了,读取到托盘图标的个数为零。
我对windows编程不是很懂,现在就想让程序能在系统更新后继续正常读取托盘。请各位熟悉托盘的朋友帮帮忙,告诉我win11的更新到底改了什么,最新的读取方法是怎样的,程序该如何对应修改。
谢谢。