В ПОИСКАХ ИСТИНЫ
Q.Не подскажете как в tray выводить текст, как например сделаны часы в Windows?
Dmitriy
Как выводить в tray иконку, надеюсь, все знают ;)
Shell_NotifyIcon() есть, а вот Shell_NotifyText(), к сожалению, не существует… ;)
У меня просьба (в связи с небольшими неполадками) – прошу тех, кто не получил от меня ответа в течение недели или больше, послать письмо еще раз.
Желаю всем программировать с удовольствием!
©Алекс Jenter mailto:jenter@mail.ru Красноярск, 2000.
Программирование на Visual C++
Выпуск №11 от 22/07/2000
Добрый день всем!
В ответ на публикацию вопроса Дмитрия о System Tray в предыдущем выпуске помимо прямых ответов пришло еще несколько просьб рассказать о том, как в системный tray вообще помещать иконки. Я, видимо, был излишне оптимистичен, когда посчитал, что это все знают ;) Так что я решил поведать уважаемым читателям об этом в данном выпуске, в рубрике "WINAPI", в расчете на то, что эта информация будет полезна многим. Получается, сегодняшний выпуск целиком посвящен system tray ;)
WINAPI
Итак, задача у нас следующая: поместить в системный tray свою иконку, причем заставить ее функционировать стандартным образом – чтобы при наведении на нее появлялась подсказка, при нажатии на правую кнопку мыши выскакивало меню, на левую – производилось какое-нибудь действие.
Начнем с начала – нужно поместить иконку в tray. Сами вы это вряд ли сделаете – да это и не нужно. За вас это сделает Windows, вам нужно только сообщить операционной системе о своем намерении. Для этого служит функция Shell_NotifyIcon( ), которая позволяет создавать, изменять и удалять такие иконки.
Первый аргумент этой функции — это код операции, которую вам нужно осуществить. Он имеет три возможных значения — NIM_ADD, NIM_DELETE и NIM_MODIFY. В пояснениях, по-моему, не нуждается. Второй параметр – указатель на структуру NOTIFYICONDATA. Вот как эта структура выглядит:
typedef struct _NOTIFYICONDATA {
DWORD cbSize; // размер, обязательно указывать
HWND hWnd; // HWND для посылки уведомлений
UINT uID; // идентификатор иконки в tray, не имеет отношения к ресурсам
UINT uFlags; // см. ниже
UINT uCallbackMessage; // посылается вашей функции окна
HICON hIcon; // дескриптор иконки
CHAR szTip[64]; // строка с подсказкой
} NOTIFYICONDATA;
// uFlags
#define NIF_MESSAGE 0x1 // uCallbackMessage содержит информацию
#define NIF_ICON 0x2 // hIcon содержит информацию
#define NIF_TIP 0x4 // szTip содержит информацию
В принципе, назначение каждого члена этой структуры довольно прозрачно. Замечу только, что uID – это не идентификатор ресурса иконки, как можно было бы подумать, а вами определенный идентификатор для tray icon вашего приложения. Иконка, которую выводит в tray приложение, может меняться в процессе работы, но этот идентификатор остается постоянным.
Также вам нужно в uCallbackMessage записать сообщение, которое вы хотите чтобы система вам посылала в качестве уведомления о событиях, происходящих с вашей иконкой. Для этого в программе определите какое-нибудь user-defined сообщение, например так: #define WM_TRAYNOTIFY (WM_APP+100).
WM_APP используется как раз для того, чтобы именно в таком виде и определять нужные вам сообщения.
Теперь, предположим у вас подготовлена иконка для tray: IDI_MYTRAYICON. Нам нужно ее вывести в tray. Вот что мы делаем:
// уведомляющее сообщение
#define WM_TRAYNOTIFY (WM_APP+100)
// идентификатор иконки
#define ID_TRAYICON 1000
…
CString sNotifyTip = "Название вашей программы или другая подсказка";
NOTIFYICONDATA nid;
memset(&nid, 0, sizeof(nid)); // обнулять структуру перед использованием – хорошая привычка
nid.cbSize = sizeof(nid);
nid.hWnd = hWnd;
nid.uID = ID_TRAYICON;
nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
nid.uCallbackMessage = WM_TRAYNOTIFY;
nid.hIcon = ::LoadIcon(hInstance, MAKEINTRESOURCE(IDR_MAINFRAME));
lstrcpyn(nid.szTip, sNotifyTip, sizeof(nid.szTip));
Shell_NotifyIcon(NIM_ADD, &nid);
Этот код вставьте в функцию инициализации, причем окно вашего приложения уже должно быть создано, hWnd и hInstance должны быть определены. hWnd вы получаете при создании окна, а hInstance вам передают прямо в WinMain. Если у вас MFC-приложение, поставьте вместо них соответственно AfxGetMainWnd()->m_hWnd и AfxGetApp()->m_hInstance.
Ну вот, иконку мы вывели, и даже подсказка у нас выводится. Для своевременного удаления иконки в функцию, обрабатывающую выход из программы, поставьте примерно такую же конструкцию, но с NIM_DELETE:
NOTIFYICONDATA nid;
memset(&nid, 0, sizeof(nid));
nid.cbSize = sizeof(nid);
nid.hWnd = hWnd;
nid.uID = ID_TRAYICON;
Читать дальше