A small note on how to work with tray icons, and how to show a baloon text next to the icon.
First the usual include stuff:
#define WINVER 0x0500 #define _WIN32_IE 0x0500 #include <windows.h> #include <string.h> #include <stdlib.h>Next we define some ID's:
#define TRAY_MESSAGE (WM_APP + 123) #define IDC_BUTTON1 1001 #define IDM_TIMER 1002There values are more or less don't care, except TRAY_MESSAGE which should have a small (e.g. 0) offset to WM_APP.
Then som variables and function prototypes:
HINSTANCE InstanceHandle; HICON HIcon; void Minimize(HWND hwndDlg); void UnMinimize(HWND hwndDlg); void SetBaloonTip(HWND hwndDlg);We will define the functions later, first the message handler for the application:
LRESULT CALLBACK DialogProc(HWND hwndDlg,
UINT msg,
WPARAM wParam,
LPARAM lParam)
{
switch(msg)
{
case WM_CREATE:
CreateWindow("BUTTON",
"Push Me",
WS_CHILD | WS_VISIBLE,
5, 5, 100, 24,
hwndDlg,
(HMENU)(IDC_BUTTON1),
InstanceHandle,
0);
break;
case TRAY_MESSAGE:
if(lParam == WM_LBUTTONDOWN)
{
UnMinimize(hwndDlg);
}
break;
case WM_TIMER:
KillTimer(hwndDlg, IDM_TIMER);
SetBaloonTip(hwndDlg);
break;
case WM_COMMAND:
if(HIWORD(wParam) == BN_CLICKED &&
LOWORD(wParam) == IDC_BUTTON1)
{
Minimize(hwndDlg);
}
break;
}
return DefWindowProc(hwndDlg, msg, wParam, lParam);
}
When we receive WM_CREATE we will create a single button on the application and nothing else.TRAY_MESSAGE is received when the user clicks the icon in the tray.
The WM_COMMAND for IDC_BUTTON1 is recevied when the user press the button.
WM_TIMER is received shortly after the app i minimized, because we we start a timer.
Now the main function:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, INT)
{
InstanceHandle = hInstance;
HIcon = LoadIcon(0, IDI_WINLOGO);
WNDCLASS wc;
memset(&wc, 0, sizeof(WNDCLASS));
wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
wc.lpfnWndProc = DialogProc;
wc.hInstance = InstanceHandle;
wc.hbrBackground = (HBRUSH )(COLOR_BTNFACE + 1);
wc.lpszClassName = "WhateverClass";
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
if(!RegisterClass(&wc))
return FALSE;
HWND WindowHandle = CreateWindow("WhateverClass",
"Whatever",
WS_VISIBLE | WS_CLIPSIBLINGS |
WS_CLIPCHILDREN | WS_CAPTION |
WS_BORDER | WS_SYSMENU,
100, 100, 110, 70,
0,
0,
InstanceHandle,
0);
MSG Msg;
while(GetMessage(&Msg, WindowHandle, 0, 0xFFFF) > 0)
{
if(!IsDialogMessage(WindowHandle, &Msg))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
}
return 0;
}
We start off by getting a icon, here a standard windows icon.If you want to use your own from a file called myicon.ico, replace the call to LoadIcon with:
HIcon = (HICON )LoadImage(0,
"myicon.ico",
IMAGE_ICON,
0,
0,
LR_DEFAULTSIZE | LR_LOADFROMFILE);
Now to the interesting stuff. First the function to hide the application and add the icon in the tray:
void Minimize(HWND hwndDlg)
{
NOTIFYICONDATA NotifyIconData;
ShowWindow(hwndDlg, SW_HIDE);
memset(&NotifyIconData, 0, sizeof(NotifyIconData));
NotifyIconData.cbSize = sizeof(NotifyIconData);
NotifyIconData.uID = 123;
NotifyIconData.hWnd = hwndDlg;
NotifyIconData.hIcon = HIcon;
NotifyIconData.uFlags = NIF_ICON | NIF_MESSAGE;
NotifyIconData.uCallbackMessage = WM_APP + 123;
strcpy(NotifyIconData.szTip, "TrayTip");
Shell_NotifyIcon(NIM_ADD, &NotifyIconData);
SetTimer(hwndDlg, IDM_TIMER, 2000, 0);
}
First the application window is hided, then we add the icon and finaly we start the timer.Now the function to show the application and remove the icon from the tray:
void UnMinimize(HWND hwndDlg)
{
NOTIFYICONDATA NotifyIconData;
ShowWindow(hwndDlg, SW_SHOW);
memset(&NotifyIconData, 0, sizeof(NotifyIconData));
NotifyIconData.cbSize = sizeof(NotifyIconData);
NotifyIconData.uID = 123;
NotifyIconData.hWnd = hwndDlg;
NotifyIconData.hIcon = HIcon;
NotifyIconData.uFlags = NIF_ICON | NIF_MESSAGE;
NotifyIconData.uCallbackMessage = TRAY_MESSAGE;
strcpy(NotifyIconData.szTip, "TrayTip");
Shell_NotifyIcon(NIM_DELETE, &NotifyIconData);
}
And finally the function which shows the ballon tip:
void SetBaloonTip(HWND hwndDlg)
{
NOTIFYICONDATA NotifyIconData;
memset(&NotifyIconData, 0, sizeof(NOTIFYICONDATA));
NotifyIconData.cbSize = sizeof(NOTIFYICONDATA);
NotifyIconData.uID = 123;
NotifyIconData.hWnd = hwndDlg;
NotifyIconData.hIcon = HIcon;
NotifyIconData.uFlags = 0x10;
NotifyIconData.uTimeout = 15000;
NotifyIconData.uCallbackMessage = TRAY_MESSAGE;
strcpy(NotifyIconData.szInfoTitle, "BaloonTitle");
strcpy(NotifyIconData.szInfo, "BalloonInfo");
strcpy(NotifyIconData.szTip, "TrayTip");
Shell_NotifyIcon(NIM_MODIFY, (NOTIFYICONDATA *)&NotifyIconData);
}
If your compiler complains about uTimeout, szInfoTitle and szInfo, it is too old, and can't show baloon tip.
The rest of the code should work anyway.The code at a glance.