Go4Expert

Go4Expert (http://www.go4expert.com/)
-   MFC (http://www.go4expert.com/articles/mfc-tutorials/)
-   -   Display a System Tray Icon in VC++ (http://www.go4expert.com/articles/display-tray-icon-vcpp-t343/)

shabbir 3Jun2005 10:56

Display a System Tray Icon in VC++
 
1 Attachment(s)
Create a Dialog based application and add a menu.

First you need to declare some variables in the the header file of your Dialog.
Code: CPP

#define MYWM_NOTIFYICON (WM_USER+1)
  //User defined messages.
 
  CMenu m_TrayMenu;
  //Displaying menu when right clicked on the system tray. Should be inside the class definition
 
  NOTIFYICONDATA tnd;
  //Icon Data
 
  afx_msg LRESULT onTrayNotify(WPARAM, LPARAM);
  //Function to handle the user messages
 

Now put the following code in the OnInitDialog function
Code: CPP

CString sTip(_T("Hello System Tray"));
 
  tnd.cbSize = sizeof(NOTIFYICONDATA);
  tnd.hWnd = this->GetSafeHwnd();;
  tnd.uID = IDR_MAINFRAME;
  //ICON RESOURCE ID
  tnd.uFlags = NIF_MESSAGE|NIF_ICON;
  tnd.uCallbackMessage = MYWM_NOTIFYICON;
  tnd.uFlags = NIF_MESSAGE|NIF_ICON|NIF_TIP;
  tnd.hIcon = LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE (IDR_MAINFRAME));
  //ICON RESOURCE ID
  lstrcpyn(tnd.szTip, (LPCTSTR)sTip, sizeof(tnd.szTip));
 
  DWORD dwMessage = NIM_ADD;
  Shell_NotifyIcon(dwMessage, &tnd);   
 
  m_TrayMenu.LoadMenu(IDR_MENU);
  //MENU RESOURCE ID.
 

Add user-defined message handler
Code: CPP

ON_MESSAGE(MYWM_NOTIFYICON,onTrayNotify)

Now define the body of onTrayNotify as follows
Code: CPP

LRESULT CWallpaperDlg::onTrayNotify(WPARAM wParam,LPARAM lParam)
  {
    UINT uMsg = (UINT) lParam;
    switch (uMsg )
    {
    case WM_LBUTTONDBLCLK:
    this->ShowWindow(SW_SHOW);
    break;
    case WM_RBUTTONUP:
    CPoint pt;   
    GetCursorPos(&pt);
    m_TrayMenu.GetSubMenu(0)->TrackPopupMenu(TPM_RIGHTALIGN|TPM_LEFTBUTTON|TPM_RIGHTBUTTON,pt.x,pt.y,this);
    break;
    }
    return TRUE;
  }

Now if you want to add the functionality that whenever someone hits the cross it should be minimized to the system tray then add the WM_CLOSE event handler and remove the call to the CDialog::OnClose(); and add the following code.
Code: CPP

ShowWindow(SW_HIDE);

Now in the WM_DESTROY message of the dialog add the following lines to delete the icon from the system tray and clean up the tray.
Code: CPP

Shell_NotifyIcon(NIM_DELETE,&tnd);

The sample application has been done in VC++ 7.1 compiler and if you wish to transfer that and view them in older version 7.0 then you need to do the following
Quote:

1. In SLN files, the 8.0 must be replaced with 7.0.
2. In vcproj files (and only vcproj), the 7.10 part must be replaced by 7.0.

AhmedHan 11Oct2005 19:28

Re: Display a System Tray Icon in VC++
 
One more thing...

Don't forget to define
#define _WIN32_WINNT 0x0501
before including "windows.h" file.

sanjoy.saha@hcl.in 19Feb2007 22:30

Re: Display a System Tray Icon in VC++
 
Quote:

Originally Posted by AhmedHan
One more thing...

Don't forget to define
#define _WIN32_WINNT 0x0501
before including "windows.h" file.

can u tell me why is this done as i am new to VC++

AhmedHan 19Feb2007 23:25

Re: Display a System Tray Icon in VC++
 
Quote:

Originally Posted by sanjoy.saha@hcl.in
can u tell me why is this done as i am new to VC++

Because some of the features of API functions and structures are defined for specific Windows versions or highers.

For example :
Code:

        //shellapi.h
            typedef struct _NOTIFYICONDATAA {
            DWORD cbSize;
            HWND hWnd;
            UINT uID;
            UINT uFlags;
            UINT uCallbackMessage;
            HICON hIcon;
    #if _WIN32_IE >= 0x0500
            CHAR szTip[128];
            DWORD dwState;
            DWORD dwStateMask;
            CHAR szInfo[256];
            _ANONYMOUS_UNION union {
                    UINT uTimeout;
                    UINT uVersion;
            } DUMMYUNIONNAME;
            CHAR szInfoTitle[64];
            DWORD dwInfoFlags;
    #else
            CHAR szTip[64];
    #endif
    #if _WIN32_IE >= 0x600
            GUID guidItem;
    #endif
    } NOTIFYICONDATAA,*PNOTIFYICONDATAA;

As you see, as the constant _WIN32_IE has higher values, higher features are enabled.
[img]file:///C:/Temp/moz-screenshot-13.jpg[/img] [img]file:///C:/Temp/moz-screenshot-14.jpg[/img] [img]file:///C:/Temp/moz-screenshot-15.jpg[/img]

From MSDN :
Code:

Windows Server 2003 family            _WIN32_WINNT>=0x0502
  Windows XP                            _WIN32_WINNT>=0x0501
  Windows 2000                        _WIN32_WINNT>=0x0500
  Windows NT 4.0                        _WIN32_WINNT>=0x0400
  Windows Me                            _WIN32_WINDOWS=0x0490
  Windows 98                            _WIN32_WINDOWS>=0x0410
  Internet Explorer 6.0                _WIN32_IE>=0x0600
  Internet Explorer 5.01, 5.5            _WIN32_IE>=0x0501
  Internet Explorer 5.0, 5.0a, 5.0b    _WIN32_IE>=0x0500
  Internet Explorer 4.01                _WIN32_IE>=0x0401
  Internet Explorer 4.0                _WIN32_IE>=0x0400
  Internet Explorer 3.0, 3.01, 3.02    _WIN32_IE>=0x0300


Gopinath 19Jul2007 16:24

Re: Display a System Tray Icon in VC++
 
Hi,

i did this application in VC++6.0, but i want to display the balloon tool tips for my system tray icon, i know how to do this. when i'm working in version 6.0 its giving errors as

error C2039: 'uTimeout' : is not a member of '_NOTIFYICONDATAA'
error C2039: 'dwInfoFlags' : is not a member of '_NOTIFYICONDATAA'
erro C2039: 'szInfo' : is not a member of '_NOTIFYICONDATAA'
.....
....


but when i did the another application application for system tray icon in VC++.Net then it runs perfectly and the system tray icons shows the balloon tips.

i know its due to the shellapi.h version with respective to the os.
now my question is how can i made VC++6.0 use the latest version of shellapi.h and able to display the balloon tool tips in my application.

please help me to solve this.
Thanks in advance.

-Gopinath

shabbir 19Jul2007 17:27

Re: Display a System Tray Icon in VC++
 
Change the header file path in the project settings.

2MuchRiceMakesMeSick 5Aug2007 07:20

Re: Display a System Tray Icon in VC++
 
Can someone walk me though the part Add user-defined message handler
I am still learning VC and im familiar with the MFC ClassWizard but where do I go from there?

2MuchRiceMakesMeSick 5Aug2007 07:21

Re: Display a System Tray Icon in VC++
 
im using VC++ 6.0 also

shabbir 5Aug2007 21:05

Re: Display a System Tray Icon in VC++
 
Quote:

Originally Posted by 2MuchRiceMakesMeSick
Can someone walk me though the part Add user-defined message handler
I am still learning VC and im familiar with the MFC ClassWizard but where do I go from there?

You need to add the code in the Message Map. In Dialog based application you will find that in the Dialog cpp file. Find the MESSAGE_MAP there.

2MuchRiceMakesMeSick 6Aug2007 08:16

Re: Display a System Tray Icon in VC++
 
Thanks. Now its saying that it cant find m_TrayMenu
I havent defined a Member Variable called m_TrayMenu is obviously why
But I cant because there is no Menu Control IDs in the wizard.
I did add a IDR_MENU1 by right clicking NEW MENU. Why is it not showing up under the MFC Class Wizard? Or am I doing it wrong?

Thanks for the help...

shabbir 6Aug2007 09:31

Re: Display a System Tray Icon in VC++
 
Why don't you download the code and try running it. I see you should have the IDR_MENU and not IDR_MENU1 but I could not get what you meant by
Quote:

Originally Posted by 2MuchRiceMakesMeSick
But I cant because there is no Menu Control IDs in the wizard.


parvez.yu 6Mar2008 14:50

Re: Display a System Tray Icon in VC++
 
what is system tray icon

shabbir 6Mar2008 16:02

Re: Display a System Tray Icon in VC++
 
Quote:

Originally Posted by parvez.yu
what is system tray icon

The Icon you see in the bottom right corner

parvez.yu 6Mar2008 16:48

Re: Display a System Tray Icon in VC++
 
oh ok thanks shabbir

torussxl 31Mar2009 08:58

Re: Display a System Tray Icon in VC++
 
I followed the instructions for the system icon, and my app is able to get one to show up...however the icon disappears as soon as the mouse hovers over it. So obviously the tooltip and the right-click menu cannot be activated.

What am I possibly doing wrong? I followed the instructions almost verbatim. I'm using Windows XP pro and Visual Studio 2005 version 8.

Thanks for any help.

shabbir 31Mar2009 14:12

Re: Display a System Tray Icon in VC++
 
Your Exe is dying and so the Icon is disappearing.

funativi 8Apr2009 18:03

Re: Display a System Tray Icon in VC++
 
I want to enable / disable menu items insystem trya. How cam I do it?

shabbir 8Apr2009 19:13

Re: Display a System Tray Icon in VC++
 
Quote:

Originally Posted by funativi (Post 45500)
I want to enable / disable menu items insystem trya. How cam I do it?

Disabling the menu item would be same for Normal Menu or for Any Windows control. There is an API EnableWindow and I think that should do it for you

funativi 9Apr2009 09:03

Re: Display a System Tray Icon in VC++
 
I have tried it, but it does not work, I debugged the code and I found that update handler is called before oncommand.

shabbir 9Apr2009 12:17

Re: Display a System Tray Icon in VC++
 
It does work for me ?

MunkeN 26May2009 16:23

Re: Display a System Tray Icon in VC++
 
Hi all.
I've used to sample, and it works like a charm - though I wonder how it's possible to make the menu dissappear if I leftclick outside of it?
It's enabled until I choose an item in the menu.

MunkeN 29May2009 13:05

Re: Display a System Tray Icon in VC++
 
Quote:

Originally Posted by MunkeN (Post 48446)
Hi all.
I've used to sample, and it works like a charm - though I wonder how it's possible to make the menu dissappear if I leftclick outside of it?
It's enabled until I choose an item in the menu.

Oh, I forgot to mention - I've already fixed it by calling "SetForegroundWindow()" just before TrackPopupMenu(). :)


All times are GMT +5.5. The time now is 11:40.