Click here to Skip to main content
15,881,898 members
Articles / Desktop Programming / ATL

Placing an icon in the system tray from an ATL COM server - with minimum hassle

Rate me:
Please Sign up or sign in to vote.
4.72/5 (10 votes)
23 Jun 20027 min read 241K   2.1K   57  
This article describes a helper class that assists with placing an icon in the shell (aka "system tray"), and changing the tip text. You can get this functionality by simply deriving your ATL object from the helper class.
// MyServer.h : Declaration of the CMyServer

#ifndef __MYSERVER_H_
#define __MYSERVER_H_

#include "resource.h"       // main symbols
#include "ShellIconHelper.h"
/////////////////////////////////////////////////////////////////////////////
// CMyServer
class ATL_NO_VTABLE CMyServer : 
	public CComObjectRootEx<CComSingleThreadModel>,
	public CComCoClass<CMyServer, &CLSID_MyServer>,
	public ISupportErrorInfo,
	public IDispatchImpl<IMyServer, &IID_IMyServer, &LIBID_SYSTEMTRAYDEMOLib>,
    public CShellIconHelper<CMyServer> // Use the shell icon helper class

{
public:
	CMyServer()
	{
	}

// This message map defines which messages you want the shell icon helper
// to receive.  In this case, we want windows timer messages and user commands.
// (User commands allow us to respond to mouse commands, such as double click,
// right click etc).
BEGIN_MSG_MAP(CMyServer )
    MESSAGE_HANDLER(WM_TIMER, OnTimer)
    MESSAGE_HANDLER(WM_USER, OnUserCommand)
END_MSG_MAP()


DECLARE_REGISTRY_RESOURCEID(IDR_MYSERVER)

DECLARE_PROTECT_FINAL_CONSTRUCT()

BEGIN_COM_MAP(CMyServer)
	COM_INTERFACE_ENTRY(IMyServer)
	COM_INTERFACE_ENTRY(IDispatch)
	COM_INTERFACE_ENTRY(ISupportErrorInfo)
END_COM_MAP()

// ISupportsErrorInfo
	STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);

// IMyServer

public:
	STDMETHOD(Visible)(/*[in]*/ VARIANT_BOOL Visible);
	STDMETHOD(Animate)(/*[in]*/ VARIANT_BOOL Animate, /*[in]*/ LONG Duration);
	STDMETHOD(SetText)(/*[in]*/ BSTR Text);
    HRESULT FinalConstruct()
    {
        m_CurrentIcon = 0;
        m_CurrentText = "Tip text";
        m_bAnimate = false;
        
        // Configure the shell, then create it by calling SetShellVisible
        SetShellTipText (std::string("Some tip text"));
        SetShellIcon (IDI_ICON4);
        SetShellVisible ();

        return S_OK;
    }

    void FinalRelease ()
    {
        // Get rid of the icon out of the system tray.
        SetShellVisible (false);
    }

    // This handler is called every time a timer windows message is received -
    // in this example, every 1 second..
    LRESULT OnTimer(UINT uMsg, WPARAM wParam,
                    LPARAM lParam, BOOL& bHandled)
    {
        WORD Icon[] = { IDI_ICON1, IDI_ICON2, IDI_ICON3, IDI_ICON4 };
	    
        // Update the icon
        SetShellIcon (Icon[m_CurrentIcon]);

        // Move onto the next icon, if we are animating.
        if (m_bAnimate == true)
        {
            if (++m_CurrentIcon > 3) m_CurrentIcon = 0;
        }

	    return 0;
    }

    // This handler is called every time there is a mouse movement.
    LRESULT OnUserCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
        if (lParam == WM_RBUTTONUP) 
        {
            // Show the popup menu.  The return code is the menu item the user
            // selected, or zero if they didn't make a choice (i.e. by clicking 
            // outside of the popup menu).
            WORD cmd = ShowPopupMenu (IDR_POPUP_MENU);
            if (cmd == ID_CODEPROJECTPOPUPMENU_ABOUT) // About menu selected?
            {
                // Show the dialog
                CSimpleDialog<IDD_ABOUT> Dlg;
                Dlg.DoModal ();
            }
		}
		return 0;
    }

    std::string m_CurrentText;
    bool m_bAnimate;

    private:
        WORD m_CurrentIcon;
};

#endif //__MYSERVER_H_

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

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


Written By
Web Developer
United Kingdom United Kingdom
I first started tinkering with a ZX81 back in 1981 and it's lovely blocky graphics, teaching myself Z80 assembler and BASIC. I come from a hardware background and electronics - I started out in embedded software for avionics but soon moved onto PC platforms.

Java and C++ are my prefered language but also dabble in VB and .NET.

I'm a team leader with Nokia developing Series 40 features - it's a cool place to work!

Comments and Discussions