在Win7中,如何检测托盘图标是否存在?

dvlinker
C/C++领域优质创作者
博客专家认证
2014-09-03 06:38:05
加精
在Win7中,如何检测托盘图标是否存在?包括两个区域,右下角可见的通知区域和掩藏的溢出区域:


使用如下的代码是有问题:
// 判断在通知区域是否有托盘图标
BOOL32 CMainFrameWnd::IsTrayIconExsitInNotifyArea()
{
HWND hWnd = NULL, hWndPager = NULL;
unsigned long ulPID = 0;
long lRet = 0, lButtons = 0;
HANDLE hProcess = NULL;
LPVOID pAddress = NULL;
long lTextAdr = 0, lHwndAdr = 0, lHwnd = 0, lButtonID = 0;
char strBuff[1024] = { 0 };
char *pStr = NULL;
char *pTemp = NULL;

hWnd = ::FindWindow( _T("Shell_TrayWnd"), NULL );
hWnd = ::FindWindowEx( hWnd, 0, _T("TrayNotifyWnd"), NULL );
hWndPager = ::FindWindowEx( hWnd, 0, _T("SysPager"), NULL );
if( hWndPager == NULL )
{
hWnd = ::FindWindowEx( hWnd, 0, _T("ToolbarWindow32"), NULL ); // 对于

Win2000,没有SysPager窗口
}
else
{
hWnd = ::FindWindowEx( hWndPager, 0, _T("ToolbarWindow32"), NULL );
}

lRet = GetWindowThreadProcessId( hWnd, &ulPID );
hProcess = OpenProcess(

PROCESS_ALL_ACCESS|PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE, 0, ulPID );
pAddress = VirtualAllocEx( hProcess, 0, 0x4096, MEM_COMMIT, PAGE_READWRITE );
lButtons = ::SendMessage( hWnd, TB_BUTTONCOUNT, 0, 0 );

for( int i=0; i< lButtons; i++ )
{
lRet = ::SendMessage( hWnd, TB_GETBUTTON, i, long(pAddress) );
lRet = ReadProcessMemory( hProcess, LPVOID(long(pAddress) + 16), <extAdr,

4, 0 );
if( lTextAdr != -1 )
{
lRet = ReadProcessMemory( hProcess, LPVOID(lTextAdr), strBuff, 1024,

0 );
USES_CONVERSION;
pStr = OLE2T( (LPOLESTR)( strBuff ) );

pTemp = strstr( pStr, MAIN_DLG_WINDOWNAME ); // 通过Toolbar中的按钮

名称(“XXXXXX”)来比对
if ( pTemp != NULL ) // 找到对应字串
{
VirtualFreeEx( hProcess, pAddress, 0X4096, MEM_RELEASE );
CloseHandle( hProcess );
return TRUE;
}
}
}

VirtualFreeEx( hProcess, pAddress, 0X4096, MEM_RELEASE );
CloseHandle( hProcess );

return FALSE;
}

// 判断在托盘溢出区域是否有托盘图标(此种情况针对Win7和Win8系统)
BOOL32 CMainFrameWnd::IsTrayIconExsitInOverflowWindow()
{
HWND hWnd = NULL;
unsigned long ulPID = 0;
long lRet = 0, lButtons = 0;
HANDLE hProcess = NULL;
LPVOID pAddress = NULL;
long lTextAdr = 0, lHwndAdr = 0, lHwnd = 0, lButtonID = 0;
char strBuff[1024] = { 0 };
char *pStr = NULL;
char *pTemp = NULL;

// 对于Win7、Win8系统,新增了通知溢出区域,所以要检查该区域中是否有托盘图标
hWnd = ::FindWindow( _T("NotifyIconOverflowWindow"), NULL ); // 获取通知溢出区域句柄


hWnd = ::FindWindowEx( hWnd, NULL, _T("ToolbarWindow32"), NULL );

lRet = GetWindowThreadProcessId( hWnd, &ulPID );
hProcess = OpenProcess(

PROCESS_ALL_ACCESS|PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE, 0, ulPID );
pAddress = VirtualAllocEx( hProcess, 0, 0x4096, MEM_COMMIT, PAGE_READWRITE );
lButtons = ::SendMessage( hWnd, TB_BUTTONCOUNT, 0, 0 );

for( int i=0; i< lButtons - 1; i++ )
{
lRet = ::SendMessage( hWnd, TB_GETBUTTON, i, long(pAddress) );
lRet = ReadProcessMemory( hProcess, LPVOID(long(pAddress) + 16), <extAdr,

4, 0 );
if( lTextAdr != -1 )
{
lRet = ReadProcessMemory( hProcess, LPVOID(lTextAdr), strBuff, 1024,

0 );
USES_CONVERSION;
pStr = OLE2T( (LPOLESTR)( strBuff ) );

pTemp = strstr( pStr, _T("XXXXXXXX") ); // 通过窗口名称(“XXXXXXX”

)来比对
if ( pTemp != NULL ) // 找到对应字串
{
VirtualFreeEx( hProcess, pAddress, 0X4096, MEM_RELEASE );
CloseHandle( hProcess );
return TRUE;
}
}
}

VirtualFreeEx( hProcess, pAddress, 0X4096, MEM_RELEASE );
CloseHandle( hProcess );

return FALSE;
}
...全文
4635 41 打赏 收藏 转发到动态 举报
写回复
用AI写文章
41 条回复
切换为时间正序
请发表友善的回复…
发表回复
k1988 2016-11-24
  • 打赏
  • 举报
回复
引用 40 楼 Yans 的回复:
我也遇到了这个问题,顶上去,楼主解决没有呢?
http://baba.zhaoxiuyuan.com/2016/11/106_windows%E6%89%98%E7%9B%98%E5%9B%BE%E6%A0%87%E6%A3%80%E6%B5%8B/
「已注销」 2016-10-26
  • 打赏
  • 举报
回复
我也遇到了这个问题,顶上去,楼主解决没有呢?
kuankuan_qiao 2016-03-29
  • 打赏
  • 举报
回复
careysucci 2015-12-28
  • 打赏
  • 举报
回复
引用 31 楼 chenlycly 的回复:
再就是,为什么在64位机器上检测失败,是由于TBBUTTON结构体:
typedef struct _TBBUTTON {
    int iBitmap;
    int idCommand;
    BYTE fsState;
    BYTE fsStyle;
#ifdef _WIN64
    BYTE bReserved[6];          // padding for alignment
#elif defined(_WIN32)
    BYTE bReserved[2];          // padding for alignment
#endif
    DWORD_PTR dwData;
    INT_PTR iString;
} TBBUTTON, NEAR* PTBBUTTON, *LPTBBUTTON;
在32位和64位程序中的内存分布是不一样的,所以对于32位的程序在64位的操作系统上运行,是要重新计算偏移的
重新给过偏移后,图标名称是可以获取到,但是图标句柄获取的都是错误的,这是什么原因?
careysucci 2015-12-17
  • 打赏
  • 举报
回复
引用 31 楼 chenlycly 的回复:
再就是,为什么在64位机器上检测失败,是由于TBBUTTON结构体:
typedef struct _TBBUTTON {
    int iBitmap;
    int idCommand;
    BYTE fsState;
    BYTE fsStyle;
#ifdef _WIN64
    BYTE bReserved[6];          // padding for alignment
#elif defined(_WIN32)
    BYTE bReserved[2];          // padding for alignment
#endif
    DWORD_PTR dwData;
    INT_PTR iString;
} TBBUTTON, NEAR* PTBBUTTON, *LPTBBUTTON;
在32位和64位程序中的内存分布是不一样的,所以对于32位的程序在64位的操作系统上运行,是要重新计算偏移的
在代码里没用到这个结构体把,可以给段事例吗
careysucci 2015-12-17
  • 打赏
  • 举报
回复
楼主,你这个问题解决了么? 在32位系统中能获取到图标title,在64位里就不行了
NorthrendSnow 2014-11-19
  • 打赏
  • 举报
回复
想找win7下刷新托盘图标的代码
dvlinker 2014-09-17
  • 打赏
  • 举报
回复
引用 33 楼 shen_wei 的回复:
不是这个问题引起的,其他图标都是正常的,就是我们应用程序托盘图标出异常消失了!
shen_wei 2014-09-17
  • 打赏
  • 举报
回复
「已注销」 2014-09-16
  • 打赏
  • 举报
回复
学习来了,表示还没有读懂代码
dvlinker 2014-09-08
  • 打赏
  • 举报
回复
再就是,为什么在64位机器上检测失败,是由于TBBUTTON结构体:
typedef struct _TBBUTTON {
    int iBitmap;
    int idCommand;
    BYTE fsState;
    BYTE fsStyle;
#ifdef _WIN64
    BYTE bReserved[6];          // padding for alignment
#elif defined(_WIN32)
    BYTE bReserved[2];          // padding for alignment
#endif
    DWORD_PTR dwData;
    INT_PTR iString;
} TBBUTTON, NEAR* PTBBUTTON, *LPTBBUTTON;
在32位和64位程序中的内存分布是不一样的,所以对于32位的程序在64位的操作系统上运行,是要重新计算偏移的
dvlinker 2014-09-08
  • 打赏
  • 举报
回复
国外的论坛中,有提出到注册表项 HKEY_Current_User\Software\Microsoft\Windows\CurrentVersion\Explorer\TrayNotify中,分析 IconStreams和 PastIconsStream文件的内容,但是这是微软不公开的,也是严格禁止的,也没有相关的代码可供参考
dvlinker 2014-09-08
  • 打赏
  • 举报
回复
引用 28 楼 rrrfff 的回复:
第一,图标消失,单就QQ我无论在XP还是WIN7都没有出现过,请先检查程序逻辑,是否自己无意中删了notify icon 第二,你的检测方法不靠谱,需要想办法先刷新图标栏()
QQ肯定添加了很多保护措施;另外,和刷新图标栏应该没关系
RLib 2014-09-08
  • 打赏
  • 举报
回复
第一,图标消失,单就QQ我无论在XP还是WIN7都没有出现过,请先检查程序逻辑,是否自己无意中删了notify icon 第二,你的检测方法不靠谱,需要想办法先刷新图标栏()
gmhfyd 2014-09-07
  • 打赏
  • 举报
回复
帮楼主顶起,我也学习一下。
oliverdon 2014-09-05
  • 打赏
  • 举报
回复
学习下,都没关注这个问题
laoer_2002 2014-09-05
  • 打赏
  • 举报
回复
学习,关注ing
aa33535146 2014-09-05
  • 打赏
  • 举报
回复
有类似的问题,帮楼主顶有类似的问题,帮楼主顶
aa33535146 2014-09-05
  • 打赏
  • 举报
回复
有类似的问题,帮楼主顶有类似的问题,帮楼主顶
云满笔记 2014-09-05
  • 打赏
  • 举报
回复
不错 楼主有完美精神
加载更多回复(20)

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧