Click here to Skip to main content
15,885,546 members
Articles / Programming Languages / C++

Example of a SysTray App in Win32

Rate me:
Please Sign up or sign in to vote.
3.50/5 (14 votes)
13 May 2007CPOL 79.6K   7.7K   32   6
How to create a systray application in Win32.

Introduction

Have you ever wondered how to create a cool application that runs in the background like a screen capture?

About the demo

Screenshot - systray_demo.jpg

The demo is a basic systray application with a popup menu and disable/enable option. It is the basic skeleton for anyone who wants to create a systray application.

How to create a systray (taskbar) application

Include the ShellAPI library

C++
#include <shellapi.h>

Init the NOTIFYICONDATA struct

C++
nidApp.cbSize = sizeof(NOTIFYICONDATA); 
nidApp.hWnd = (HWND) hWnd;
nidApp.uID = IDI_SYSTRAYDEMO; 
nidApp.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; 
nidApp.hIcon = hMainIcon; 
nidApp.uCallbackMessage = WM_USER_SHELLICON; 
LoadString(hInstance, IDS_APPTOOLTIP,nidApp.szTip,MAX_LOADSTRING);

Show the systary icon

C++
Shell_NotifyIcon(NIM_ADD, &nidApp);

Response to the message

Now our application gets a callback message when the mouse is moving over the systray icon. In our window callback function:

C++
switch (message)
{
    case WM_USER_SHELLICON: 
        // systray msg callback 
        switch(LOWORD(lParam)) 
        {
            case WM_RBUTTONDOWN:

Now we are monitoring the right button click.

Create a dynamic popup menu

C++
UINT uFlag = MF_BYPOSITION|MF_STRING;
GetCursorPos(&lpClickPoint);
hPopMenu = CreatePopupMenu();
InsertMenu(hPopMenu,0xFFFFFFFF,MF_BYPOSITION|MF_STRING,IDM_ABOUT,_T("About"));
if ( bDisable == TRUE )
{
    uFlag |= MF_GRAYED;
}
InsertMenu(hPopMenu,0xFFFFFFFF,uFlag,IDM_TEST2,_T("Test 2"));
InsertMenu(hPopMenu,0xFFFFFFFF,uFlag,IDM_TEST1,_T("Test 1"));
InsertMenu(hPopMenu,0xFFFFFFFF,MF_SEPARATOR,IDM_SEP,_T("SEP"));
if ( bDisable == TRUE )
{
    InsertMenu(hPopMenu,0xFFFFFFFF, 
               MF_BYPOSITION|MF_STRING,IDM_ENABLE,_T("Enable"));
}
else 
{
    InsertMenu(hPopMenu,0xFFFFFFFF,MF_BYPOSITION|MF_STRING,IDM_DISABLE,_T("Disable"));    
}
InsertMenu(hPopMenu,0xFFFFFFFF,MF_SEPARATOR,IDM_SEP,_T("SEP"));    
InsertMenu(hPopMenu,0xFFFFFFFF,MF_BYPOSITION|MF_STRING,IDM_EXIT,_T("Exit"));     
SetForegroundWindow(hWnd);
TrackPopupMenu(hPopMenu,TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_BOTTOMALIGN,
               lpClickPoint.x, lpClickPoint.y,0,hWnd,NULL);

When the application is closed

We need to delete the systray.

C++
Shell_NotifyIcon(NIM_DELETE,&nidApp);

A word from the author

More information can be found from the MSDN site: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/functions/shell_notifyicon.asp.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
Israel Israel
I have been developing since the age 12

Started on commador 64 and moved to C/Assembler

In the last 7 years i have been developing performance monitoring software.

Programming languages: C/C++/Java



Comments and Discussions

 
Generalit doesn't work on windows 7 Pin
gndnet17-Sep-10 6:27
gndnet17-Sep-10 6:27 
GeneralProblem with menu Pin
Sir Kot12-Jul-07 11:30
Sir Kot12-Jul-07 11:30 
GeneralRe: Problem with menu Pin
Sir Kot12-Jul-07 11:50
Sir Kot12-Jul-07 11:50 
GeneralRe: Problem with menu Pin
David Crow10-Oct-07 6:05
David Crow10-Oct-07 6:05 
GeneralTHANK YOU THANK YOU THANK YOU !!!!!!!! [modified] Pin
Danacom15-May-07 14:49
Danacom15-May-07 14:49 
I've been going NUTS, trying to figure out how to dynamically create the popup menu for the system tray. I tried:
(a) creating part of the menu in a resource file, then using AppendMenu or InsertMenu in WM_CREATE (after LoadMenu), and
(b) creating my menu from scratch in WM_CREATE,
but neither of these ever worked, for various reasons that I don't understand at all. Confused | :confused:

Now, I tried your technique of creating the menu in WM_USER / WM_LBUTTONUP, and that works *beautifully* !!! It's a little repetitious, in that the menu is repeatedly created, but maybe I can create it once and reuse it in subsequent calls to WM_USER... I'll try that.

Either way, you've saved what little remains of my hair!!

Thank you again... Cool | :cool: Rose | [Rose]


-- modified at 20:54 Tuesday 15th May, 2007
Yes, saving the menu handle globally, and creating it only once, worked fine - as long as I create it in WM_USER, and not in WM_CREATE... who knows...


GeneralRe: THANK YOU THANK YOU THANK YOU !!!!!!!! [modified] Pin
ExoticmE21-Sep-11 15:39
ExoticmE21-Sep-11 15:39 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.