Search code examples
c++winapisystem-traybackground-process

c++ create program runs in the background


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


Solution

  • 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;
            // ...
        }
    }