通过Spy++可以看出,系统托盘图标是一个ToolbarWindow32控件,要对其进行控制,只要用FindWindow和FindWindowEx找到其句柄,并发送ToolbarWindow32支持的消息即可。

1.获取图标数量:TB_BUTTONCOUNT

DWORD dwCount=::SendMessage(hToolbarWindow32, TB_BUTTONCOUNT, NULL, NULL);

2.获取图标的具体信息:TB_GETBUTTON

::SendMessage(hToolbarWindow32, TB_GETBUTTON, iIndex, (LPARAM)(LPTBBUTTON) lpButton);

难点在于,此处的SendMessage是跨进程操作,lpButton要在ToolbarWindow32所在的进程中申请。

具体代码如下:

//打开ToolbarWindow32所在的进程,就是explorer.exe
HANDLE hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,x_GetWndProcessId(hToolbarWindow32));

//在进程explorer.exe中申请内存
LPVOID lpButton=VirtualAllocEx(hProcess,NULL,sizeof(TBBUTTON),MEM_COMMIT, PAGE_READWRITE);

//执行TB_GETBUTTON
::SendMessage(hToolbarWindow32, TB_GETBUTTON, i, (LPARAM)lpButton);

//从进程explorer.exe中读取需要的数据
TBBUTTON TButton;
::ReadProcessMemory(hProcess, lpButton, &TButton, sizeof(TBBUTTON), NULL);

TRAYDATA TrayData;
::ReadProcessMemory(hProcess, (LPVOID)TButton.dwData, &TrayData, sizeof(TRAYDATA), NULL);

TCHAR szTips[1024];
::ReadProcessMemory(hProcess, (LPVOID)TButton.iString, szTips, 1024, NULL);

//szTips是Unicode字符串,需要转换
USES_CONVERSION;
CString csTips=W2A((WCHAR*)(szTips));

//释放在进程explorer.exe中申请的内存
::VirtualFreeEx(hProcess, lpButton, sizeof(TBBUTTON), MEM_FREE);
CloseHandle(hProcess);

备注,TBBUTTON.dwData的格式如下:

struct TRAYDATA
{
 HWND hWnd;
 UINT uID;
 UINT uCallbackMessage;
 DWORD Reserved1[2];
 HICON hIcon;
 DWORD Reserved2[3];
 TCHAR szExePath[MAX_PATH];
 TCHAR szTip[128];
};

3.删除或恢复图标
有了上面得到的信息,就可以使用Shell_NotifyIcon函数来操作图标了。

4.程序截图与源码
双击某行可实现托盘图标的隐藏或显示。



源码:点击下载系统托盘图标管理器源码与可执行程序


本文链接地址: 托盘图标管理器与跨进程SendMessage
https://blog.qingfengju.com/index.asp?id=294

分类:Win32/C++ 查看次数:14693 发布时间:2012/6/21 23:24:26