Я создаю значок на панели задач:
BOOL TrayMessage(HWND hWnd, DWORD dwMessage)
{
NOTIFYICONDATA nid;
nid.cbSize = sizeof(nid);
nid.hWnd = hWnd;
nid.uID = 1;
nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
nid.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_MYAPP));
lstrcpy(nid.szTip, L"MyApp");
nid.uCallbackMessage = WM_NOTIFYICON;
return Shell_NotifyIcon(dwMessage, &nid);
}
когда приложение запускается / создается окно:
case WM_CREATE:
if (!TrayMessage(hWnd, NIM_ADD))
MessageBox(hMainWnd, L"Tray error.", 0, 0);
Это сообщение об ошибке:
никогда не происходит, когда я обычно запускаю .exe.
происходит только после выхода пользователя / повторного входа пользователя, в среднем каждые 5 запусков (мое приложение автоматически запускается при каждом запуске сеанса с помощью задачи TaskSchedular)
Конечно, когда возникает ошибка, значок не отображается на панели задач.
Что может быть причиной?
Система панели задач еще не готова (очень скоро после выхода пользователя из системы / повторного входа в систему)?
Сама панель задач еще не готова?
Следует ли мне переместить творение куда-нибудь за пределы
WM_CREATE
?
Изменить: после комментария @RbMm я попробовал следующее:
case WM_CREATE:
TrayMessage(hWnd, NIM_ADD);
// I removed MessageBox(...) from here
uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated"));
...
break;
default:
if (message == uTaskbarRestart)
{
TrayMessage(hWnd, NIM_ADD);
MessageBox(hMainWnd, L"TaskbarRestart", 0, 0);
}
Результат этого теста: случаи, когда значок в трее не отображается, это в точности те случаи, когда MessageBox TaskbarRestart
не отображается, т.е. когда событие TaskbarRestart никогда не доходит до цикла сообщений ... Это странно ...
Примечание: это происходит только после выхода / повторного входа пользователя.
s_uTaskbarRestart = RegisterWindowMessage(L"TaskbarCreated");
и каждый раз, когда у вас будетs_uTaskbarRestart
- добавлять значок на панель задач. сделайте это также наWM_CREATE
. он может выйти из строя по 1.) причине - панель задач еще не создана - person RbMm   schedule 22.07.2017TrayMessage
вам нужно не всегда вdefault
, а только когдаmessage == uTaskbarRestart
+ наWM_CREATE
. конечно возможен разрыв междуTrayMessage
(панель задач еще не создана в данный момент) иRegisterWindowMessage
(панель задач уже создана, поэтому вы не получите сообщение). вам нужно изменить порядок - сначала вызовRegisterWindowMessage
наWM_CREATE
или лучше при запуске программы (это глобальные данные, не связанное с окном) и только после этогоTrayMessage
WM_CREATE
- person RbMm   schedule 22.07.2017entrypoint (WinMain, etc)
вызовитеuTaskbarRestart = RegisterWindowMessage(L"TaskbarCreated");
(это должно быть сначала и один раз) и только потом, приWM_CREATE
иmessage == uTaskbarRestart
вызовитеTrayMessage
- person RbMm   schedule 22.07.2017TrayMessage
не всегда вdefault:
, но только еслиmessage == uTaskbarRestart
+WM_CREATE
, вы правы, это была неправильная копия / вставка. Редактировал вопрос. Попробую ваше новое предложение в комментариях! - person Basj   schedule 23.07.2017uTaskbarRestart = RegisterWindowMessage(L"TaskbarCreated");
вWinMain
перед основным циклом сообщений. В 75% случаев это работает, но иногда: 1. выход из сеанса 2. журнал сеанса 3. запускается проводник 4. мои приложения запускаются скрытыми (без значка) (я вижу это в диспетчере процессов!) 5. нет окна сообщений это похоже на то, что в моем приложении никогда не запускается TaskbarCreated :) (хотя в 75% случаев окно сообщения отображается!) - person Basj   schedule 23.07.2017he RegisterWindowMessage should be done during WM_CREATE:
- не конечно. это плохой пример.s_uTaskbarRestart
- это глобальные данные по смыслу (не связанные с вашим окном, посмотрите даже в примере, что он определен какstatic
) должен быть инициализирован только один раз. лучшее место - запуск программы - person RbMm   schedule 23.07.2017uTaskbarRestart
сообщение. Я думаю, что он отправляется во все окна верхнего уровня, однако я не отлаживаю подробно этот случай - поэтому не могу просто сказать, почему это происходит - person RbMm   schedule 23.07.2017