| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313 |
- ////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "TrayIcon.h"
-
- IMPLEMENT_DYNAMIC(CTrayIcon, CCmdTarget)
- CTrayIcon::CTrayIcon(UINT uID) : m_SysToolBarHandle(NULL)
- {
- // Initialize NOTIFYICONDATA
- memset(&m_ID, 0 , sizeof(m_ID));
- m_ID.cbSize = NOTIFYICONDATA_V3_SIZE;
- m_ID.uID = uID; // never changes after construction
- }
- CTrayIcon::~CTrayIcon()
- {
- SetIcon(0, NULL, NULL); // remove icon from system tray
- }
- /*****************************************************************
- **【函数名称】 SetNotificationWnd
- **【函数功能】 设置托盘图标消息的通知窗口
- **【参数】 pNotifyWnd:窗口指针
- uCbMsg:消息
- **【返回值】
- ****************************************************************/
- void CTrayIcon::SetNotificationWnd(CWnd* pNotifyWnd, UINT uCbMsg)
- {
- ASSERT(pNotifyWnd==NULL || ::IsWindow(pNotifyWnd->GetSafeHwnd()));
- m_ID.hWnd = pNotifyWnd->GetSafeHwnd();
- ASSERT(uCbMsg==0 || uCbMsg>=WM_USER);
- m_ID.uCallbackMessage = uCbMsg;
- }
- /*****************************************************************
- **【函数名称】 SetIcon
- **【函数功能】 设置托盘图标样式
- **【参数】 uID:ICON ID
- hicon: ICON句柄
- lpTip:提示消息
- **【返回值】 成功TRUE,失败FALSE
- ****************************************************************/
- BOOL CTrayIcon::SetIcon(UINT uID, HICON hicon, LPCTSTR lpTip)
- {
- ASSERT((uID == 0) || (hicon == 0));
- UINT msg;
- m_ID.uFlags = 0;
-
- if(uID)
- {
- hicon = AfxGetApp()->LoadIcon(uID);
- }
-
- // Set the icon
- if (hicon)
- {
- // Add or replace icon in system tray
- msg = m_ID.hIcon ? NIM_MODIFY : NIM_ADD;
- m_ID.hIcon = hicon;
- m_ID.uFlags |= NIF_ICON;
- }
- else
- { // remove icon from tray
- if (m_ID.hIcon==NULL)
- return TRUE; // already deleted
- msg = NIM_DELETE;
- }
- // Use the tip, if any
- if (lpTip)
- lstrcpyn(m_ID.szTip, lpTip, sizeof(m_ID.szTip));
- if (m_ID.szTip[0])
- m_ID.uFlags |= NIF_TIP;
- // Use callback if any
- if (m_ID.uCallbackMessage && m_ID.hWnd)
- m_ID.uFlags |= NIF_MESSAGE;
- // Do it
- BOOL bRet = Shell_NotifyIcon(msg, &m_ID);
- if (msg==NIM_DELETE || !bRet)
- m_ID.hIcon = NULL; // failed
- return bRet;
- }
- /*****************************************************************
- **【函数名称】 ShowBalloonTip
- **【函数功能】 托盘气泡通知消息
- **【参数】 szMsg:消息内容
- szTitle:消息标题
- UINT:消息持续时间
- dwInfoFlags:消息类型
- **【返回值】 成功TRUE,失败FALSE
- ****************************************************************/
- BOOL CTrayIcon::ShowBalloonTip(LPCTSTR szMsg, LPCTSTR szTitle, UINT uTimeout, DWORD dwInfoFlags)
- {
- m_ID.cbSize = NOTIFYICONDATA_V3_SIZE;
- m_ID.uFlags = NIF_INFO;
- m_ID.uTimeout = uTimeout;
- m_ID.dwInfoFlags = dwInfoFlags;
- lstrcpy(m_ID.szInfo, szMsg ? szMsg : _T(""));
- lstrcpy(m_ID.szInfoTitle, szTitle ? szTitle : _T(""));
- return Shell_NotifyIcon(NIM_MODIFY, &m_ID);
- }
- /*****************************************************************
- **【函数名称】 SetTip
- **【函数功能】 设置托盘提示消息
- **【参数】 szTip:提示内容
- **【返回值】 成功TRUE,失败FALSE
- ****************************************************************/
- BOOL CTrayIcon::SetTip(LPCTSTR szTip)
- {
- m_ID.cbSize = NOTIFYICONDATA_V3_SIZE;
- m_ID.uFlags = NIF_TIP;
- lstrcpy(m_ID.szTip, szTip ? szTip : _T(""));
- return Shell_NotifyIcon(NIM_MODIFY, &m_ID);
- }
- /*****************************************************************
- **【函数名称】 FindTrayWnd
- **【函数功能】 获取托盘区域的窗口句柄
- **【参数】
- **【返回值】 托盘区域的窗口句柄
- ****************************************************************/
- HWND CTrayIcon::__FindTrayWnd(void)
- {
- HWND hWnd = NULL;
- HWND hWndPaper = NULL;
- if((hWnd = FindWindow(_T("Shell_TrayWnd"), NULL)) != NULL)
- {
- if((hWnd = FindWindowEx(hWnd, 0, _T("TrayNotifyWnd"), NULL)) != NULL)
- {
- hWndPaper = FindWindowEx(hWnd, 0, _T("SysPager"), NULL);
- if(hWndPaper == NULL)
- hWnd = FindWindowEx(hWnd, 0, _T("ToolbarWindow32"), NULL);
- else
- hWnd = FindWindowEx(hWndPaper, 0, _T("ToolbarWindow32"), NULL);
- }
- }
- return hWnd;
- }
- /*****************************************************************
- **【函数名称】 EnumTrayIcon
- **【函数功能】 枚举托盘区域所有图标为获取本图标的Rect数据
- **【参数】 hWnd: 系统托盘窗口句柄
- rect:本图标Rect值
- **【返回值】 成功TRUE,失败FALSE
- ****************************************************************/
- BOOL CTrayIcon::__EnumTrayIcon( HWND hWnd, RECT &rect )
- {
- BOOL bSuc = FALSE;
- unsigned long lngPID = 0;
- long ret = 0;
- long lngButtons = 0;
- long lngHwndAdr = 0;
- long lngHwnd = 0;
- HANDLE hProcess = NULL;
- LPVOID lngAddress = NULL;
- LPVOID LPlngRect = NULL;
- if(hWnd != NULL)
- {
- ret = GetWindowThreadProcessId(hWnd, &lngPID);
- if(ret != 0 && lngPID != 0)
- {
- hProcess = OpenProcess(PROCESS_ALL_ACCESS | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, 0, lngPID);
- if(hProcess != NULL)
- {
- lngAddress = VirtualAllocEx(hProcess, 0, 0x4096, MEM_COMMIT, PAGE_READWRITE);
- LPlngRect = VirtualAllocEx(hProcess, 0, sizeof(RECT), MEM_COMMIT, PAGE_READWRITE);
- lngButtons = SendMessage(hWnd, TB_BUTTONCOUNT, 0, 0); //发送消息获取托盘button数量
-
- if(lngAddress != NULL && LPlngRect != NULL)
- {
- for(int i = 0; i < lngButtons; i++)
- {
- RECT rc = { 0 };
- int j = i;
- SendMessage(hWnd, TB_GETBUTTON, j, long(lngAddress)); //发送消息获取托盘项数据起始地址
- //ret = ReadProcessMemory(hProcess, LPVOID(long(lngAddress) + 4), &m_IconBtnID, 4, 0); //获取buttonID
- ret = ReadProcessMemory(hProcess, LPVOID(long(lngAddress) + 12), &lngHwndAdr, 4, 0); //获取句柄地址
- if(ret != 0 && lngHwndAdr != -1)
- {
- ret = ReadProcessMemory(hProcess, LPVOID(lngHwndAdr), &lngHwnd, 4, 0); //获取句柄
- if((ret != 0) && ((HWND)lngHwnd == m_ID.hWnd)) //即我们要找的ICON
- {
- SendMessage(hWnd, TB_GETITEMRECT, (WPARAM)j, (LPARAM)LPlngRect); //发送消息获取托盘项区域数据
- ret = ReadProcessMemory(hProcess, LPlngRect, &rc, sizeof(rc), 0); //读取托盘区域数据
- if(ret != 0)
- {
- CWnd::FromHandle(hWnd)->ClientToScreen(&rc);
- rect = rc;
- }
- bSuc = TRUE;//在普通托盘区找到,在溢出区不再查找
- break;
- }
- }
- }
- }
-
- if(lngAddress != NULL)
- {
- VirtualFreeEx(hProcess, lngAddress, 0x4096, MEM_DECOMMIT);
- VirtualFreeEx(hProcess, lngAddress, 0, MEM_RELEASE);
- }
-
- if(LPlngRect != NULL)
- {
- VirtualFreeEx(hProcess, LPlngRect, sizeof(RECT), MEM_DECOMMIT);
- VirtualFreeEx(hProcess, LPlngRect, 0, MEM_RELEASE);
- }
-
- CloseHandle(hProcess);
- }
- }
- }
- return bSuc;
- }
- /*****************************************************************
- **【函数名称】 FindNotifyIconOverflowWindow
- **【函数功能】 获取溢出托盘区域的窗口句柄(WIN7适用)
- **【参数】
- **【返回值】 托盘区域的窗口句柄
- ****************************************************************/
- HWND CTrayIcon::__FindNotifyIconOverflowWindow( void )
- {
- HWND hwnd = NULL;
- hwnd = FindWindow(_T("NotifyIconOverflowWindow"), NULL);
- if(hwnd != NULL)
- {
- hwnd = FindWindowEx(hwnd, NULL, _T("ToolbarWindow32"), NULL);
- }
- return hwnd;
- }
- /*****************************************************************
- **【函数名称】 __GetDefaultHideRect
- **【函数功能】 获取托盘图标区域失败时给出缺省RECT
- **【参数】
- **【返回值】
- ****************************************************************/
- void CTrayIcon::__GetDefaultHideRect( RECT& rect )
- {
- int Wideth = GetSystemMetrics(SM_CXSCREEN);
- int Height = GetSystemMetrics(SM_CYSCREEN);
- rect.left = Wideth - 10;
- rect.right = Wideth;
- rect.top = Height - 10;
- rect.bottom = Height;
- }
- /*****************************************************************
- **【函数名称】 GetTrayRect
- **【函数功能】 获取本图标的Rect数据
- **【参数】
- **【返回值】 成功图标的Rect数据,失败Rect{ 0 }
- ****************************************************************/
- RECT CTrayIcon::GetTrayRect( void )
- {
- RECT rect = { 0 };
- if(m_SysToolBarHandle != NULL)
- {
- __EnumTrayIcon(m_SysToolBarHandle, rect);
- }
- else
- {
- m_SysToolBarHandle = __FindTrayWnd();
- if(m_SysToolBarHandle != NULL)
- {
- if(!__EnumTrayIcon(m_SysToolBarHandle, rect))
- {
- m_SysToolBarHandle = __FindNotifyIconOverflowWindow(); //在溢出区(win7)
- if(m_SysToolBarHandle != NULL)
- {
- __EnumTrayIcon(m_SysToolBarHandle, rect);
- }
- }
- }
- }
- if(IsRectEmpty(&rect))
- __GetDefaultHideRect(rect);
- return rect;
- }
|