Я видел много «неофициальных» обходных путей, чтобы обойти эту визуальную ошибку, но ни один из них, кажется, не работает правильно для меня. Позволь мне объяснить.
Скажем, я показываю свой собственный значок в системном трее в области уведомлений Windows (по часам).
Моя программа также поддерживает отображение контекстного меню, когда пользователь щелкает правой кнопкой мыши значок моего трея. Я воплощаю это в ловушку WM_RBUTTONDOWN
уведомление от обработчика сообщений, указанного в uCallbackMessage
параметр NOTIFYICONDATA
, Я тогда обрабатываю это так:
//Show menu (ask to return results here)
int nRes = TrackPopupMenu(hMenu, TPM_RIGHTALIGN | TPM_TOPALIGN |
TPM_LEFTBUTTON | TPM_VERPOSANIMATION | TPM_HORNEGANIMATION | TPM_RETURNCMD,
pnt.x, pnt.y, 0, this->GetSafeHwnd(), NULL);
К сожалению, приведенный выше код сам по себе не позволяет закрыть меню после щелчка левой кнопкой мыши где-то за его пределами.
Чтобы решить эту проблему, я нашел следующее решение:
//Need this to bypass a glitch in Windows to remove popup menu from
//System Tray after mouse click outside of it
::SetForegroundWindow(this->GetSafeHwnd());
//Show menu (ask to return results here)
int nRes = TrackPopupMenu(hMenu, TPM_RIGHTALIGN | TPM_TOPALIGN |
TPM_LEFTBUTTON | TPM_VERPOSANIMATION | TPM_HORNEGANIMATION | TPM_RETURNCMD,
pnt.x, pnt.y, 0, this->GetSafeHwnd(), NULL);
PostMessage(WM_NULL, 0, 0);
Но приведенное выше «исправление» вносит дополнительную ошибку.
Например, вот скриншот из Windows 8. Иногда я думаю, что это зависит от того, какое окно было в фокусе до этого, когда я щелкаю правой кнопкой мыши по иконке в трее, мое контекстное меню отображается поверх контекстного меню Windows по умолчанию, которое выглядит как это:
Есть ли способ устранить эту визуальную ошибку перекрывающихся контекстных меню?
Задача ещё не решена.
Других решений пока нет …