Существует много способов обеспечить вызов Shell_NotifyIcon(NIM_DELETE, &m_tnd);
в C ++ для случая разрушения приложения; использование оболочки 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
, и его деструктор будет вызывается при очистке программы, даже если эта очистка вызвана ненормальным завершением.
Итак, мы можем использовать этот NOTIFYICONDATA
ресурс, заключенный в struct NID
, следующим образом:
NID nid; // <--- automatic storage duration, cleared after WinMain return
// even if it returns normal or abnormally
int CALLBACK WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
try
{
// GetMessage(&message, NULL, 0, 0) loop ...
// ...
// use nid.icon_data as you please
}
catch (...)
{
// something bad happened...
}
return 0;
}
В приведенном выше примере вызывается ~NID()
, когда программа завершает работу (после исключения или после закрытия программы), деструктор вызывает Shell_NotifyIcon(NIM_DELETE, &icon_data);
, и значок удаляется из области уведомлений; этот код охватывает нормальное завершение и исключение исключения, вы можете прочитать больше об этой теме в этот хороший ответ от NPE :
Что касается случая kill the process , то простого способа сделать это не существует.
Я уже проверял, что функции std::atexit
и std::at_quick_exit
не вызываются после завершения работы программы через диспетчер задач, поэтому я предполагаю, что вы должны перехватить вызов завершения ... это кажется довольно сложной задачей, но объяснено в этом ответе из BSH :
Когда процесс завершается (не закрывается), на самом деле ничего нельзя сделать, если вы не начнете делать некоторые перехваты, либо путем перехвата TerminateProcess
или NtTerminateProcess
в диспетчере задач процесс
Надеюсь, это поможет (хотя ответ через 6 лет, смеется)