FAQ:WinAPI VCPP:иконка в области уведомлений (системном трее)
Материал из Весельчак У
Как создать иконку в области уведомлений (системном трее)? Как определить, какие действия производит с иконкой пользователь? Как сделать анимацию иконки в трее? Как удалить иконку?
Для всего этого - использовать процедуру API Shell_NotifyIcon(). Например, сделаем так, чтобы, по нажатию кнопки меню, окно программы сворачивалось в трей (иконка сначала недолго поморгает), а при щелчке левой кнопкой мыши по иконке - разворачивалось к предыдущему состоянию. В примере использовано одно документное приложение (MDI), поэтому "всё происходит" в классе CMainFrame. Переписать для CDialog и вообще для любого случая - несложно.
//определение класса CMainFrame
class CMainFrame : public CFrameWnd
{
// переменная для сохранения состояния окна до сворачивания.
// "Запоминаем" сюда значения SW_MAXIMIZE или SW_RESTORE
DWORD m_dwdTrayShowCMD;
// определяем константы
enum
{
// идентификатор иконки приложения в трее.
// не путать с ID ресурса иконки!!!
e_tray_ID = 1000,
e_tray_ID_1 = 1001, //(ID второй иконки для анимации)
e_tray_MSG = WM_COMMAND, //сообщение, посылаемое из трея
};
// это добавит визард ->
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMainFrame)
protected:
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
//}}AFX_VIRTUAL
};
//конструктор
CMainFrame::CMainFrame()
{
m_dwdTrayShowCMD = SW_MAXIMIZE;
}
// обработчик кнопки меню "свернуть в трей" (ID_PUTTOTRAY)
void CMainFrame::OnPuttotray()
{
// "запоминаем", какой командой потом разворачивать окно
m_dwdTrayShowCMD = ((GetStyle() & WS_MAXIMIZE) ? SW_MAXIMIZE : SW_RESTORE);
// заполняем структуру NOTIFYICONDATA для иконки
NOTIFYICONDATA ndata =
{
sizeof(NOTIFYICONDATA), // размер структуры
m_hWnd, // хендл этого окна
e_tray_ID, // идентификатор иконки трея в приложении
NIF_ICON | NIF_MESSAGE | NIF_TIP, // опции: есть иконка, есть сообщение, есть надпись
e_tray_MSG, // сообщение, посылаемое иконкой из трея (сейчас == WM_COMMAND)
::AfxGetApp()->LoadIcon(IDR_MAINFRAME), // иконка из ресурсов
"Значок моей программы" // всплывающая надпись
};
// заполняем структуру NOTIFYICONDATA для "пустой" иконки
NOTIFYICONDATA ndata1 = ndata;
ndata1.hIcon = 0;
// скрываем окно программы
ShowWindow(SW_HIDE);
// добавляем значок e_tray_ID в трей
Shell_NotifyIcon(NIM_ADD, &ndata);
// "моргаем" 4 раза
for (int i = 0; i < 4; i++)
{
// заменяем значок в трее пустым
Shell_NotifyIcon(NIM_MODIFY, &ndata1);
Sleep(70);
// возвращаем обратно иконку
Shell_NotifyIcon(NIM_MODIFY, &ndata);
Sleep(70);
}
return;
}
Добавим обработчик для команды e_tray_MSG (WM_COMMAND) - переопределим виртуальную функцию
BOOL CWnd::OnCommand(WPARAM wParam, LPARAM lParam)
BOOL CMainFrame::OnCommand(WPARAM wParam, LPARAM lParam)
{
// определяем, что сообщение от иконки e_tray_ID
if (wParam == e_tray_ID)
{
// определяем, какое действие мышью произвели
switch (lParam)
{
case WM_LBUTTONDOWN:
{
// показываем окно ("запомненной" командой)
ShowWindow(m_dwdTrayShowCMD);
// заполняем структуру для удаления иконки
NOTIFYICONDATA ndata =
{
sizeof(NOTIFYICONDATA),
m_hWnd,
e_tray_ID
};
// удаляем иконку
Shell_NotifyIcon(NIM_DELETE, &ndata);
}
break;
case WM_MOUSEMOVE:
{
// по иконке двигался курсор
}
break;
case WM_LBUTTONUP: {} break;
case WM_LBUTTONDBLCLK: {} break;
case WM_RBUTTONDOWN: {} break;
case WM_RBUTTONUP: {} break;
case WM_RBUTTONDBLCLK: {} break;
case WM_MBUTTONDOWN: {} break;
case WM_MBUTTONUP: {} break;
case WM_MBUTTONDBLCLK: {} break;
}
// сообщение обработано
return 1;
}
return CFrameWnd::OnCommand(wParam, lParam);
}