有许多方法可以确保在应用程序崩溃的情况下,在C ++中调用Shell_NotifyIcon(NIM_DELETE,&m_tnd);
。例如,使用 RAII包装器覆盖您正在使用的NOTIFYICONDATA
将起作用:
struct NID
{
NID() : icon_data() { icon_data.cbSize = sizeof(icon_data); }
~NID() { Shell_NotifyIcon(NIM_DELETE, &icon_data); }
void Show(HWND w) { icon_data.hWnd = w; Shell_NotifyIcon(NIM_ADD, &icon_data); }
NOTIFYICONDATA icon_data;
};
这是一个简化版的包装器,但它将说明主要思想:如果您在静态存储中创建
NID
实例,则它将在
WinMain
或
main
调用之前进行初始化,并且其析构函数将在程序清理期间调用,即使此清理是由于异常终止而引起的。
因此,我们可以这样使用
struct NID
中包装的
NOTIFYICONDATA
资源:
NID nid;
int CALLBACK WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
try
{
}
catch (...)
{
}
return 0;
}
上面的示例在程序终止时调用
~NID()
,无论是在异常还是关闭程序后,析构函数都会调用
Shell_NotifyIcon(NIM_DELETE, &icon_data);
并且图标会从通知区域中删除;此代码涵盖了正常终止和异常终止,您可以在
this good answer中阅读更多关于此主题的内容,该回答来自
NPE。
至于“杀死进程”的情况,没有简单的方法可以做到这一点。
我已经测试过
std::atexit
和
std::at_quick_exit
函数在通过任务管理器杀死程序后不会被调用,所以我猜你必须
hook终止调用...这似乎是一个相当复杂的任务,但可以在
this answer中从
BSH中找到解释。
当进程被终止(而不是关闭)时,除非开始进行一些挂钩,否则什么都无法做,要么通过挂钩TerminateProcess
或NtTerminateProcess
在任务管理器进程中。
希望能有所帮助(虽然是六年后的答案哈哈)。