GIDForums  

Go Back   GIDForums > Computer Programming Forums > C++ Forum
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

 
 
Thread Tools Search this Thread Rating: Thread Rating: 7 votes, 5.00 average.
  #1  
Old 12-May-2005, 12:54
Thomas555 Thomas555 is offline
New Member
 
Join Date: May 2005
Posts: 4
Thomas555 is on a distinguished road
Unhappy

How to minimize a application to the system tray?


im wondering could anyone tell me how to minimize my app to the system tray im using borland c++ builder if you can can you also explain how to when a right click is pressed a menu comes up from the icon in the system tray.
  #2  
Old 12-May-2005, 14:44
ubergeek ubergeek is offline
Regular Member
 
Join Date: Jan 2005
Posts: 775
ubergeek is a jewel in the roughubergeek is a jewel in the roughubergeek is a jewel in the rough
OK, this is a very good question and I will try to give a full answer, as I have done this a couple of times with my own applications.

I don't know about Borland C++ Builder, but my explanation will work in Dev-C++ at least and comes pretty much directly from MSDN so should be univeresal C/C++ code.

Ok, first of all you need to know when the user wants you to minimize to the tray. This is usually done by a menu item or button or whatever. I assume if you are at this stage you know how to do this, but if not reply and I'll give a general overview of that.

So, pretend at the point in your program we are concerned with, you know that the user wants you to minimize to the tray. The following psuedocode would presumably be in an event handler, or a function called from one.
Code:
variables: hwnd: variable of type HWND specifying your application's main window. ID_MINTRAYICON: #defined unique constant, probably in your header file. IDI_ICON: another #defined constant. This identifies an icon resource. MSG_MINTRAYICON: yet another unique #define. define it as (WM_USER+x) where x is a number that has never been used in this context before. The reason for this is that this is to be a window message, so it must be unique from all other WM_* messages. Placing it above WM_USER guarantees this. nid: NOTIFYICONDATA struct. contains information necessary for the system tray function. Step 0. Set up necessary structures for system tray icon stuff. Step 1. Add your icon to the tray. Step 2. Hide your application's window.

Now for some real code.

Step 1. Set up necessary structures.
CPP / C++ / C Code:
//assuming variables as above.
ZeroMemory(&nid, sizeof(NOTIFYICONDATA)); //intialize struct to 0.
nid.cbSize = sizeof(NOTIFYICONDATA); //this helps the OS determine stuff. (I have no idea, but it is necessary.
nid.hWnd = hwnd; //the hWnd and uID members allow the OS to uniquely identify your icon. One window (the hWnd) can have more than one icon, as long as they have unique uIDs.
nid.uFlags = //some flags that determine the tray's behavior:
NIF_ICON //we're adding an icon
| NIF_MESSAGE //we want the tray to send a message to the window identified by hWnd when something happens to our icon (see uCallbackMesage member below).
| NIF_TIP; //our icon has a tooltip.
nid.uCallbackMessage = MSG_MINTRAYICON; //this message must be handled in hwnd's window procedure. more info below.
nid.hIcon = (HICON)LoadImage( //load up the icon:
GetModuleHandle(NULL), //get the HINSTANCE to this program
MAKEINTRESOURCE(IDI_ICON), //grab the icon out of our resource file
IMAGE_ICON, //tells the versatile LoadImage function that we are loading an icon
16, 16, //x and y values. we want a 16x16-pixel icon for the tray.
0); //no flags necessary. these flags specify special behavior, such as loading the icon from a file instead of a resource. see source list below for MSDN docs on LoadImage.
strcpy(nid.szTip, "My very own system tray icon!"); //this string cannot be longer than 64 characters including the NULL terminator (which is added by default to string literals).
//There are some more members of the NOTIFYICONDATA struct that are for advanced features we aren't using. See sources below for MSDN docs if you want to use balloon tips (only Win2000/XP).
Step 1.
OK, got our struct all set up. Now to actually call the function to add our icon to the tray. Did I say "function"? As in, singular? Yup, there is only ONE function to interface with the system tray. it takes two parameters: A flag that tells it what to do, and a pointer to a NOTIFYICONDATA struct.
CPP / C++ / C Code:
Shell_NotifyIcon(NIM_ADD, &nid); //NIM_ADD=add an icon to the tray. Then I pass a pointer to the struct that we set up above. You should error-check this function (it returns a BOOL) but I didn't since this is just an example.
.
That was easy! Now to hide our window.
Step 2.
There are two ways to do this. You can go the easy, simple, and proven route:
CPP / C++ / C Code:
ShowWindow(hwnd, SW_HIDE);
This certainly works fine. However, there is that nice visual effect with the titlebar moving down to the taskbar that the shell does when doing regular minimizing. How can you mimic that? Simple. Use the DrawAnimatedRects function. You'll have to get the RECT of your titlebar, and the RECT of the system tray. Your titlebar's RECT can be obtained easily with the GetTitleBarInfo() function. It won't be so easy to find the tray's. You'll need to find the tray window with the FindWindow() function (the shell window always has a classname of "Shell_TrayWnd" and then call GetWindowRect(). Note that you still have to use ShowWindow to hide your window at the end. Watch.
CPP / C++ / C Code:
RECT myTitlebarRect = { 0, 0, 0, 0};  //initialize both RECT structure to 0, just in case.
RECT trayWindowRect = { 0, 0, 0, 0};

TITLEBARINFO tbi = { 0 }; //helper structure for GetTitleBarInfo()
GetTitleBarInfo(hwnd, &tbi);
myTitlebarRect = tbi.rcTitleBar; //transfer RECT structure. You don't have to do this, but I did for clarity.

HWND hTray = NULL; //just in case.
hTray = FindWindow("Shell_TrayWnd", NULL); //find the window with the classname "Shell_TrayWnd".
if (hTray != NULL) //if we found something. if not, this code will be skipped and the window will appear to minimize to the top left corner of the screen. Not optimal, but still pretty cool.
{
GetWindowRect(hTray, &trayWindowRect);
}

//Now comes the magic function.
DrawAnimatedRects( //draw some animated rectangles!
hwnd, //needs a window to find title and stuff
IDANI_CAPTION, //what kind of animation. I don't know what the purpose of this is, because this is only flag you can pass.
&myTitlebarRect, //animate from our window's titlebar...
&trayWindowRect); //...to the tray window.

ShowWindow(hwnd, SW_HIDE); //and finish it off.
Congrats! You've now minimized your app to the tray.

But we're not done. How do you know stuff about the icon, such as when it is clicked? That's where uCallbackMessage comes in. Here's a snippet from hwnd's window procedure:
CPP / C++ / C Code:
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) //or whatever function name.
{
switch (msg)
{
...
case MSG_MINTRAYICON: //aha! something happened, and the tray has dutifully notified us of the event. WPARAM is the uID member of nid, and LPARAM is one of the Window mouse messages (such as WM_LBUTTONUP).
if (wParam != ID_MINTRAYICON) break; //if it's not the icon we planted, then go away.
{

if (lParam == WM_LBUTTONUP) //the mouse button has been released. It's time to re-maximize our window. This is basically done using the reverse of the minimizing process. MAKE SURE you look for WM_LBUTTONUP and not WM_LBUTTONDOWN. Most tray icons handle the release, so if your icon disappears on mousedown, the next icon will get notified of a mouseup. This is not what you want to happen.
{
//Here you can repeat the same magic with DrawAnimatedRects as before. Just call FindWindow and GetWindowRect for the tray, and GetTitleBarInfo() for your window again (it's still there, just invisible). Basically, follow the exact same process given above, except switch the order of the last two parameters of DrawAnimatedRects (the pointers to the RECTS) so that the animation goes in reverse.
NOTIFYICONDATA nid = { 0 };
nid.cbSize = sizeof(NOTIFYICONDATA);
nid.hWnd = hwnd;
nid.uID = ID_MINTRAYICON;
Shell_NotifyIcon(NIM_DELETE, &nid); //the OS only needs the hwnd and id number to know which icon to delete.
ShowWindow(hwnd, SW_SHOW);
}

else if (lParam == WM_RBUTTONUP) //time to display a menu.
{
HMENU myMenu = NULL;
myMenu = CreatePopupMenu(); //create our menu. You'll want to error-check this, because if it fails the next few functions may produce segmentation faults, and your menu won't work.

//IDM_TRAYEXIT, IDM_TRAYABOUT, and IDM_TRAYHELP are #defined constants.
AppendMenu(myMenu, MF_STRING, IDM_TRAYEXIT, "Exit");
AppendMenu(myMenu, MF_STRING, IDM_TRAYHELP, "Help");
AppendMenu(myMenu, MF_STRING, IDM_TRAYABOUT, "About");

DWORD mp = GetMessagePos(); //get the position of the mouse at the time the icon was clicked (or, at least, the time this message was generated).

SetForegroundWindow(hwnd); //even though the window is hidden, we must set it to the foreground window because of popup-menu peculiarities. See the Remarks section of the MSDN page for TrackPopupMenu.
TrackPopupMenu(myMenu, 0, GET_X_LPARAM(mp), GET_Y_LPARAM(mp), 0, hwnd, NULL); //display the menu. you MUST #include <windowsx.h> to use those two macros.
SendMessage(hwnd, WM_NULL, 0, 0); //send benign message to window to make sure the menu goes away.
}
} //end case handler
...
} //end switch
...
}
And then, of course, you have to write a WM_COMMAND handler that checks for IDM_TRAYEXIT, IDM_TRAYABOUT, and IDM_TRAYHELP.

One more thing: Like all things Microsoft, Explorer and therefore the system tray crash once every so often. Then the tray icons disappear. This is rather annoying. to replace your icon in the tray when Explorer restarts, do
CPP / C++ / C Code:
const UINT WM_TASKBARCREATED = RegisterWindowMessage(TEXT("TaskbarCreated"));
then write a handler for it that re-adds your icon to the tray. Explorer broadcasts this message to all top-level windows in the system as soon as the taskbar is ready.


Sources:

MSDN page on NOTIFYICONDATA:
http://msdn.microsoft.com/library/de...fyicondata.asp

MSDN page on DrawAnimatedRects:
http://msdn.microsoft.com/library/de...tdraw_6qnn.asp

"Secrets of the System Tray" (told me the classname to use in FindWindow and about TaskbarCreated):
http://www.cs.kent.edu/~kschaffe/sdn...s/systray.html

MSDN page on CreatePopupMenu:
http://msdn.microsoft.com/library/de...epopupmenu.asp

MSDN page on AppendMenu:
http://msdn.microsoft.com/library/de...epopupmenu.asp

MSDN page on GetMessagePos:
http://msdn.microsoft.com/library/de...messagepos.asp

MSDN page on TrackPopupMenu:
http://msdn.microsoft.com/library/de...epopupmenu.asp
  #3  
Old 13-May-2005, 01:01
Thomas555 Thomas555 is offline
New Member
 
Join Date: May 2005
Posts: 4
Thomas555 is on a distinguished road
Angry

it almost compiles but i get 4 errors:

[C++ Error] Unit1.cpp(271): E2451 Undefined symbol 'nid'
[C++ Error] Unit1.cpp(273): E2451 Undefined symbol 'hwnd'
[C++ Error] Unit1.cpp(27: E2451 Undefined symbol 'MSG_MINTRAYICON'
[C++ Error] Unit1.cpp(281): E2451 Undefined symbol 'IDI_ICON'

how and were should i define these.
  #4  
Old 13-May-2005, 05:17
ubergeek ubergeek is offline
Regular Member
 
Join Date: Jan 2005
Posts: 775
ubergeek is a jewel in the roughubergeek is a jewel in the roughubergeek is a jewel in the rough
nid:
Define this locally in Step 1:
CPP / C++ / C Code:
NOTIFYICONDATA nid = { 0 };

hwnd:
Presumable Step 1 is encapsulated in a function. That function needs to be passed a parameter called hwnd, of type HWND. This will identify your app's window. This will be easy if it is called from the window procedure.

MSG_MINTRAYICON:
CPP / C++ / C Code:
//in your header file
#define MSG_MINTRAYICON (WM_USER+1)

IDI_ICON:
CPP / C++ / C Code:
//in your header file
#define IDI_ICON 5 //must be a unique number


//in your resource file (remove this line, no comments allowed in resource)
IDI_ICON ICON "myappicon.ico"
^^or whatever filename (remove this line, it won't compile)
  #5  
Old 13-May-2005, 12:07
Thomas555 Thomas555 is offline
New Member
 
Join Date: May 2005
Posts: 4
Thomas555 is on a distinguished road
i still get 3 probs.

[C++ Error] Unit1.cpp(271): E2451 Undefined symbol 'nid'
[C++ Error] Unit1.cpp(273): E2451 Undefined symbol 'hwnd'
[C++ Error] Unit1.cpp(287): E2238 Multiple declaration for 'nid'
  #6  
Old 13-May-2005, 19:27
ubergeek ubergeek is offline
Regular Member
 
Join Date: Jan 2005
Posts: 775
ubergeek is a jewel in the roughubergeek is a jewel in the roughubergeek is a jewel in the rough
i posted my code in chunks. post some complete functions, and we can see what is wrong. if your code is not too long, go ahead and post all of it.
  #7  
Old 17-May-2005, 09:01
Thomas555 Thomas555 is offline
New Member
 
Join Date: May 2005
Posts: 4
Thomas555 is on a distinguished road
here is all of the problems with the part of code that there in

[C++ Error] Unit1.cpp(271): E2451 Undefined symbol 'nid'

CPP / C++ / C Code:
ZeroMemory(&nid, sizeof(NOTIFYICONDATA));

[C++ Error] Unit1.cpp(273): E2451 Undefined symbol 'hwnd'

CPP / C++ / C Code:
nid.hWnd = hwnd;

[C++ Error] Unit1.cpp(314): E2451 Undefined symbol 'msg'

CPP / C++ / C Code:
switch (msg)


[C++ Error] Unit1.cpp(321): E2451 Undefined symbol 'Wparam'

CPP / C++ / C Code:
if (wParam != ID_MINTRAYICON) break;

[C++ Error] Unit1.cpp(327): E2451 Undefined symbol 'ID_MINTRAYICON'
CPP / C++ / C Code:
nid.uID = ID_MINTRAYICON;

[C++ Error] Unit1.cpp(33: E2451 Undefined symbol 'IDM_TRAYEXIT'

CPP / C++ / C Code:
AppendMenu(myMenu, MF_STRING, IDM_TRAYEXIT, "Exit");

[C++ Error] Unit1.cpp(339): E2451 Undefined symbol 'IDM_TRAYHELP'

CPP / C++ / C Code:
AppendMenu(myMenu, MF_STRING, IDM_TRAYHELP, "Help");

[C++ Error] Unit1.cpp(340): E2451 Undefined symbol 'IDM_TRAYABOUT'

CPP / C++ / C Code:
AppendMenu(myMenu, MF_STRING, IDM_TRAYABOUT, "About");

[C++ Error] Unit1.cpp(345): E2268 Call to undefined function 'GET_X_LPARAM'

CPP / C++ / C Code:
TrackPopupMenu(myMenu, 0, GET_X_LPARAM(mp), GET_Y_LPARAM(mp), 0, hwnd, NULL);

[C++ Error] Unit1.cpp(345): E2268 Call to undefined function 'GET_Y_LPARAM'

CPP / C++ / C Code:
TrackPopupMenu(myMenu, 0, GET_X_LPARAM(mp), GET_Y_LPARAM(mp), 0, hwnd, NULL);



[C++ Warning] Unit1.cpp(354): W8004 'WM_TASKBARCREATED' is assigned a value that is never used
CPP / C++ / C Code:
const UINT WM_TASKBARCREATED = RegisterWindowMessage(TEXT("TaskbarCreated"));
}
  #8  
Old 17-May-2005, 15:37
ubergeek ubergeek is offline
Regular Member
 
Join Date: Jan 2005
Posts: 775
ubergeek is a jewel in the roughubergeek is a jewel in the roughubergeek is a jewel in the rough
for GET_X_LPARAM and GET_Y_LPARAM, #include <windowsx.h> along with the standard <windows.h>. For the last warning, it is never used because I didn't say anything about implementing it. You will probably want to put that in a header file somewhere, and then in your window procedure, handle the WM_TASKBARCREATED message. In that handler, you will want to call the function that adds your tray icons. As for the nid and hwnd variables, I would still need to see more code. However, I can try. If all this is in a function (called MinimizeToTray or whatever), declare NOTIFYICONDATA nid; at the beginning of the function. HWND hwnd will have to be passed as a parameter (it is the handle to your main window). About wParam: if that code is in your window procedure, as it should be, change "wParam" to whatever you named the WPARAM window procedure parameter.
  #9  
Old 20-May-2005, 02:10
MaPa2701 MaPa2701 is offline
New Member
 
Join Date: May 2005
Posts: 3
MaPa2701 is on a distinguished road
Dear ubergeek,

can you create a small example programm and send the source code to my email adress? (mapa@marcus-2000.de)
Because i have problems to understand your instructions!!!!

(Sorry my english is not very good)

Bye Marcus
  #10  
Old 20-May-2005, 06:37
ubergeek ubergeek is offline
Regular Member
 
Join Date: Jan 2005
Posts: 775
ubergeek is a jewel in the roughubergeek is a jewel in the roughubergeek is a jewel in the rough
sure, why not. i'll just post here instead of emailing so that other people can learn from it too. here is the source:

CPP / C++ / C Code:
// tray.cpp

#include "tray.h"

/*  Declare Windows procedure  */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

/*  Make the class name into a global variable  */
char szClassName[ ] = "TrayMinimizerClass__";

int WINAPI WinMain (HINSTANCE hThisInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpszArgument,
                    int nFunsterStil)

{
    HWND hwnd;               /* This is the handle for our window */
    MSG messages;            /* Here messages to the application are saved */
    WNDCLASSEX wincl;        /* Data structure for the windowclass */

    /* The Window structure */
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
    wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
    wincl.cbSize = sizeof (WNDCLASSEX);

    /* Use default icon and mouse-pointer */
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;                 /* No menu */
    wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
    wincl.cbWndExtra = 0;                      /* structure or the window instance */
    /* Use Windows's default color as the background of the window */
    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;

    /* Register the window class, and if it fails quit the program */
    if (!RegisterClassEx (&wincl))
        return 0;

    /* The class is registered, let's create the program*/
    hwnd = CreateWindowEx (
           0,                   /* Extended possibilites for variation */
           szClassName,         /* Classname */
           "Minimize to Tray Example",       /* Title Text */
           WS_OVERLAPPEDWINDOW, /* default window */
           CW_USEDEFAULT,       /* Windows decides the position */
           CW_USEDEFAULT,       /* where the window ends up on the screen */
           544,                 /* The programs width */
           375,                 /* and height in pixels */
           HWND_DESKTOP,        /* The window is a child-window to desktop */
           NULL,                /* No menu */
           hThisInstance,       /* Program Instance handler */
           NULL                 /* No Window Creation data */
           );

    /* Make the window visible on the screen */
    ShowWindow (hwnd, nFunsterStil);

    /* Run the message loop. It will run until GetMessage() returns 0 */
    while (GetMessage (&messages, NULL, 0, 0))
    {
        /* Translate virtual-key messages into character messages */
        TranslateMessage(&messages);
        /* Send message to WindowProcedure */
        DispatchMessage(&messages);
    }

    /* The program return-value is 0 - The value that PostQuitMessage() gave */
    return messages.wParam;
}


/*  This function is called by the Windows function DispatchMessage()  */

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    if ( (message == TASKBARCREATED) && (minimized) ) //have to do this out here because it won't let me use TASKBARCREATED in a case statement (something about not allowed to use it in a constant-expression)
    {
        minimize(hwnd);
        return 0;
    }
    
    switch (message)                  /* handle the messages */
    {
        case WM_CREATE:
            CreateWindowEx(0, "BUTTON", "Click to minimize to tray", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | BS_TEXT | BS_CENTER | BS_VCENTER, 200, 50, 300, 25, hwnd, (HMENU)IDC_MINIMIZE, GetModuleHandle(NULL), NULL);
            break;
        case WM_COMMAND:
            if ( (HIWORD(wParam) == BN_CLICKED) && (LOWORD(wParam) == IDC_MINIMIZE) )
            {
                if (minimized) restore(hwnd);
                else minimize(hwnd);
            }
            break;
        case MSG_MINTRAYICON:
        {
            if (wParam != IDI_TRAYICON) break; //if it's not the icon we planted, then go away
            if (lParam == WM_LBUTTONUP) //the mouse button has been released. It's time to re-maximize our window. This is basically done using the reverse of the minimizing process. MAKE SURE you look for WM_LBUTTONUP and not WM_LBUTTONDOWN. Most tray icons handle the release, so if your icon disappears on mousedown, the next icon will get notified of a mouseup. This is not what you want to happen.
            {
                restore(hwnd);
            }
            
            else if (lParam == WM_RBUTTONUP) //time to display a menu.
            {
                HMENU myMenu = NULL;
                myMenu = CreatePopupMenu(); //create our menu. You'll want to error-check this, because if it fails the next few functions may produce segmentation faults, and your menu won't work.
                
                //IDM_TRAYEXIT, IDM_TRAYABOUT, and IDM_TRAYHELP are #defined constants.
                AppendMenu(myMenu, MF_STRING, IDM_TRAYEXIT, "Exit");
                AppendMenu(myMenu, MF_STRING, IDM_TRAYHELP, "Help");
                AppendMenu(myMenu, MF_STRING, IDM_TRAYABOUT, "About");
                
                DWORD mp = GetMessagePos(); //get the position of the mouse at the time the icon was clicked (or, at least, the time this message was generated).
                
                SetForegroundWindow(hwnd); //even though the window is hidden, we must set it to the foreground window because of popup-menu peculiarities. See the Remarks section of the MSDN page for TrackPopupMenu.
                UINT clicked = TrackPopupMenu(myMenu, TPM_RETURNCMD | TPM_NONOTIFY /*don't send me WM_COMMAND messages about this window, instead return the identifier of the clicked menu item*/, GET_X_LPARAM(mp), GET_Y_LPARAM(mp), 0, hwnd, NULL); //display the menu. you MUST #include <windowsx.h> to use those two macros.
                SendMessage(hwnd, WM_NULL, 0, 0); //send benign message to window to make sure the menu goes away.
                if (clicked == IDM_TRAYEXIT) SendMessage(hwnd, WM_DESTROY, 0, 0);
                else if (clicked == IDM_TRAYHELP) MessageBox(hwnd, "Click the button to minimize to the system tray.", "Tray Example Help", MB_OK | MB_ICONINFORMATION);
                else if (clicked == IDM_TRAYABOUT) MessageBox(hwnd, "Tray Example: Demonstrates minimizing a window to the tray.", "About Tray Example", MB_OK | MB_ICONINFORMATION);
            }
        }
            break;
        case WM_DESTROY:
            PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
            break;
        default:                      /* for messages that we don't deal with */
            return DefWindowProc (hwnd, message, wParam, lParam);
    }

    return 0;
}

void minimize(HWND hwnd)
{
    NOTIFYICONDATA nid = { 0 };
    nid.cbSize = sizeof(NOTIFYICONDATA); //this helps the OS determine stuff. (I have no idea, but it is necessary.
    nid.hWnd = hwnd; //the hWnd and uID members allow the OS to uniquely identify your icon. One window (the hWnd) can have more than one icon, as long as they have unique uIDs.
    nid.uID = IDI_TRAYICON; //sorry, had forgotten this in my original example. but without, the function probably wouldn't work
    nid.uFlags = //some flags that determine the tray's behavior:
        NIF_ICON //we're adding an icon
        | NIF_MESSAGE //we want the tray to send a message to the window identified by hWnd when something happens to our icon (see uCallbackMesage member below).
        | NIF_TIP; //our icon has a tooltip.
    nid.uCallbackMessage = MSG_MINTRAYICON; //this message must be handled in hwnd's window procedure. more info below.
    nid.hIcon = (HICON)LoadImage( //load up the icon:
        GetModuleHandle(NULL), //get the HINSTANCE to this program
        MAKEINTRESOURCE(IDI_ICON), //grab the icon out of our resource file
        IMAGE_ICON, //tells the versatile LoadImage function that we are loading an icon
        16, 16, //x and y values. we want a 16x16-pixel icon for the tray.
        0); //no flags necessary. these flags specify special behavior, such as loading the icon from a file instead of a resource. see source list below for MSDN docs on LoadImage.
    strcpy(nid.szTip, "My very own system tray icon!"); //this string cannot be longer than 64 characters including the NULL terminator (which is added by default to string literals).
    //There are some more members of the NOTIFYICONDATA struct that are for advanced features we aren't using. See sources below for MSDN docs if you want to use balloon tips (only Win2000/XP).
    Shell_NotifyIcon(NIM_ADD, &nid);
    ShowWindow(hwnd, SW_HIDE);
    minimized = true;
}

void restore(HWND hwnd)
{
    NOTIFYICONDATA nid = { 0 };
    nid.cbSize = sizeof(NOTIFYICONDATA);
    nid.hWnd = hwnd;
    nid.uID = IDI_TRAYICON;
    Shell_NotifyIcon(NIM_DELETE, &nid);
    ShowWindow(hwnd, SW_SHOW);
    minimized = false;
}


CPP / C++ / C Code:
//tray.h

#ifndef _TRAY_H_ //inclusion guard
#define _TRAY_H_


#include <windows.h>
#include <windowsx.h>
#include <shellapi.h>

#ifndef RC_INVOKED //variable definitions and function prototypes just confuse the resource compiler

void minimize(HWND hwnd);
void restore(HWND hwnd);

bool minimized = false;
const int TASKBARCREATED = RegisterWindowMessage("TaskbarCreated");

#endif // 8: #ifndef RC_INVOKED

#define IDI_ICON        0
#define IDC_MINIMIZE    1
#define IDI_TRAYICON    2
#define IDM_TRAYEXIT    3
#define IDM_TRAYHELP    4
#define IDM_TRAYABOUT   5
#define MSG_MINTRAYICON (WM_USER+0)


#endif // 1: #ifndef _TRAY_H_


CPP / C++ / C Code:
#include "tray.h"

IDI_ICON ICON "tray.ico"


And there you have it--Tray Example.

NB: I don't know Borland, so you'll have to use tray.rc however one uses resource files in Borland--perhaps through the IDE somehow, or with a #pragma
 
 

Recent GIDBlogProblems with the Navy (Enlisted) by crystalattice

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
gcc-grouping instructions of diff. types for application bravetanveer C++ Forum 1 25-Mar-2005 09:01
Help! Some basal questions about MFC xutingnjupt MS Visual C++ / MFC Forum 1 05-Dec-2004 03:38
Track change in system time Poolan C++ Forum 3 19-Nov-2004 04:08
i = system ("cd c:\text"); :( kyle C Programming Language 1 25-Aug-2003 11:43
PHP doc system - for when you need to write up some documentation jrobbio MySQL / PHP Forum 0 22-May-2003 08:43

Network Sites: GIDNetwork · GIDWebHosts · GIDSearch · Learning Journal by J de Silva, The

All times are GMT -6. The time now is 18:05.


vBulletin, Copyright © 2000 - 2010, Jelsoft Enterprises Ltd.