Introduction :
Maintenant que nous savons créer une boîte de dialogue, nous allons voir comment
initialiser ses contrôles et comment restituer leur contenu à la fenêtre
qui a appelé la boîte de dialogue.
Nous continuons toujours avec le même exemple où nous ajouterons une option
au menu nommé "Paramètres...". Elle appellera une nouvelle boîte de dialogue qui
comportera un champ de saisie (EDITTEXT), un bouton "Ok" et un bouton "Annuler".
A l'ouverture de la boîte de dialogue, le champ de saisie devra être initialisé
avec le titre de la fenêtre principale. A sa fermeture, le titre de la fenêtre
principale devra être modifié si la boîte de dialogue est fermée avec le bouton "Ok".
Le script de ressources :
Le script de ressources est fort semblable à celui de la boîte de dialogue du
chapitre précédent :
DIALOG2 DIALOG
60, 60, 182, 70
STYLE WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Paramètres"
BEGIN
DEFPUSHBUTTON "OK", IDOK, 36, 42, 42, 12
PUSHBUTTON "Cancel", IDCANCEL, 96, 42, 42, 12
EDITTEXT IDE_EDIT1, 88, 15, 74, 12
LTEXT "Titre de la fenêtre", -1, 24, 18, 60, 10
END
On peut remarquer deux types de boutons "DEFPUSHBUTTON" et "PUSHBUTTON".
Le bouton qui à le type "DEFPUSHBUTTON" est le bouton par défaut.
Le contrôle d'édition "EDITTEXT" est identifié par la constante IDE_EDIT1
définie dans le fichier resource.h.
Appel de la boîte de dialogue :
Nous allons appeler la boîte de dialogue avec la fonction
DialogBoxParam. Cette fonction permet de passer un paramètre supplémentaire
de notre choix. Il pourra être récupéré dans sa procédure de fenêtre.
Dans l'exemple, nous lui passerons le handle de la fenêtre qui l'appelle.
switch (uMsg)
{
case WM_COMMAND:
if(LOWORD(wParam) == IDM_PARAM)
DialogBoxParam(hinst, "DIALOG2" , hwnd,
(DLGPROC)Dialog2Proc, (LPARAM)hwnd);
Procédure de fenêtre de la boîte de dialogue :
Récupération des données venant de la fenêtre principale :
BOOL APIENTRY Dialog2Proc(HWND hDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
static HWND hParent;
switch (uMsg)
{
case WM_INITDIALOG:
{
CHAR st[256];
hParent = (HWND)lParam;
GetWindowText(hParent, st, 256);
SetDlgItemText(hDlg, IDE_EDIT1, st);
}
return TRUE;
A la réception du message WM_INITDIALOG nous récupérons le titre de la fenêtre
qui l'a appelée avec GetWindowText. Son handle est récupéré dans la variable lParam
transmise avec WM_INITDIALOG. C'est le paramètre supplémentaire transmit par
la fonction DialogBoxParam.
Nous affectons ce titre au champ d'édition avec la fonction SetDlgItemText.
Elle reçoit comme paramètres le handle de la boîte de dialogue, puis la
constante identifiant le contrôle d'édition, puis le pointeur sur la chaîne de caractères.
Maintenant que notre boîte de dialogue est ouverte, nous pouvons modifier le
champ de saisie, puis la fermer.
Si nous la fermons avec le bouton "Ok" :
switch (uMsg)
{
case WM_COMMAND:
if (LOWORD(wParam) == IDOK )
{
CHAR st[256];
GetDlgItemText(hDlg, IDE_EDIT1, st, 256);
SetWindowText(hParent,st);
EndDialog(hDlg,0);
return TRUE;
}
Nous faisons l'opération inverse. Nous récupérons le contenu du champ
d'édition avec la fonction GetDlgItemText et nous l'affectons
à la fenêtre principale dont on avait mémorisé le handle dans la variable
hParent.
Si vous m'avez suivi jusque là, vous vous rendez compte qu'il y a plusieurs
possibilités pour transmettre les données entres fenêtres. Celle-ci n'était
peut-être pas la meilleure dans cet exemple.
On aurait pu utiliser des variables globales ou transmettre un pointeur
sur structure dans le paramètre supplémentaire de DialogBoxParam...
Styles étendus des contrôles :
Vous avez remarqué que le contrôle d'édition dans notre boîte de dialogue
a un aspect 3D et pas celui qui ce trouve sur la fenêtre principale.
Pour donner un aspect 3D à un contrôle qui se trouve sur une fenêtre
qui n'est pas une boîte de dialogue, il faut lui donner le style étendu
WS_EX_CLIENTEDGE. Pour cela il faut créer le contrôle avec la fonction
CreateWindowEx. Les styles étendus sont donnés dans le premier
paramètre de CreateWindowEx. Les autres paramètres de cette fonction
sont les mêmes que ceux de CreateWindow.
hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, "edit", "Texte",
WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_WANTRETURN | WS_VSCROLL,
0, 0, 0, 0, hwnd, NULL, hinst, NULL);
Code complet :
resource.h :
#define IDM_QUIT 1
#define IDM_NEW 2
#define IDM_ABOUT 3
#define IDM_PARAM 4
#define IDE_EDIT1 101
resource.rc :
#include <windows.h>
#include "resource.h"
1 ICON icone.ico
2 ICON autre.ico
LEMENU MENU
BEGIN
POPUP "Fichier"
BEGIN
MENUITEM "Nouveau", IDM_NEW
MENUITEM "Paramètres...", IDM_PARAM
MENUITEM SEPARATOR
MENUITEM "Quitter", IDM_QUIT
END
POPUP "Aide"
BEGIN
MENUITEM "A propos...", IDM_ABOUT
END
END
DIALOG2 DIALOG
60, 60, 182, 70
STYLE WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Paramètres"
BEGIN
DEFPUSHBUTTON "OK", IDOK, 36, 42, 42, 12
PUSHBUTTON "Cancel", IDCANCEL, 96, 42, 42, 12
EDITTEXT IDE_EDIT1, 88, 15, 74, 12
LTEXT "Titre de la fenêtre", -1, 24, 18, 60, 10
END
DIALOG1 DIALOG
60, 60, 160, 80
STYLE WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "A propos"
BEGIN
DEFPUSHBUTTON "Ok", IDOK, 56, 50, 42, 12
ICON 2, -1, 20, 15, 32, 32
LTEXT "Mon beau programme !", -1, 60, 18, 80, 10
END
winmain.c :
#include <windows.h>
#include "resource.h"
HINSTANCE hinst;
LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);
BOOL APIENTRY Dialog1Proc(HWND, UINT, WPARAM, LPARAM);
BOOL APIENTRY Dialog2Proc(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(hinstance,MAKEINTRESOURCE(2));
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = "LEMENU";
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);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
/******************************************************************************/
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static HWND hEdit;
static BOOL EditNotChg = TRUE;
switch (uMsg)
{
case WM_CREATE:
{
HFONT hFont;
hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, "edit", "Texte",
WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_WANTRETURN | WS_VSCROLL,
0, 0, 0, 0, hwnd, NULL, hinst, NULL);
hFont = (HFONT)GetStockObject(ANSI_FIXED_FONT);
SendMessage(hEdit,WM_SETFONT,(UINT)hFont,TRUE);
SendMessage(hEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN,
MAKELONG(5, 5));
return 0;
}
case WM_CLOSE:
if(EditNotChg ||
MessageBox(hwnd,"Le texte a été modifié.\r\nEtes vous sûr de \
vouloir fermer l'application ?"
,"Question ?",MB_YESNO | MB_ICONQUESTION ) == IDYES)
DestroyWindow(hwnd);
return 0;
case WM_COMMAND:
if(LOWORD(wParam) == IDM_QUIT) PostMessage(hwnd, WM_CLOSE,0,0);
if(LOWORD(wParam) == IDM_NEW)
if(EditNotChg ||
MessageBox(hwnd,"Le texte a été modifié.\r\nEtes vous sûr de \
vouloir fermer votre travail ?"
,"Question ?",MB_YESNO | MB_ICONQUESTION ) == IDYES)
{
SendMessage(hEdit,WM_SETTEXT,0,(LPARAM)"");
EditNotChg = TRUE;
}
if(LOWORD(wParam) == IDM_ABOUT)
DialogBox(hinst, "DIALOG1" , hwnd, (DLGPROC)Dialog1Proc);
if(LOWORD(wParam) == IDM_PARAM)
DialogBoxParam(hinst, "DIALOG2" , hwnd,
(DLGPROC)Dialog2Proc, (LPARAM)hwnd);
if(HIWORD(wParam) == EN_CHANGE) EditNotChg = FALSE;
return 0;
case WM_SIZE:
MoveWindow(hEdit, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
}
/******************************************************************************/
BOOL APIENTRY Dialog1Proc(HWND hDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
switch (uMsg)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDCANCEL || LOWORD(wParam) == IDOK)
{
EndDialog(hDlg,0);
return TRUE;
}
default:
return FALSE;
}
}
/******************************************************************************/
BOOL APIENTRY Dialog2Proc(HWND hDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
static HWND hParent;
switch (uMsg)
{
case WM_INITDIALOG:
{
CHAR st[256];
hParent = (HWND)lParam;
GetWindowText(hParent, st, 256);
SetDlgItemText(hDlg, IDE_EDIT1, st);
}
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK )
{
CHAR st[256];
GetDlgItemText(hDlg, IDE_EDIT1, st, 256);
SetWindowText(hParent,st);
EndDialog(hDlg,0);
return TRUE;
}
if (LOWORD(wParam) == IDCANCEL )
{
EndDialog(hDlg,0);
return TRUE;
}
default:
return FALSE;
}
}
J'ai testé les compilations avec C++ Builder et DevC++.
Voici un exemple semblable avec le contrôle case à cocher :
Le contrôle CheckBox ou case à cocher.
A vos PC.
CGi
Avec la contribution de pharaonix pour la relecture.
|