I. Introduction▲
Avec cette application minimum, nous allons voir comment mettre une icône dans la barre des tâches (à côté de l'horloge). Et comment faire surgir un menu quand on fait un clic droit sur cette icône. Son fonctionnement sera le suivant : L'application s'ouvre normalement, puis si on clique sur le bouton de fermeture de la fenêtre, la fenêtre devient invisible et l'icône apparait dans la barre des tâches. Pour fermer l'application, il faudra cliquer sur le menu « Quitter » qui apparait au clic droit sur l'icône. Pour la restaurer, il faudra soit faire un simple clic gauche sur l'icône soit utiliser le menu avec l'option « Restaurer ».
II. Description sommaire▲
Pour faire apparaitre l'icône il faut remplir une structure de type NOTIFYICONDATA ensuite il faut appeler la fonction Shell_NotifyIcon avec comme paramètres la constante NIM_ADD et l'adresse de la variable de type NOTIFYICONDATA.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
NOTIFYICONDATA TrayIcon;
ZeroMemory
(&
TrayIcon, sizeof
(
NOTIFYICONDATA));
TrayIcon.cbSize =
sizeof
(
NOTIFYICONDATA);
TrayIcon.hWnd =
hwnd;
TrayIcon.uID =
0
;
TrayIcon.hIcon =
LoadIcon
(
NULL
, IDI_WINLOGO);
TrayIcon.uCallbackMessage =
MY_WM_NOTIFYICON;
TrayIcon.uFlags =
NIF_ICON |
NIF_MESSAGE |
NIF_TIP;
strcpy
(
TrayIcon.szTip, "
Test TrayIcon
"
);
Shell_NotifyIcon
(
NIM_ADD,&
TrayIcon);
La structure NOTIFYICONDATA a un champ nommé uCallbackMessage qui doit être rempli avec un identificateur de message que l'on doit créer nous-mêmes.
#define MY_WM_NOTIFYICON WM_USER+1
Nous traiterons ce message dans la procédure de fenêtre comme n'importe quel autre message. Dans l'exemple ce sera le clic gauche pour faire réapparaître la fenêtre et le clic droit pour faire surgir le menu. La suppression de l'icône se fait aussi avec la fonction Shell_NotifyIcon.
III. Code complet▲
III-A. resources.h▲
2.
#define IDM_QUIT 1
#define IDM_RESTORE 2
III-B. resources.rc▲
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
#include <windows.h>
#include "resources.h"
LEMENU MENU
BEGIN
POPUP "
TrayMenu
"
BEGIN
MENUITEM "
Restorer
"
, IDM_RESTORE
MENUITEM SEPARATOR
MENUITEM "
Quitter
"
, IDM_QUIT
END
END
III-C. winmain.c▲
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
#include <windows.h>
#include "resources.h"
#define MY_WM_NOTIFYICON WM_USER+1
NOTIFYICONDATA TrayIcon;
HINSTANCE hinst;
LRESULT CALLBACK MainWndProc
(
HWND, UINT, WPARAM, LPARAM);
int
WINAPI WinMain
(
HINSTANCE hinstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int
nCmdShow)
{
HWND hwnd;
MSG msg;
WNDCLASS wc;
hinst =
hinstance;
wc.style =
0
;
wc.lpfnWndProc =
MainWndProc;
wc.cbClsExtra =
0
;
wc.cbWndExtra =
0
;
wc.hInstance =
hinstance;
wc.hIcon =
LoadIcon
(
NULL
, IDI_APPLICATION);
wc.hCursor =
LoadCursor
(
NULL
, IDC_ARROW);
wc.hbrBackground =
(
HBRUSH)(
1
+
COLOR_BTNFACE);
wc.lpszMenuName =
NULL
;
wc.lpszClassName =
"
MaWinClass
"
;
if
(!
RegisterClass
(&
wc)) return
FALSE;
hwnd =
CreateWindow
(
"
MaWinClass
"
, "
Titre
"
, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 400
, 300
,
NULL
, NULL
, hinstance, NULL
);
if
(!
hwnd) return
FALSE;
ShowWindow
(
hwnd, nCmdShow);
UpdateWindow
(
hwnd);
while
(
GetMessage
(&
msg, NULL
, 0
, 0
))
{
TranslateMessage
(&
msg);
DispatchMessage
(&
msg);
}
return
msg.wParam;
}
/**
*************************************************************************
*/
LRESULT CALLBACK MainWndProc
(
HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch
(
uMsg)
{
case
WM_CREATE:
return
0
;
case
WM_CLOSE:
ShowWindow
(
hwnd,SW_HIDE);
TrayIcon.cbSize =
sizeof
(
NOTIFYICONDATA );
TrayIcon.hWnd =
hwnd;
TrayIcon.uID =
0
;
TrayIcon.hIcon =
LoadIcon
(
NULL
, IDI_WINLOGO);
TrayIcon.uCallbackMessage =
MY_WM_NOTIFYICON;
TrayIcon.uFlags =
NIF_ICON |
NIF_MESSAGE |
NIF_TIP;
strcpy
(
TrayIcon.szTip, "
Test trayicon
"
);
Shell_NotifyIcon
(
NIM_ADD,&
TrayIcon);
return
0
;
case
MY_WM_NOTIFYICON :
if
(
lParam ==
WM_LBUTTONUP)
{
ShowWindow
(
hwnd,SW_SHOW);
Shell_NotifyIcon
(
NIM_DELETE,&
TrayIcon);
}
if
(
lParam ==
WM_RBUTTONUP)
{
HMENU hmenu;
HMENU hpopup;
POINT pos;
GetCursorPos
(&
pos);
hmenu =
LoadMenu
(
hinst,"
LEMENU
"
);
hpopup =
GetSubMenu
(
hmenu, 0
);
SetForegroundWindow
(
hwnd);
TrackPopupMenuEx
(
hpopup, 0
, pos.x, pos.y, hwnd, NULL
);
DestroyMenu
(
hmenu);
}
return
0
;
case
WM_COMMAND:
if
(
LOWORD
(
wParam) ==
IDM_QUIT) DestroyWindow
(
hwnd);
if
(
LOWORD
(
wParam) ==
IDM_RESTORE)
{
ShowWindow
(
hwnd,SW_SHOW);
Shell_NotifyIcon
(
NIM_DELETE,&
TrayIcon);
}
return
0
;
case
WM_DESTROY:
Shell_NotifyIcon
(
NIM_DELETE,&
TrayIcon);
PostQuitMessage
(
0
);
return
0
;
default
:
return
DefWindowProc
(
hwnd, uMsg, wParam, lParam);
}
}
J'ai testé les compilations avec C++ Builder et DevC++.
À vos PC.