views:

89

answers:

3

i wanna make a program runs in the background and shows an icon in tray bar.
I'm using win32. What api should i use? Do you know any good tutorials?

+1  A: 

http://www.winprog.org/tutorial/ is good for learning winapi and basically how Windows apps work. For the tray icon, use Shell_NotifyIcon. You will need a window, and a message loop for this.

tenfour
A: 

CSystemTray works well from coeproject. It is a wrapper around Shell_NotifyIcon.

Brian R. Bondy
+1  A: 

To make a program run in the background, you either add it as a service or make it "unavailable" to shutdown (for instance, hide the window for the program). To add an icon in the toolbar you use winapi. Call Shell_NotifyIcon and pass in a NOTIFYICONDATA structure

This should be defined somewhere

enum TrayIcon {
    ID = 13, CALLBACKID = WM_APP+1
};

Also, in the below code the hWnd is a HWND, which is the window that you want to associate with the notification icon. This HWND's wndProc will receive the messages for the icon.

Notes:

  • the NIF_ICON flag makes the hIcon valid in the NOTIFICATIONICONDATA structure. So if you don't want to have an icon, don't specify it.
  • the NIF_MESSAGE flag makes the uCallbackMessage valid. If you don't want to handle any messages, don't specify this flag.
  • You have to remove the icon before you shut down your program, or it will get stuck there until you hover over it
  • At startup of your computer, Shell_NotifyIcon may have some difficulties to succeed. I can't find the reference for it, but I know I have read it somewhere.. So, when not successful, don't assume that it will not work at all - just try again.

With this said, this is how you add, remove and handle the messages for the tray icon

To add the icon

// in HICON hIcon: this is the icon you want as the image in the tray
NOTIFYICONDATA nid;
nid.cbSize = sizeof(NOTIFYICONDATA);
nid.hWnd = hWnd;
nid.uID = ID;
nid.uFlags = NIF_ICON | NIF_MESSAGE;
nid.hIcon = hIcon;
nid.uCallbackMessage = /*TrayIcon::*/CALLBACKID;
Shell_NotifyIcon(NIM_ADD, &nid);

To remove the icon

NOTIFYICONDATA nid;
nid.cbSize = sizeof(NOTIFYICONDATA);
nid.hWnd = hWnd;
nid.uID = /*TrayIcon::*/ID;
Shell_NotifyIcon(NIM_DELETE, &nid);

Handling the messages for the icon

LRESULT wndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){
    switch (msg){
        // ...
        case /*TrayIcon::*/CALLBACKID:
        {
            // here, you handle the messages for your tray icon
        }
        break;
        // ...
    }
}
Default