Les boîtes de dialogue.
Nous étudierons ici un exemple qui calcule la distance entre 2 points du plan.
Présentation de l'application.
L'objectif de cette application est d'avoir à l'écran les coordonnées de 2 points A et B dans des champs texte éditables. Deux boutons "Modifier A" et "Modifier B" permettent d'éditer les coordonnées des 2 boutons dans une boîte de dialogue modale.
Structuration en classe de l'application.
Notre application distance comportera 4 classes : la classe DistanceAppli qui représente notre application et qui hérite de wxApp, la classe DistanceWin qui héritera de wxframe et qui sera notre principale fenêtre, la classe Point qui permet de représenter un point et qui calcule la distance entre 2 points et la classe PointDialog qui permet d'éditer les coordonnées d'un point dans un boîte de dialogue. 
Pour chacune de ces classes nous allons créer un fichier .h et un fichier .cpp. Nous aurons donc 8 fichiers au total : 
La classe DistanceAppli.
Rien de nouveau par rapport aux leçons précédentes. La classe DistanceAppli ouvre une fenêtre de la classe DistanceWin. Le fichier DistanceAppli.h est le suivant :
class DistanceAppli : public wxApp
public:
 bool OnInit();
protected:
 DistanceWin * window;
DECLARE_APP(DistanceAppli)
Le fichier DistanceAppli.cpp est le suivant : 
IMPLEMENT_APP(DistanceAppli)
bool DistanceAppli::OnInit()
 window=new DistanceWin();
 window->Show(TRUE);
 SetTopWindow(window);
 return true;
La classe DistanceWin.
La fenêtre de notre application est composée d'un wxPanel sur lequel on positionne du texte (classe wxStaticText), des champs texte (classe wxTextCtrl) qui seront rendus inéditables et des boutons (classe wxButton). 
Cette classe comporte comme données membres deux points A et B (de la classe Point) et une méthode nommée ShowPoint(). Cette méthode va récupérer les coordonnées des 2 points A et B (grâce à des accesseurs getX() et getY()) ainsi que la distance entre les 2 points grâce à la méthode distance(..). Une fois ces informations récupérées, elles seront transformées en wxString et affichées dans les différents champs texte de la fenêtre.
Cette classe comportera également 2 autres méthodes editPointA et editPointB qui seront appelée lorsqu'on cliquera respectivement sur les boutons "MODIFIER A" et "MODIFIER B". Pour créer cette association, il faut écrire la macro DECLARE_EVENT_TABLE() dans le fichier DistanceWin.h à la fin de la déclaration de la classe DistanceWin . 
Dans le fichier DistanceWin.cpp, il faut écrire :
BEGIN_EVENT_TABLE(DistanceWin,wxFrame)
EVT_BUTTON(BUTTONEDITA_ID,DistanceWin::editPointA)
EVT_BUTTON(BUTTONEDITB_ID,DistanceWin::editPointB)
END_EVENT_TABLE()
Les paramètres BUTTONEDITA_ID et BUTTONEDITB_ID sont des identifiants des 2 boutons issus d'un type énuméré. Lorsqu'on appelle les méthodes editPointA et editPointB, il faut créer une nouvelle boîte de dialogue de la classe PointDialog en passant au constructeur de cette classe le nom et l'instance du point à éditer. Il faut ouvrir cette boîte de dialog en appelant la méthode ShowModal(). Lorsque la boîte de dialogue se referme, il faut mettre à jour les coordonnées des points et la distance en appelant la méthode ShwPoint(). 
Le fichier DistanceWin.h est le suivant :
enum
 BUTTONEDITA_ID ,BUTTONEDITB_ID
class DistanceWin : public wxFrame
public:
 DistanceWin();
protected:
 wxPanel * panel;
 wxStaticText *textXA,*textXB,*textYA,*textYB,*textDistance;
 wxTextCtrl *editXA,*editXB,*editYA,*editYB,*editDistance;
 wxButton *editA,*editB;
 Point A,B;
 void ShowPoint();
 void editPointA(wxCommandEvent &event);
 void editPointB(wxCommandEvent &event);
 DECLARE_EVENT_TABLE()
Le fichier DistanceWin.cpp est le suivant :
DistanceWin::DistanceWin()
 : wxFrame(NULL,-1,"Distance",wxPoint(10,10),wxSize(400,300))
 panel= new wxPanel(this);
 textXA=new wxStaticText(panel,-1,"Abscisse de A : ",wxPoint(10,20),wxSize(100,20));
 textYA=new wxStaticText(panel,-1,"Ordonnée de A : ",wxPoint(10,50),wxSize(100,20));
 textXB=new wxStaticText(panel,-1,"Abscisse de B : ",wxPoint(10,90),wxSize(100,20));
 textYB=new wxStaticText(panel,-1,"Ordonnée de B : ",wxPoint(10,120),wxSize(100,20));
 textDistance=new wxStaticText(panel,-1,"La distance AB : ",wxPoint(10,180),wxSize(200,20));
 editXA=new wxTextCtrl(panel,-1,"",wxPoint(120,20),wxSize(100,20));
 editXA->SetEditable(false);
 editXA->SetBackgroundColour(wxColour(200,200,200));
 editYA=new wxTextCtrl(panel,-1,"",wxPoint(120,50),wxSize(100,20));
 editYA->SetEditable(false);
 editYA->SetBackgroundColour(wxColour(200,200,200));
 editXB=new wxTextCtrl(panel,-1,"",wxPoint(120,90),wxSize(100,20));
 editXB->SetEditable(false);
 editXB->SetBackgroundColour(wxColour(200,200,200));
 editYB=new wxTextCtrl(panel,-1,"",wxPoint(120,120),wxSize(100,20));
 editYB->SetEditable(false);
 editYB->SetBackgroundColour(wxColour(200,200,200));
 editDistance=new wxTextCtrl(panel,-1,"",wxPoint(120,180),wxSize(100,20));
 editDistance->SetEditable(false);
 editDistance->SetBackgroundColour(wxColour(200,200,200));
 editA=new wxButton(panel,BUTTONEDITA_ID,"MODIFIER A",wxPoint(240,35));
 editB=new wxButton(panel,BUTTONEDITB_ID,"MODIFIER B",wxPoint(240,105));
 ShowPoint();
void DistanceWin::editPointA(wxCommandEvent &event)
 PointDialog *dialog=new PointDialog(this,"Modification du Point A",A);
 dialog->ShowModal();
 ShowPoint();
void DistanceWin::editPointB(wxCommandEvent &event)
 PointDialog *dialog=new PointDialog(this,"Modification du Point B",B);
 dialog->ShowModal();
 ShowPoint();
void DistanceWin::ShowPoint()
 wxString s;
 s.sprintf("%lf",A.getX());
 editXA->SetValue(s);
 s.sprintf("%lf",A.getY());
 editYA->SetValue(s);
 s.sprintf("%lf",B.getX());
 editXB->SetValue(s);
 s.sprintf("%lf",B.getY());
 editYB->SetValue(s);
 s.sprintf("%lf",A.distance(B));
 editDistance->SetValue(s);
BEGIN_EVENT_TABLE(DistanceWin,wxFrame)
 EVT_BUTTON(BUTTONEDITA_ID,DistanceWin::editPointA)
 EVT_BUTTON(BUTTONEDITB_ID,DistanceWin::editPointB)
END_EVENT_TABLE()
La classe Point.
La classe Point comportera 2 données membres privées x et y qui représentent les coordonnées du point, un constructeur qui initialise à 0 les coordonnées des points, 2 accesseurs getX() et getY() et 1 mutateur setXY(int x, int y). Elle possède également une méthode distance pour calculer la distance entre 2 points. 
Le fichier Point.h est le suivant : 
class Point
public:
 Point();
 double getX();
 double getY();
 void setXY(double x, double y);
 double distance(const Point &P);
private:
 double x,y;
Le fichier Point.cpp est le suivant : 
Point::Point():x(0),y(0)
void Point::setXY(double x, double y)
 this->x=x;
 this->y=y;
double Point::distance(const Point &P)
 double dx,dy;
 dx=x-P.x;
 dy=y-P.y;
 return sqrt(dx*dx+dy*dy);
La classe PointDialog.
La classe PointDialog est une boîte de dialogue modale qui permet d'éditer les coordonnées d'un point. Elle hérite à ce titre de la classe prédéfinie wxDialog. 
La boîte est modale, c'est-à-dire que lorsqu'on l'ouvre, l'application est bloquée jusqu'à ce qu'on la ferme en cliquant sur le bouton OK ou Annuler. 
Le constructeur de la boîte de dialogue aura 3 paramètres : 
Le constructeur de PointDialog appelle le constructeur de wxDialog. Ce dernier a besoin des informations suivantes : 
Ce constructeur va dans un premier temps créer les différents composants graphiques : des wxStaticText, des champs texte éditables de la classe wxTextCtrl et les boutons OK et Annuler qui auront des identifiants prédéfinis : respectivement wxID_OK et wxID_CANCEL.
Une fois ces composants graphiques positionnés, on affichera les coordonnées du point passé par référence en appelant la méthode ShowPoint(). Cette méthode récupérera les coordonnées du point en appelant les accesseurs, transformera ces données en chaînes de caractères et affichera ces chaînes dans les champs texte correspondant.
Lorsqu'on cliquera sur le bouton Annuler, ce bouton ayant l'identifiant wxID_CANCEL, la boîte de dialogue sera tout simplement fermée.
Lorsqu'on cliquera sur le bouton OK, ce bouton ayant l'identifiant wxID_OK, alors on appellera automatiquement la méthode virtuelle bool Validate(). Si cette méthode renvoie true, alors la boîte de dialogue sera fermée, sinon elle restera ouverte. Nous redéfinissons la méthode Validate dans notre classe PointDialog : cette méthode récupère les chaînes saisies pour l'abscisse et l'ordonnée du point. Elle essaye ensuite de transformer ces chaînes en double en appelant la méthode ToDouble sur la classe wxString. Si les 2 coordonnées sont correctes, alors on modifiera les coordonnées du point (passé par référence) en appelant le mutateur setXY(...). Dans le cas contraire, un message d'erreur sera affiché en appelant la fonction wxMessageBox("Les données ne sont pas valides","ERREUR");. 
Le fichier PointDialog.h est le suivant : 
class PointDialog : public wxDialog
public:
 PointDialog(wxWindow * parent,wxString titre, Point &P);
private:
 Point &P;
 wxStaticText *textX,*textY;
 wxTextCtrl *editX,*editY;
 wxButton *OK,*Cancel;
 void ShowPoint();
 bool Validate();
Le fichier PointDialog.cpp est le suivant : 
PointDialog::PointDialog(wxWindow * parent,wxString titre, Point &P):
 wxDialog(parent,-1,titre,wxPoint(500,100),wxSize(400,200)),P(P)
 textX=new wxStaticText(this,-1,"Abscisse du point : ",wxPoint(10,20),wxSize(100,20));
 textY=new wxStaticText(this,-1,"Ordonnée du point : ",wxPoint(10,50),wxSize(100,20));
 editX=new wxTextCtrl(this,-1,"",wxPoint(120,20),wxSize(100,20));
 editY=new wxTextCtrl(this,-1,"",wxPoint(120,50),wxSize(100,20));
 OK=new wxButton(this,wxID_OK,"OK",wxPoint(260,20));
 Cancel=new wxButton(this,wxID_CANCEL,"Annuler",wxPoint(260,50));
 ShowPoint();
void PointDialog::ShowPoint()
 wxString s;
 s.sprintf("%lf",P.getX());
 editX->SetValue(s);
 s.sprintf("%lf",P.getY());
 editY->SetValue(s);
bool PointDialog::Validate()
 double x,y;
 bool okx,oky,ok;
 wxString s;
 s=editX->GetValue();
 okx=s.ToDouble(&x);
 s=editY->GetValue();
 oky=s.ToDouble(&y);
 ok=okx && oky;
 if(ok) P.setXY(x,y);
 else wxMessageBox("Les données ne sont pas valides","ERREUR");
 return ok;