Jump to content
  • Advertisement
Sign in to follow this  
slippnslide

Minimizing to tray

This topic is 4416 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I was wondering if anybody had any tutorials on how to make a Win32 application and have it minimize to the system tray. All the examples I've found require MFC, so they don't work. So, if somebody knew where to get that, that would work just as well. But if not, I need an alternative, preferably with the Win32 API. I've tried MSDN, but I'm new to Win32 stuff, so it doesn't make much sense to me.

Share this post


Link to post
Share on other sites
Advertisement
Check this article on codeproject : http://www.codeproject.com/wtl/wtltrayicon.asp.
it is for WTL though.

Share this post


Link to post
Share on other sites
Quote:
Original post by meeshoo
Check this article on codeproject : http://www.codeproject.com/wtl/wtltrayicon.asp.
it is for WTL though.

Well, I'm trying to get WTL working now, so I'll see how it goes. Thanks.

Share this post


Link to post
Share on other sites
What happens is that you use Shell_NotifyIcon() to show/hide the tray icon, and then you use ShowWindow() to show/hide the main window in response to the minimize/maximize messages.

Share this post


Link to post
Share on other sites
no problem. I've used that article in one of my applications and it works, just need some tweeking to get it to your specific needs.

Share this post


Link to post
Share on other sites
Aw heck - I'll just give you my tray class - it's a little dirty, but works.

Header:


#ifndef SystemTrayH
#define SystemTrayH

#define WM_SYSTRAY (WM_APP + 100)

#include <Windows.h>
#include <ShellAPI.h>
#include <vector>

class TTrayIcon
{
private:
HWND parent;
std::vector<HICON>icons;
std::vector<char*>tips;
std::vector<UINT>state_ids;
int state;
UINT id;
UINT callback;

char Tip[128];

//if this flag is set to true (by default), certain
//messages are handled and not passed on to the main
//message loop of the owner window to be handled
//there manually. These include:
//
// WM_DRAWITEM
//
bool InterceptMessages;

NOTIFYICONDATA nid;

UINT GetState(UINT i);
void CreateNID(UINT state);

public:
TTrayIcon();
virtual ~TTrayIcon();

TTrayIcon(HWND trayParent, UINT trayId, bool intercept = true);

void AddState(HICON trayIcon, char * trayTip, const int trayState);
void Draw(LPARAM lParam);
void SetState(UINT i);
void Enable();
void Disable();
void SetCallbackMessage(UINT msg);
void SetInterceptMessages(bool intercept);
bool GetInterceptMessages();
void SetTip(char * Tip);
};

#endif



Source:


#include "SystemTray.h"

UINT TTrayIcon::GetState(UINT i)
{
for(unsigned j = 0; j < state_ids.size(); j++)
if(state_ids[j] == i)
return j;
return NULL;
}

void TTrayIcon::CreateNID(UINT state)
{
nid.cbSize = sizeof(NOTIFYICONDATA);
nid.hWnd = parent;
nid.uID = id;
nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
nid.uCallbackMessage = callback;
nid.hIcon = icons[state];

if(!strlen(Tip) && tips[state])
lstrcpyn(nid.szTip, tips[state], sizeof(nid.szTip));
else if(strlen(Tip))
lstrcpyn(nid.szTip, Tip, sizeof(nid.szTip));
else
nid.szTip[0] = '\0';
}

TTrayIcon::TTrayIcon() {};
TTrayIcon::~TTrayIcon() {};

TTrayIcon::TTrayIcon(HWND trayParent, UINT trayId, bool intercept)
{
parent = trayParent;
state = 0;
id = trayId;
callback = WM_SYSTRAY;
InterceptMessages = intercept;
Tip[0] ='\0';
}

void TTrayIcon::AddState(HICON trayIcon, char * trayTip, const int trayState)
{
if(trayState < 0)
return;

icons.push_back(trayIcon);
tips.push_back(trayTip);
state_ids.push_back(trayState);
}

void TTrayIcon::SetTip(char * pTip)
{
strcpy(Tip, pTip);

CreateNID(state);

Shell_NotifyIcon(NIM_MODIFY, &nid);
}


void TTrayIcon::Draw(LPARAM lParam)
{
DrawIconEx(LPDRAWITEMSTRUCT(lParam)->hDC,
LPDRAWITEMSTRUCT(lParam)->rcItem.left,
LPDRAWITEMSTRUCT(lParam)->rcItem.top,
icons[state], 16, 16, 0, NULL, DI_NORMAL);
}

void TTrayIcon::SetState(UINT i)
{
state = GetState(i);
CreateNID(state);
Shell_NotifyIcon(NIM_MODIFY, &nid);
}

void TTrayIcon::Enable()
{
SetState(state_ids[state]);
Shell_NotifyIcon(NIM_ADD, &nid);
}

void TTrayIcon::Disable()
{
Shell_NotifyIcon(NIM_DELETE, &nid);
}

void TTrayIcon::SetCallbackMessage(UINT msg)
{
callback = msg;
}

void TTrayIcon::SetInterceptMessages(bool intercept)
{
InterceptMessages = intercept;
}

bool TTrayIcon::GetInterceptMessages()
{
return InterceptMessages;
}





Sample usage:



//the id (12) is really not used internally, so you can essentially ignore it
tray = new TTrayIcon(handle_of_owner, 12);

//add an icon and text for state 0;
//you can use any icon, either loaded from disk or resource;
//in this example a default windows icon is loaded
tray->AddState(LoadIcon(NULL, IDI_EXCLAMATION), "idle...", 0);
//ditto for state 1
tray->AddState(LoadIcon(NULL, IDI_ERROR), "working...", 1);
//tray->Enable();
//set state 0
tray->SetState(0);


//in owner window's message loop

if(msg == WM_SYSTRAY)
{
if(lParam == WM_LBUTTONDOWN)
{
tray->Disable();
}
else if(lParam == WM_MOUSEMOVE)
{
expressUtterSorrow(true);
}
else
tray->SetTip("Click to disable");
}




This doesn't compass all of the functionality of the tray icon, but it will give you easy access to it.

Hope you find it useful.

Share this post


Link to post
Share on other sites
After reading MSDN, I've got it to display a custom icon all the time and it removes it on the program's exit, so I have everything working good there. However, I'm really stumped again on what I thought would be a simple solution.

I figured I could just use GetMessage to check if the minimize button was pressed, then just hide the window. But, apparantly I'm either completely missing something on MSDN or it's not as easy as I expected. I scoured CodeProject and found even more examples with tray icons, but none of them make it clear on how it's done and the fact that they use MFC along with huge classes doesn't help. So, once again, I would appreciate any links, tips, or help.

Thanks in advance.

Share this post


Link to post
Share on other sites
Quote:
Original post by slippnslide
After reading MSDN, I've got it to display a custom icon all the time and it removes it on the program's exit, so I have everything working good there. However, I'm really stumped again on what I thought would be a simple solution.

I figured I could just use GetMessage to check if the minimize button was pressed, then just hide the window. But, apparantly I'm either completely missing something on MSDN or it's not as easy as I expected. I scoured CodeProject and found even more examples with tray icons, but none of them make it clear on how it's done and the fact that they use MFC along with huge classes doesn't help. So, once again, I would appreciate any links, tips, or help.

Thanks in advance.


Look at the source I posted - it has everything you need!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!