在使用NOTIFYICONDATA类的过程中,需要动态修改提示信息的内容,并同时改变绘制策略,即当鼠标指向该图标时不会消失(系统默认3秒后消失)
使用函数得到该提示框的窗口句柄(因为该窗口被动态维护,所以根据提示内容查找该窗口句柄)
HWND
CMainDlg::GetVideoStockHwnd(void)
{
HWND VideoHwnd = NULL;
HWND hwnd = ::FindWindow("Shell_TrayWnd", NULL ) ;
hwnd = ::FindWindowEx(hwnd, 0, "TrayNotifyWnd", NULL );
hwnd = ::FindWindowEx(hwnd, 0, "SysPager", NULL );
hwnd = ::FindWindowEx(hwnd, 0, "ToolbarWindow32", NULL );
int iNum=::SendMessage(hwnd,TB_BUTTONCOUNT ,NULL,NULL);
unsigned long n = 0;
TBBUTTON *pButton = new TBBUTTON;
CString strInfo = _T("");
wchar_t name[256] = {0};
CRect lprect;
TBBUTTON BButton;
DWORD pid = 0;
HWND wnd = 0;
LPPOINT lppoint = NULL;
GetWindowThreadProcessId(hwnd,&pid);
HANDLE hProcess=OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_ALL_ACCESS,true,pid);
for(int i=0; i<iNum; i++)
{
::SendMessage(hwnd,TB_GETBUTTON,i,(LPARAM)(&BButton));
ReadProcessMemory(hProcess,&BButton,pButton,sizeof(TBBUTTON),&n);
if (pButton->iString != 0xffffffff)
{
try
{
ReadProcessMemory(hProcess,(void *)pButton->iString,name,255,&n);
}
catch(...)
{
}
strInfo.Format("%s",CString(name));
if (strInfo.Find("Downloading Video Pack")==0 || strInfo.Find("Configuration Environment!")==0)
{
VideoHwnd = ::FindWindow("tooltips_class32", NULL ) ;
break;
}
}
}
delete pButton;
return VideoHwnd;
}
得到该句柄后根据spy++观测到的消息发送情况发现该窗口使用timer4来关闭提示信息,故在我的窗口中的更新提示信息内容的timer中加入杀掉该timer的语句,这样就可以保证当用户鼠标指向提示信息一段时间后提示不会消失。
同时在向该句柄发送wmpaint消息或使用invalidaterect均无法刷新,后采用showwindow频繁隐藏显示窗口实现了内容的刷新。
本窗口的timer消息处理代码如下:
case 1:
state = m_updateObj.GetDownloadState();
if(state<=100 && state>-2)
{
m_ProgressCtrl.SetPos(state);
DoDataExchange(FALSE);
// stockicon
cstip.Format("Downloading Video Pack %2d%%",state);
lstrcpyn(_StockIcon.szTip,cstip.GetBuffer(),sizeof(_StockIcon.szTip));
Shell_NotifyIcon(NIM_MODIFY,&_StockIcon);
}
else
{
if (m_ProgressCtrl.GetPos()==100)
{
m_ProgressCtrl.SetPos(0);
}
m_ProgressCtrl.StepIt();
DoDataExchange(FALSE);
cstip.Format("Configuration Environment!",state);
lstrcpyn(_StockIcon.szTip,cstip.GetBuffer(),sizeof(_StockIcon.szTip));
Shell_NotifyIcon(NIM_MODIFY,&_StockIcon);
}
hwnd = GetVideoStockHwnd();
if (hwnd && ::IsWindow(hwnd))
{
::KillTimer(hwnd,4);
::ShowWindow(hwnd,SW_HIDE);
::ShowWindow(hwnd,SW_SHOW);
}
break;