FAQ:WinAPI VCPP:иконка в области уведомлений (системном трее)
Материал из Весельчак У
Версия от 20:52, 30 июля 2008; RXL (обсуждение | вклад)
Как создать иконку в области уведомлений (системном трее)? Как определить, какие действия производит с иконкой пользователь? Как сделать анимацию иконки в трее? Как удалить иконку?
Для всего этого - использовать процедуру 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; } </pre> <pre> //обработчик кнопки меню "свернуть в трей" (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, //сообщение, посылаемое иконкой из трея (сейчас == WM_COMMAND) e_tray_MSG, //иконка из ресурсов ::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); }