资源管理器重启后,程序的托盘图标不见了,但是程序确实还在运行。如何解决这一个问题呢?基本上有两个解决方向:其一是索性完全关闭程序,再重新打开;其二是重新建一个托盘图标。
这两种方法实现的关键是如何获得资源管理器重启的消息,以便做出相应的操作。百度了一下,找到一篇文章:www.vckbase.com/index.php/wv/310,但是看着不太符合我的习惯,且看别人的代码实在很费劲。
这里介绍另一中思路,即创建一个计时器,用于检测资源管理器的进程,如果它的PID(进程标示符)改变了,那么就表示它重启了(当然,这个方法是有一点风险的,但是PID在重启进程后不改变的几率很小,况且这里只是为了重新显示托盘图标)。
介绍一个关键函数,功能是通过进程名获取进程PID。
注:需引入头文件Tlhelp32.h
DWORD CTraffic_MonitoringDlg::GetProcessIdFromName(LPCTSTR name)
{
PROCESSENTRY32 pe;
DWORD id = 0;
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
pe.dwSize = sizeof(PROCESSENTRY32);
if( !Process32First(hSnapshot,&pe) )
{
return 0;
}
while(1)
{
pe.dwSize = sizeof(PROCESSENTRY32);
if( Process32Next(hSnapshot,&pe)==FALSE )
{
break;
}
if(strcmp(pe.szExeFile,name) == 0)
{
id = pe.th32ProcessID;
break;
}
}
CloseHandle(hSnapshot);
return id;
}
示例:
DWORD explorerID = GetProcessIdFromName("explorer.exe");
explorerID即为资源管理器进程的PID。
要判断它是否改变了,只要保存原来的explorerID,与新获得的explorerID比较,若改变了,说明资源管理器重启了。
追加一个方法:
重载窗口过程函数:
LRESULT
CxxxDlg::DefWindowProc(
UINT
message,
WPARAM
wParam,
LPARAM
lParam)
{
// TODO: 在此添加专用代码和/或调用基类
static
UINT
const
WM_TASKBARCREATED = RegisterWindowMessage(_T(
"TaskbarCreated"
));
if
( WM_TASKBARCREATED == message )
{
//显示托盘
Shell_NotifyIcon(NIM_ADD, &m_nid);
//在托盘区添加图标
return
TRUE;
}
return
CDialogEx::DefWindowProc(message, wParam, lParam);
}
|
或
1.在stdafx.h文件或MainFrm.h文件定义消息WMEX_TASKBARCREATED:
const
UINT
WMEX_TASKBARCREATED = ::RegisterWindowMessage(TEXT(
"TaskbarCreated"
));
2. 在MainFrm.h文件中,定义对应的消息函数OnRestartExplorer:
afx_msg
LRESULT
OnRestartExplorer(
WPARAM
wParam,
LPARAM
lParam);
3. 在MainFrm.cpp文件中定义消息映射:
ON_REGISTERED_MESSAGE(WMEX_TASKBARCREATED, OnRestartExplorer)
4. 在MainFrm.cpp文件中实现消息函数OnRestartExplorer:
LRESULT
CMainframe::OnRestartExplorer(
WPARAM
wParam,
LPARAM
lParam)
{
ToTray();
//添加托盘图标的函数,调用Shell_NotifyIcon函数
return
1;
}
|