csdnzgj828网友提供:
http://info.52z.com/html/24668.html
有网友提出,能不能在程序界面上显示当前的托盘图标,这样更直观一些。这一点我也曾想到过,也知道奥秘就在TBBUTTON这个结构体的dwData域里面,可惜这个域的结构在MSDN中没有描述。我也曾试着发送TB_GETIMAGELIST消息获取image list的句柄,然后用CImageList::FromHandle加载到CImageList中,但却都失败了。
在csdn网友的帮助下,我弄清了dwData的结构,并据此改进了程序,下面的截图是改进版运行的画面。
其实dwData有一个这样的机构,我们命名为TRAYDATA:
- struct TRAYDATA
- {
- HWND hwnd;
- UINT uID;
- UINT uCallbackMessage;
- DWORD Reserved[2];
- HICON hIcon; //托盘图标的句柄
- };
要获取到这个hIcon,其实很简单:
- //分配虚拟内存
- lngAddress = VirtualAllocEx(hProcess, NULL, sizeof(TBBUTTON), MEM_COMMIT, PAGE_READWRITE);
- //将hProcess进程内,地址为lngAddress中的内容(大小为sizeof(TBBUTTON))获取到tb中
- ret = ::ReadProcessMemory(hProcess, LPVOID(long(lngAddress)), &tb, sizeof(TBBUTTON), 0);
- //将hProcess进程内,地址为tb.dwData中的内容(大小为sizeof(TRAYDATA))获取到tray中
- ret = ::ReadProcessMemory(hProcess, LPVOID(tb.dwData), &tray, sizeof(TRAYDATA), 0);
然后就可以用tray.hIcon索引到这个图标句柄了
-------------------------------------------------------------------------------------
HWND hWnd,hWndTmp;
unsigned long lngPID;
long ret,lngButtons;
HANDLE hProcess;
LPVOID lngAddress;
long lngTextAdr,lngHwndAdr,lngHwnd,lngButtonID;
char strBuff[1024]={0};
char* str = NULL;
hWnd = ::FindWindow("Shell_TrayWnd", NULL);
hWnd = ::FindWindowEx(hWnd, 0, "TrayNotifyWnd", NULL);
hWndTmp = ::FindWindowEx(hWnd, 0, "SysPager", NULL);
if(!hWndTmp)
hWnd = ::FindWindowEx(hWnd, 0, "ToolbarWindow32", NULL);
else
hWnd = ::FindWindowEx(hWndTmp, 0, "ToolbarWindow32", NULL);
TRACE("/nhWnd=%x/n",hWnd);
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);//0x02e60000
lngButtons = ::SendMessage(hWnd, TB_BUTTONCOUNT, 0, 0);
for(int i = 0 ;i<lngButtons ;i++)
{
ret = ::SendMessage(hWnd,TB_GETBUTTON,i,long(lngAddress));
ret = ::ReadProcessMemory(hProcess, LPVOID(long(lngAddress) + 16), &lngTextAdr, 4, 0);
if(lngTextAdr != -1)
{
ret = ::ReadProcessMemory(hProcess, LPVOID(lngTextAdr), strBuff, 1024, 0);
ret = ::ReadProcessMemory(hProcess, LPVOID(long(lngAddress) + 12), &lngHwndAdr, 4, 0);
ret = ::ReadProcessMemory(hProcess, LPVOID(lngHwndAdr), &lngHwnd, 4, 0);
ret = ::ReadProcessMemory(hProcess, LPVOID(long(lngAddress) + 4), &lngButtonID, 4, 0);
}
HWND h = (HWND)lngHwnd;
HICON hIcon = (HICON)::SendMessage(h,WM_GETICON,ICON_SMALL,0);
if(hIcon == NULL)
{
}
else
{
((CStatic*)GetDlgItem(IDC_STATIC1))->SetIcon(hIcon);
}
}
::VirtualFreeEx( hProcess, lngAddress, 0X4096, MEM_RELEASE);
::CloseHandle(hProcess);