La partie droite de la barre des tâches de Windows (près de lhorloge) sappelle en anglais le Tray Icon. On y trouve des icônes de programmes généralement exécutés de manière automatique au démarrage du système, et qui restent résidents.
Un programme utilisant le Tray icon est un programme comme les autres, mais il doit signaler au système quil vaut utiliser le Tray Icon pour y placer une icône.
La fonction de lAPI qui traite celà est Shell_NotifyIcon. Elle permet à lutilisateur de placer ou denlever son icône du Tray, de définir les évenements qui lintéressent (comme clic de souris)...
Le prototype de cette fonction est le suivant :
WINSHELLAPI BOOL WINAPI Shell_NotifyIcon(
DWORD dwMessage, // message identifier
PNOTIFYICONDATA pnid // pointer to structure
);
dwMessage peut prendre une des valeurs suivantes :
pnid doit pointer sur une structure NOTIFYICONDATA définit comme suit :
typedef struct _NOTIFYICONDATA { // nid
DWORD cbSize;
HWND hWnd;
UINT uID;
UINT uFlags;
UINT uCallbackMessage;
HICON hIcon;
char szTip[64];
} NOTIFYICONDATA, *PNOTIFYICONDATA;
cbSize contient la taille de la structure : sizeof(NOTIFYICONDATA)
hWnd doit contenir le Handle de la fenêtre (Form1->Handle)
uID : numéro didentification de licône (nimporte quelle valeur entière)
uFlags : signale quels sont les champs valides (combinaison binaire des flags NIF_ICON, NIF_MESSAGE,NIF_TYPE)
uCallbackMessage : Numéro du message didentification. Doit être supérieur à WM_USER.
hIcon : contient un handle sur licône à afficher dans le tray.
szTip : texte à afficher dans la bulle daide..
Nous allons construire une petite application qui pourra modifier la Tray Icon.
Pour cela il nous faut dessiner deux icônes, par exemple.
La fenêtre contient deux RadioGroupBox permettant de choisir laquelle est affichée dans le Tray Icon.
Elle contient également un CheckBox permettant dafficher ou non licône dans le Tray.
Construisons donc les fonctions de réponse aux évenements OnClick des trois boutons :
void __fastcall TForm1::CheckBox1Click(TObject *Sender)
{
NOTIFYICONDATA n;
n.cbSize = sizeof(NOTIFYICONDATA);
n.hWnd = Handle;
n.uID = 101;
if(CheckBox1->Checked)
{
// affiche dans le tray
n.uFlags = NIF_ICON|NIF_MESSAGE;
n.uCallbackMessage = WM_ICONNOTIFY;
if(RadioButton1->Checked)
n.hIcon = Image1->Picture->Icon->Handle;
else
n.hIcon = Image2->Picture->Icon->Handle;
Shell_NotifyIcon(NIM_ADD,&n);
}
else
{
// efface du tray
n.uFlags = 0;
Shell_NotifyIcon(NIM_DELETE,&n);
}
}
void __fastcall TForm1::RadioButton1Click(TObject *Sender)
{
// modifie l'icone du tray
if(CheckBox1->Checked)
{
NOTIFYICONDATA n;
n.cbSize = sizeof(NOTIFYICONDATA);
n.hWnd = Handle;
n.uID = 101;
n.uFlags = NIF_ICON;
n.hIcon = Image1->Picture->Icon->Handle;
Shell_NotifyIcon(NIM_MODIFY,&n);
}
}
la fonction de réponse au 2e RadioButton est identique, en remplaçant Image1 par Image2.
Imaginons maintenant que nous voulons traiter les messages en provenance du Tray Icon, tels que clic souris....
On a demandé à Windows, quand on ajoute licone dans le Tray, de nous prévenir par un message WM_ICONNOTIFY quand un évènement arrive sur notre icone...
Mais il nexiste pas dévènement correspondant dans la fiche. Comment capter ce message ?
De la manière suivante, en insérant dans le .h les lignes suivantes, dans la définition de la classe :
MESSAGE void __fastcall WMIconNotify(TMessage&);
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(WM_ICONNOTIFY,TMessage,WMIconNotify);
END_MESSAGE_MAP(TForm);
et la fonction WMIconNotify (qui est la réponse à un évènement sur le Tray Icon) :
MESSAGE void __fastcall TForm1::WMIconNotify(TMessage& M)
{
POINT MousePos;
switch(M.LParam) // contient le type du message
{
case WM_RBUTTONUP : // clic bouton droit
GetCursorPos(&MousePos); // position de la souris
PopupMenu1->Popup(MousePos.x,MousePos.y); // affiche le menu
break;
// .. autres case si besoin
}
}
On peut bien sûr imaginer répondre à lévènement WM_MOUSEMOVE, WM_LBUTTONDBLCLK....
Il ne reste plus quà écrire les fonctions de réponse aux items du PopupMenu.