Click here to Skip to main content
Click here to Skip to main content

System Tray Icons - Adding to your dialog application

By , 15 Apr 2002
 

Sample Image - systray.jpg

Introduction

I write applications for my site Settlers.net and also to make things easier for myself at home. In one of my apps, I have wanted to include a system tray icon. Only problem being, the sys tray icon samples people wrote were confusing and didn't do what I want. I'm young and not exactly pro at programming yet. This tray icon code is different simply because upon starting the program, the icon is placed into the system tray. When you click hide, the whole program is minimized to tray.

Right, now down the code.

Let's do this!

Okay, on the main dialog you must make a button for the hiding command. Name this button IDC_HIDEAPP.

Add files traynot.cpp and traynot.h to your project.

Paste this into yourDlg.cpp:

void CYourDlg::OnHide()
{
  // Load icon onto taskbar tray
  m_pTray = new CTrayNot (this,WM_TRAY_NOTIFY,
  NULL,theApp.m_pIconList);
  m_pTray->SetState(IDR_MAINFRAME);
  m_bHidden = TRUE;
}

void CYourDlg::OnUnHide()
{
  ShowWindow (SW_RESTORE) ;
  m_bHidden = FALSE ;
  /////////////////////////////////////
  // Remove icon from taskbar tray
  if (m_pTray)
  {
     delete m_pTray ;
     m_pTray = NULL ;
  }
}

LONG CYourDlg::OnTrayNotify ( WPARAM wParam, LPARAM lParam )
{
  switch (lParam)
  {
    case WM_RBUTTONDOWN:
    {
       CMenu menu ;
       // Load and Verify Menu
       VERIFY(menu.LoadMenu(IDR_TRAY));
       CMenu* pPopup = menu.GetSubMenu (0) ;
       ASSERT(pPopup != NULL);

       // Get the cursor position
       POINT pt ;
       GetCursorPos (&pt) ;

       // Fix Microsofts' BUG!!!!
       SetForegroundWindow();

       ///////////////////////////////////
       // Display The Menu
       pPopup->TrackPopupMenu(TPM_LEFTALIGN |
       TPM_RIGHTBUTTON,pt.x, pt.y, AfxGetMainWnd());
       break ;
    }
    case WM_LBUTTONDBLCLK:
       //////////////////////////////////
       // Unhide our Window
       if (m_bHidden)
          ShowWindow (SW_RESTORE);
       //OnUnHide() ;
       break ;
  }
  return (0) ;
}

void CYourDlg::OnDestroy() 
{
  CDialog::OnDestroy();

  // Remove Icon from Tray
  if (m_pTray)
  {
    delete m_pTray ;
    m_pTray = NULL ;
  } 
}

void CYourDlg::OnTrayRestore() 
{
  // UnHide Application
  if (m_bHidden)
    ShowWindow (SW_RESTORE) ;
  m_bHidden = FALSE ;
}

void CYourDlg::OnHideapp() 
{
  //This will be the onclick for the hide button
  //in order to call that the app is minimised.
  theApp.HideApplication();
}

Add these to yourDlgs message map:

ON_MESSAGE(WM_TRAY_NOTIFY, OnTrayNotify)
ON_COMMAND(ID_TRAY_RESTORE, OnTrayRestore)
ON_BN_CLICKED(IDC_HIDEAPP, OnHideapp)

Add #include "TrayNot.h" to yourDlg.h. Add:

CTrayNot* m_pTray;
BOOL m_bHidden;

to your public call in yourDlg.h before yourDlgs standard constructor.

Add the following to your dialog's afx message maps.

afx_msg LONG OnTrayNotify ( WPARAM wParam, LPARAM lParam ) ;
afx_msg void OnTrayRestore();
afx_msg void OnHideapp();
afx_msg void OnHide();
afx_msg void OnUnHide();
afx_msg void OnDestroy();

In yourapp.cpp (Not yourdlg.cpp) add this just after #endif:

// Load Icons for Tray 
m_pIconList[0] = LoadIcon (MAKEINTRESOURCE(IDR_MAINFRAME));
m_pIconList[1] = LoadIcon (MAKEINTRESOURCE(IDR_MAINFRAME));
m_pIconList[2] = LoadIcon (MAKEINTRESOURCE(IDR_MAINFRAME));

In the yourapp.h (not yourdlg.h) add this to the public callback:

HICON m_pIconList[3];

After the last } down the bottom of this file, add this:

extern CYourApp theApp;

Open stdafx.h and add #define WM_TRAY_NOTIFY WM_APP+1000 after AfxCmn.h's include.

Now just add a menu using the resource add and name it IDR_TRAY. Add a restore command (ID_TRAY_RESTORE) and then you're done....

You may find that when you quit, the icon doesn't disappear. Use the destroy function and add delete m_pTray ; to it... Or you could just download my demo project and rip all the code from that?

Anyways, I hope this helped some of you. Vote for this, so I get a T-Shirt haha!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Ashman
Web Developer
Australia Australia
Member
Name: Ash Rowe
From: Canberra, Australia
Qualifications: Diploma in Game Programming
Age: 19 (Getting old and feeling it)
 
Tutorials I have written in the past, I have done so in a fashion that would enable even the newest of programmers to get a grasp on what is actually happening with the code I submit. I am looking at writing even more in the near future to further assist others as well as gain a better understanding myself of the code I end up with.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralRe: two problems...memberAshman17 Feb '05 - 1:47 
For question 2:
Head towards OnTrayRestore() in yourProgramDlg.cpp.
Remove the line m_bHidden = FALSE;
 
So your code should look like this:
 

void CYourProgamDlg::OnTrayRestore()
{
if(m_bHidden)
ShowWindow(SW_RESTORE);
 
}
 

 
Now you can hide and restore and double click to your hearts content Smile | :)
 
Im not sure about question one sorry.
 
Will update my article.
 
Thanks
Ashman
 
I'm normally not a praying man, but if you're up there, please save me Superman.
GeneralRe: two problems...susssmarty907121 Feb '05 - 16:15 
Hello ashman,
 
I want to perform some different functionality wrt double click.. so can you tell me how is there any message can be captured apart from wm_lbtndblclk(as this one not work on win98)... i hope so you got my point...
 
Bye

GeneralRe: two problems...memberAshman21 Feb '05 - 18:22 
You are going to have to extend on your question. I didn't quite understand. Are you saying you want to use another mouse flag rather than dblclick to open the tray icon?
 
Thanks
Ashman
 
I'm normally not a praying man, but if you're up there, please save me Superman.
GeneralRe: two problems...membersmarty907124 Feb '05 - 4:07 
Hello ashman,
 
It works...
 
I was trying to integrate your code on a demo project with some other ui dialog. There in case of win 98/me I found double click was not working.
I had a impression wm_dblclk message not working...
 
But that was not the case ... It was due to error which states that an outgoing call can be made only when the incoming calls were depleted.. I freed up the message queue before making any outer calls
 
I solved it..
 
thxs a lot... Had done it...
 
Bye
 
smarty9071
 

Questionhow to start a dialog app hiddenmemberk-nar13 Feb '05 - 5:30 
it seems that the domodal function automatically set the window as visible
how to start a dialog based application in the tray without showing the dialog at all before you click on the icon?
I don't want a "hide it just after creating it" method : that makes a noticeable flipping window
 

thanks!
AnswerRe: how to start a dialog app hiddensusssmarty907116 Feb '05 - 20:56 
Hi,
 
u can apply a trick...
 
use timer to hide the dialog window after 2 second in your main application.
 
or logically use the following code to hide the dialog inside initinstance of your app
 
CWnd* pWnd = CWnd::GetDesktopWindow();
m_pMainWnd = m_pDlg;
m_pDlg->Create(,pWnd);
m_pDlg->ShowWindow(SW_HIDE);
 
remove the doModal code..
 
bye
smarty 9071
GeneralRe: how to start a dialog app hiddenmemberLeo Huf2 May '06 - 11:39 
Hi...
 
I'm a beginner in MFC programming, and I'm experimeting with your code...I think it will be very useful for me Smile | :)
 
Anyway, I tried this code for hiding the initial dialog when the program starts but it doesn't work... Doens't Create need more parameters than (,pWnd)? This didn't even work, so I tried (NULL, pWnd), but it says that the method doesn't take 2 parameters either. MSDN Library for CWnd::Create wasn't very helpful hehe...
 
Any help would be appreciated Smile | :)
Thanks
Leo
QuestionIs it has a bug?membersmallbarrow4 Aug '04 - 14:39 
I tested the demo at my machine, I found when I repeat to hide and restore several times, it will not work correctly.
Is it has a bug or my machine has some problem?
The environment of the demo runs at is Windows 2000 anc VC6.
GeneralAWESOMEmembershultas6 Mar '04 - 12:48 
Hey ashman
 
Excellent work. This is one of the best examples for a newbie that I've seen on this site. A lot of the times, authors label the article for a beginner, and then leave out this or that and it makes the beginner (like myself) pull out his hair trying to figure out why there are 79 compiler errors. A lot of other times, they slap a beginner example together, and it's great, but there's no walkthrough to tell beginners how to take their code and put it in yours.
 
This is a great example. Everything that you need to make it work in your own application.
 
You've got my 5 vote. Keep up the good work, and thanks for the efforts!
 
Shultas
GeneralAfxGetApp()->HideApplication(); when initialising main wndmemberIndrekSnt22 Dec '03 - 1:59 
I have windows XP and I want my program to automatically slip into tray without showing itself before.
 
HideApplication() works when I click on a button which triggers HideApplication() but not when I use it in BOOL CMyDlg::OnInitDialog(){
...
AfxGetApp()->HideApplication();
...
}
or in
LRESULT CMyDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam){
...
if(message==WM_SHOWWINDOW){
AfxGetApp()->HideApplication();
}
...
}

 
How could I get the window closing when program initialised?
Confused | :confused:
 
---
Blääh

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

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130523.1 | Last Updated 16 Apr 2002
Article Copyright 2001 by Ashman
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid