Partie V : Apprendre à manipuler les boîtes de dialogues standards

CGi

Les boîtes de dialogues standards.

Dans cette cinquième partie de cette série de tutoriels, vous allez apprendre à manipuler avec la bibliothèque wxWidgets.

Un espace de dialogue vous est proposé sur le forum. N'hésitez pas à apporter vos commentaires sur le lien ci-dessous, si vous avez des remarques concernant ce tutoriel. ♪

Commentez

- Titre : Partie V : Apprendre à manipuler les boîtes de dialogues standards

- Auteur : CGi

- Parution : 7 juin 2004

- Mise à jour : 14 octobre 2016

- Licence : Copyright ® 2016 CGi. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. Introduction

- II. Les boîtes de dialogue de fichiers

- III. La boîte de dialogue de choix de police de caractères

- IV. La boîte de dialogue de choix de couleurs

- V. Les Messages Box

- VI. Précisions sur le code de l'exemple

- VII. Code source complet

- VII-A. wxwin.h

- VII-B. wxwin.cpp

- VII-C. Remarques sur ce document

I - Introduction

Dans ce chapitre nous allons voir l'appel des boîtes de dialogues standards, c'est-à-dire celles : d'ouverture de fichiers, de sauvegarde de fichiers, de sélections de polices de caractères, de sélections de couleurs et les messages box de prises de décisions.

L'exemple que nous utiliserons dans ce document sera un mini éditeur de texte, tel celui de la copie d'écran ci-dessous. Nous pourrons y ouvrir un fichier texte, le sauvegarder sous un nom de notre choix. Nous pourrons aussi changer la couleur de fond du contrôle d'édition ainsi que sa police de caractère et sa couleur de texte. Si le texte a été modifié et qu'il n'a pas été sauvegardé une boîte de messages nous donnera le choix entre réellement quitter ou non l'application lors de sa demande de fermeture.

L'application sera construite sur une wxFrame munie de menus comme dans le chapitre 2. Elle comportera un unique contrôle d'édition multiligne, instancié depuis la classe wxTextCtrl. Sa police de caractères sera initialisée avec une police à pas fixe (deuxième paramètre du constructeur de la police à wxMODERN).

1. mlTextCtrl = new wxTextCtrl(this,TextEdit,"",wxDefaultPosition,wxDefaultSize,

2. wxHSCROLL  | wxTE_MULTILINE );

3. mlTextCtrl->SetFont(wxFont(11, wxMODERN, wxNORMAL, wxNORMAL));

Le fait que le contrôle soit seul sur la fiche a pour conséquence qu'il s'étend sur toute la zone client de la fiche.

II - Les boîtes de dialogue de fichiers

Les boîtes de dialogues d'ouverture ou de sauvegarde de fichiers seront appellées depuis les commandes de menus « Ouvrir… » et « Enregister sous… ». Pour leur appel nous utilisons une fonction nommée wxFileSelector. Le premier paramètre de cette fonction est le titre de la boîte de dialogue, le 2e le dossier par défaut, le 3e le nom du fichier par défaut, le 5e est une chaîne de caractères de sélection de types de fichiers : Une sélection s'écrit, avec le nom du type de fichiers, suivie d'une barre verticale, suivie de ou des extensions séparées par des points virgules. D'autres sélections de types de fichiers peuvent être ajoutées en les séparant de barres verticales comme le type 'resources files' dans l'exemple, elles seront accessibles depuis la ComboBox « Type de fichiers » des boîtes de dialogues. Son 6e paramètre est un entier qui renseigne si elle est : une boîte d'ouverture de fichier 'wxOPEN' ou de sauvegarde de fichiers 'wxSAVE'.

1. void Frame::OnOuvrir(wxCommandEvent& WXUNUSED(event))

2. {

3. wxString nomfichier = wxFileSelector("Ouvrir" ,"" ,"" ,"",

4. "cpp files (*.cpp;*.h)|*.h;*.cpp|resources files (*.rc)|*.rc",wxOPEN);

5. if (!nomfichier.empty())

6. {

7. mlTextCtrl->LoadFile(nomfichier);

8. TextChg = false;

9. }

10. }

11. //------------------------------------------------------------------------------

12. void Frame::OnEnregistrer(wxCommandEvent& WXUNUSED(event))

13. {

14. wxString nomfichier = wxFileSelector("Enregistrer" ,"" ,"" ,"",

15. "cpp files (*.cpp;*.h)|*.h;*.cpp|resources files (*.rc)|*.rc",wxSAVE);

16. if (!nomfichier.empty())

17. {

18. mlTextCtrl->SaveFile(nomfichier);

19. TextChg = false;

20. }

21. }

Ces fonctions renvoient une chaîne de caractères désignant le fichier sélectionné si elles sont fermées par « Ouvrir » pour les boîtes de dialogues d'ouverture de fichiers ou par « Enregistrer » pour celles d'enregistrement. Dans tous les autres cas, elles renvoient une chaîne vide.
Dans cet exemple nous avons appelé ces boîtes de dialogues avec des fonctions de la bibliothèque. Il faut savoir que cela peut aussi ce faire avec une classe nommée wxFileDialog (voir aide).

III - La boîte de dialogue de choix de police de caractères

Nous appellerons cette boîte de dialogue depuis le menu : « Options » -> « Polices » à l'aide de la classe wxFontDialog prévue à cet effet. À savoir que là aussi il existe une fonction pour son appel : wxGetFontFromUser (voir aide).

Avant d'appeler la boîte de dialogue, nous initialiserons un objet nommé dfont de type wxFontData avec la police actuelle du contrôle d'édition ainsi qu'avec sa couleur de texte à l'aide des méthodes SetInitialFont et SetColour de la classe wxFontData. Le constructeur de la boîte de dialogue recevant en paramètre un pointeur sur l'objet de type wxFontData afin de l'initialiser avec les données de l'objet dfont. La boîte de dialogue est appelée par sa méthode ShowModal dont nous utiliserons la valeur de retour, nous indiquant comment elle a été fermée. Si cette valeur retourne 'wxID_OK' nous affectons les nouvelles valeurs au contrôle d'édition, à savoir sa police et sa couleur qui sont retournées dans un objet de type wxFontData dont nous récupérons les valeurs à l'aide des méthodes GetChosenFont et GetColour. On termine par l'appel de la méthode Refresh du contrôle d'édition pour actualiser l'affichage.

1. void Frame::OnPolice(wxCommandEvent& WXUNUSED(event))

2. {

3. wxFontData dfont;

4. dfont.SetInitialFont(mlTextCtrl->GetFont());

5. dfont.SetColour(mlTextCtrl->GetForegroundColour());

6. wxFontDialog FontDlg(this, &dfont);

7. if (FontDlg.ShowModal() == wxID_OK)

8. {

9. mlTextCtrl->SetFont(FontDlg.GetFontData().GetChosenFont());

10. mlTextCtrl->SetForegroundColour(FontDlg.GetFontData().GetColour());

11. mlTextCtrl->Refresh();

12. }

13. }

IV - La boîte de dialogue de choix de couleurs

Nous l'appelons depuis le menu : « Option » -> « Couleur du fond » avec la fonction wxGetColourFromUser de la bibliothèque, là aussi il existe une classe faisant la même chose. C'est la plus simple d'utilisation, dans l'exemple nous l'initialisons avec la couleur de fond du contrôle d'édition, nullement besoin de faire de test, car elle renvoie cette couleur si elle est fermée par le bouton « Annuler ». Nous affecterons ensuite la couleur de fond du contrôle d'édition avec sa valeur de retour.

1. void Frame::OnCouleur(wxCommandEvent& WXUNUSED(event))

2. {

3. wxColour NewColor = wxGetColourFromUser(this,

4. mlTextCtrl->GetBackgroundColour());

5. mlTextCtrl->SetBackgroundColour(NewColor);

6. mlTextCtrl->Refresh();

7. }

Les fonctions ou classes pour l'appel des boîtes de dialogues de choix de couleurs et de police de caractère nécessitent l'inclusion de leur fichier en-tête respectif.

1. #include "wx/fontdlg.h"

2. #include "wx/colordlg.h"

V - Les Messages Box

Voyons tout d'abord la message box simple avec un bouton « OK », accessible dans l'exemple par : le menu « aide », option de menu « À propos ». Nous en avions vu une dans le chapitre précédent qui était construite à partir d'une classe (wxMessageDialog), celle-ci l'est avec la fonction wxMessageBox.

1. void Frame::OnAPropos(wxCommandEvent& WXUNUSED(event))

2. {

3. wxMessageBox("Programme de démonstration de wxWidgets.","A propos !");

4. }

Voyons maintenant une message box de prise de décision, dans l'exemple elle comportera deux boutons « Oui » et « Non » et nous l'utiliserons à la fermeture de l'application pour nous laisser le choix entre réellement fermer ou non l'application.

1. void Frame::OnClose(wxCloseEvent& event)

2. {

3. if (TextChg == true)

4. {

5. if (wxMessageBox(

6. "Êtes-vous sûr de vouloir quitter sans sauvegarder votre travail ?",

7. "Attention !",wxYES_NO ) == wxYES) event.Skip();

8. }

9. else event.Skip();

10. }

VI - Précisions sur le code de l'exemple

Vous vous demandez peut-être ce qu'est la donnée membre 'TextChg', c'est elle qui nous indique si le texte du contrôle d'édition a changé ou non. Elle est mise à jour dans la méthode 'OnTextUpdate' :

1. void Frame::OnTextUpdate(wxCommandEvent& WXUNUSED(event))

2. {

3. if (TextChg == false)  TextChg = true;

4. }

Cette méthode est appelée suite à un événement du contrôle d'édition. Voir son appel dans la table d'événements (macro EVT_TEXT). Par ailleurs la méthode OnClose suit le même principe et est appelée suite à une demande de fermeture de la fenêtre principale.

1. BEGIN_EVENT_TABLE(Frame, wxFrame)

2. //...

3. EVT_TEXT(TextEdit, Frame::OnTextUpdate)

4. EVT_CLOSE(Frame::OnClose)

5. END_EVENT_TABLE()

Dans la méthode OnClose vous avez sans doute remarqué l'appel de la méthode Skip de l'événement. Elle permet l'exécution du code par défaut de l'événement, à savoir dans ce cas la fermeture de l'application.

Dans l'exemple j'ai aussi mis une message box de prise de décision quand on crée un nouveau document vide, je ne l'ai pas mis sur l'ouverture d'un nouveau fichier pour ne pas trop charger l'exemple, mais il va de soi que le test serait là aussi nécessaire.

VII - Code source complet

VII-A - wxwin.h

1. #ifndef wxWinH

2. #define wxWinH

4. class Application : public wxApp

5. {

6. public:

7. virtual bool OnInit();

8. };

9. //------------------------------------------------------------------------------

11. class Frame : public wxFrame

12. {

13. public:

14. Frame(const wxString& title, const wxPoint& pos, const wxSize& size,

15. long style = wxDEFAULT_FRAME_STYLE);

16. private:

17. bool TextChg;

18. wxTextCtrl *mlTextCtrl;

19. void OnQuit(wxCommandEvent& event);

20. void OnNouveau(wxCommandEvent& event);

21. void OnOuvrir(wxCommandEvent& event);

22. void OnEnregistrer(wxCommandEvent& event);

23. void OnPolice(wxCommandEvent& event);

24. void OnCouleur(wxCommandEvent& event);

25. void OnAPropos(wxCommandEvent& event);

26. void OnTextUpdate(wxCommandEvent& event);

27. void OnClose(wxCloseEvent& event);

28. enum

29. {

30. App_Quit = 1,

31. Nouveau,

32. Ouvrir,

33. Enregister,

34. Police,

35. Couleur,

36. APropos,

37. TextEdit

38. };

40. DECLARE_EVENT_TABLE()

41. };

42. //------------------------------------------------------------------------------

44. #endif //wxWinH

VII-B - wxwin.cpp

1. #include "wx/wxprec.h"

2. #include "wx/fontdlg.h"

3. #include "wx/colordlg.h"

5. #ifdef __BORLANDC__

6. #pragma hdrstop

7. #endif

9. #ifndef WX_PRECOMP

10. #include "wx/wx.h"

11. #endif

12. //------------------------------------------------------------------------------

13. #include "wxWin.h"

15. BEGIN_EVENT_TABLE(Frame, wxFrame)

16. EVT_MENU(App_Quit,  Frame::OnQuit)

17. EVT_MENU(Nouveau, Frame::OnNouveau)

18. EVT_MENU(Ouvrir, Frame::OnOuvrir)

19. EVT_MENU(Enregister, Frame::OnEnregistrer)

20. EVT_MENU(Police, Frame::OnPolice)

21. EVT_MENU(Couleur, Frame::OnCouleur)

22. EVT_MENU(APropos, Frame::OnAPropos)

23. EVT_TEXT(TextEdit, Frame::OnTextUpdate)

24. EVT_CLOSE(Frame::OnClose)

25. END_EVENT_TABLE()

27. IMPLEMENT_APP(Application)

29. bool Application::OnInit()

30. {

31. Frame *frame = new Frame("Frame", wxPoint(150, 150), wxSize(480, 360));

32. frame->Show();

33. return true;

34. }

35. //------------------------------------------------------------------------------

36. Frame::Frame(const wxString& title, const wxPoint& pos, const wxSize& size,

37. long style) : wxFrame(NULL, -1, title, pos, size, style)

38. {

39. SetIcon(wxICON(monicone));

40. SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));

41. TextChg = false;

43. wxMenu *menuFichier = new wxMenu;

44. menuFichier->Append(Nouveau,"Nouveau");

45. menuFichier->Append(Ouvrir,"Ouvrir...");

46. menuFichier->Append(Enregister,"Enregister sous...");

47. menuFichier->AppendSeparator();

48. menuFichier->Append(App_Quit,"Quitter l'application");

49. wxMenu *menuOption = new wxMenu;

50. menuOption->Append(Police,"Police");

51. menuOption->Append(Couleur,"Couleur du fond");

52. wxMenu *menuAide = new wxMenu;

53. menuAide->Append(APropos,"A Propos !");

54. wxMenuBar *menuBarre = new wxMenuBar();

55. menuBarre->Append(menuFichier,("Fichier"));

56. menuBarre->Append(menuOption,("Options"));

57. menuBarre->Append(menuAide,("Aide"));

58. SetMenuBar(menuBarre);

59. mlTextCtrl = new wxTextCtrl(this,TextEdit,"",wxDefaultPosition,wxDefaultSize,

60. wxHSCROLL  | wxTE_MULTILINE );

61. mlTextCtrl->SetFont(wxFont(11, wxMODERN, wxNORMAL, wxNORMAL));

62. }

63. //------------------------------------------------------------------------------

64. void Frame::OnQuit(wxCommandEvent& WXUNUSED(event))

65. {

66. Close();

67. }

68. //------------------------------------------------------------------------------

69. void Frame::OnNouveau(wxCommandEvent& WXUNUSED(event))

70. {

71. if (TextChg == true)

72. {

73. if (wxMessageBox("Êtes-vous sûr de vouloir créer un nouveau\n\

74. fichier sans sauvegarder votre travail ?","Attention !",wxYES_NO ) == wxYES)

75. {

76. mlTextCtrl->Clear();

77. TextChg = false;

78. }

79. }

80. else mlTextCtrl->Clear();

81. }

82. //------------------------------------------------------------------------------

83. void Frame::OnOuvrir(wxCommandEvent& WXUNUSED(event))

84. {

85. wxString nomfichier = wxFileSelector("Ouvrir" ,"" ,"" ,"",

86. "cpp files (*.cpp;*.h)|*.h;*.cpp|resources files (*.rc)|*.rc",wxOPEN);

87. if (!nomfichier.empty())

88. {

89. mlTextCtrl->LoadFile(nomfichier);

90. TextChg = false;

91. }

92. }

93. //------------------------------------------------------------------------------

94. void Frame::OnEnregistrer(wxCommandEvent& WXUNUSED(event))

95. {

96. wxString nomfichier = wxFileSelector("Enregistrer" ,"" ,"" ,"",

97. "cpp files (*.cpp;*.h)|*.h;*.cpp|resources files (*.rc)|*.rc",wxSAVE);

98. if (!nomfichier.empty())

99. {

100. mlTextCtrl->SaveFile(nomfichier);

101. TextChg = false;

102. }

103. }

104. //------------------------------------------------------------------------------

105. void Frame::OnPolice(wxCommandEvent& WXUNUSED(event))

106. {

107. wxFontData dfont;

108. dfont.SetInitialFont(mlTextCtrl->GetFont());

109. dfont.SetColour(mlTextCtrl->GetForegroundColour());

110. wxFontDialog FontDlg(this, &dfont);

111. if (FontDlg.ShowModal() == wxID_OK)

112. {

113. mlTextCtrl->SetFont(FontDlg.GetFontData().GetChosenFont());

114. mlTextCtrl->SetForegroundColour(FontDlg.GetFontData().GetColour());

115. mlTextCtrl->Refresh();

116. }

117. }

118. //------------------------------------------------------------------------------

119. void Frame::OnCouleur(wxCommandEvent& WXUNUSED(event))

120. {

121. wxColour NewColor = wxGetColourFromUser(this,

122. mlTextCtrl->GetBackgroundColour());

123. mlTextCtrl->SetBackgroundColour(NewColor);

124. mlTextCtrl->Refresh();

125. }

126. //------------------------------------------------------------------------------

127. void Frame::OnAPropos(wxCommandEvent& WXUNUSED(event))

128. {

129. wxMessageBox("Programme de démonstration de wxWidgets.","A propos !");

130. }

131. //------------------------------------------------------------------------------

132. void Frame::OnTextUpdate(wxCommandEvent& WXUNUSED(event))

133. {

134. if (TextChg == false)  TextChg = true;

135. }

136. //------------------------------------------------------------------------------

137. void Frame::OnClose(wxCloseEvent& event)

138. {

139. if (TextChg == true)

140. {

141. if (wxMessageBox(

142. "Êtes-vous sûr de vouloir quitter sans sauvegarder votre travail ?",

143. "Attention !",wxYES_NO ) == wxYES) event.Skip();

144. }

145. else event.Skip();

146. }

147. //------------------------------------------------------------------------------

VII-C - Remarques sur ce document

J'ai énuméré dans cet exemple les principales boîtes de dialogues standards. L'appel des autres boîtes de dialogues standards (impressions, dossier, tips…) suit le même principe, veuillez pour cela consulter l'aide de wxWidgets.

J'ai réalisé les compilations dans l'EDI de C++ Builder, wxWidgets étant installé comme vu dans l'article : « Installation de wxWidgets dans l'EDI de C++ Builder ».

Pour les autres compilateurs, veuillez vous référer à leur documentation respective ainsi qu'à la documentation de wxWindows.

À bientôt,

Cgi

Avec la contribution d'Alacazam pour la relecture.