Une fenêtre complète

Voir le sujet précédent Voir le sujet suivant Aller en bas

Une fenêtre complète

Message par Admin le Dim 18 Déc - 21:34

Dans ce programme, nous allons ajouter plusieurs éléments pour créer un petit éditeur de texte avec lecture et écriture de fichiers. Les fonctions de l'éditeur seront très simples !!! Ce programme s'inspire du programme SIB (Small Is Beautiful) de Steve Gibson écrit en assembleur 32 bits pour le compilateur MASM. Je l'ai donc traduit pour le 64 bits et le compilateur nasm. Il peut servir de squelette à d'autres programmes.
Et comme en 64 bits, nous disposons de plus de registres, j'utiliserais aussi les registres supplémentaires (R12 à R15 par exemple).
Dans la partie data, après les descriptions des libellés habituels, nous trouvons plusieurs nouvelles structures : certaines de type ACCEL qui permettent d'utiliser des raccourcis clavier pour selectionner des menus et sous-menus, d'autres de type TBBUTTONS qui vont permettre de créer sous la barre des menus, une barre d'outils avec les icônes Nouveau, Ouvrir, Save.
Dans la partie code, nous trouvons une première procèdure intéressante OnlyOneInstance qui vérifie si le programme a déjà été lancé. Pour cela , nous créons un sémaphore par la fonction CreateSemaphoreA et si un sémaphore existe déjà, nous cherchons l'état de la fenêtre et nous la réactivons pour la mettre au premier plan. Sinon le programme s’exécute normalement.
Ensuite nous créons la classe de la fenêtre puis la fen^tre elle même comme nous l'avons déjà vu. Nous avons ajouté le quand même le chargement d'une icone particulière qui viendra s'afficher dans le bandeau haut de la fenêtre avec la fonction LoadImageA. Le handle récupérée alimentera la zone WNDCLASSEX.hIcon. Après la création, nous trouvons la création de la table des raccourcis claviers (accélérateurs) par la fonction CreateAcceleratorTableA puis la boucle que nous avons déjà vue de traitements des messages.
Tout le reste se trouve dans la procèdure de gestion des événements de la fenêtre WndProc. Nous avons ajouté le traitement des messages WM_SIZE et WM_NOTIFY.
Dans la partie création, nous trouvons une procèdure de centrage de la fenêtre au milieu de l'écran MiscCenterWnd. Nous l'appelons en lui passant de handle de l'écran trouvé par la fonction GetDesktopWindow et le handle de notre fenêtre (Nous passons ces paramètres par push pour pouvoir réutiliser cette procèdure dans d'autres programmes). Dans cette procèdure nous trouvons la fonction GetWindowRect qui va extraire les dimensions de l'écran et de la fenêtre puis une série de calculs pour calculer les déplacements horizontaux et verticaux qui vont servir à positionner la fenêtre par SetWindowPos.

De retour dans la partie création, nous trouvons une procédure pour ajouter les menus, une pour la barre d'état, une pour la barre des boutons et une pour la zone d'édition.
Pour les menus, après avoir crée la barre des menus, nous appelons une procèdure de création du menu Fichier et du menu Aide. Pour le menu Fichier, nous créons les sous menus, Nouveau, Ouvrir, Enregistrer, Enregistrer sous et Quitter. Nous séparons les 4 premiers et Quitter par une barre de séparation. Pour le menu Aide, nous nous contentons d'un seul sous menu pour afficher la version.
La procèdure pour ajouter la barre d'état est identique à celle vue précedement.
Dans celle pour ajouter les boutons, nous appelons la fonction CreateToolbarEx avec de nombreux paramètres dont un contient l'adresse de la structure qui décrit les boutons TBBUTTON. Cette structure indique le nom de l'icone standard à utiliser et l'identification de chaque bouton. Nous ne créons que les 3 boutons Nouveau, Ouvrir, Enregistrer.
Pour la zone d'édition, nous nous contentons de créer une fenêtre avec le type Edit et nous l'initialisons à blanc.

Dans la partie paint, nous nous contentons du minimum.
Dans la partie resize, nous trouvons le traitement du message WM_SIZE envoyé par windows quand l'utilisateur diminue ou agrandit la fenêtre. Si vous revenez au programme précédent, et si vous changer la dimension de la fenêtre avec la souris, vous remarqerez que la barre d'état et les zones de saises ou d'affichage ne changent pas de taille. Ce n'est pas très joli.
Par contre dans ce programme, nous allons envoyer un message à la barre d'état et à la barre d'outil qui contiendra les paramètres reçus à notre fonction et ces 2 barres suivront bien sagement les évolutions de la fenêtre. C'est plus compliqué pour la zone de saisie car s'agissant d'une fenêtre, il faut calculer les nouvelles positions et placer la fenêtre par la fonction MoveWindow  mais le résultat est parfait.

Dans la partie Commande, il nous faut distinguer les cas où l'utilisateur a choisi chacun des sous menus possibles ou a modifié la zone d'édition.
Pour la commande IDM_VERSION, nous nous contentons d'afficher la version par la fonction MessageBoxA.
Pour la commande IDM_NEW (nouveau texte), nous appelons la procèdure CmdIDM_NEW dans laquelle nous appelons la procèdure SaveChanges qui va vérifier que le texte précédent n'est pas à sauvegarder. Nous réinitialisons les infos fichiers, nous changeons le titre de la fenêtre par NewWindowName et nous allouons de la place sur le tas pour le buffer de travail par allocBuffer. Vous remarquerez que dans CmdIDM_NEW nous avons l'instruction  sub rsp,8h bien que dans cette procèdure nous n'avons pas d'appel à des fonctions de l'API. Mais cela permet d'avoir la pile alignée pour les sous procédures.
Pour la commande IDM_OPEN, nous appelons la procèdure ouvrirfichier qui commence par appeler la procèdure SaveChanges. Ensuite nous appelons la fonction GetOpenFileNameA que nous avons déjà vu pour choisir le nom du fichier à ouvrir. Dans les paramètres, nous avons mis un filtre pour selectionner que les fichiers avec l'extension .txt.
Puis nous appelons la fonction CreateFileA qui va créer la structure de fichier cessionnaire à Windows et nous retourner un handle. Nous recherchons la taille du fichier choisi par GetFileSizeEx avec la quelle nous allons allouer l'espace mémoire pour le charger. Nous ajoutons une quantité pour prévoir les agrandissements du texte. Puis nous entrons dans une boucle de lecture qui va charger le fichier en mémoire. En fin, nous refermons le fichier. Quand le fichier est chargé, nous envoyons le texte dans la zone de saisie prévue dans notre fenêtre par SendMessageA. Il sera donc affiché tel quel.
Pour la commande IDM_SAVE, nous commençons par récupérer les informations saisies dans la zone d'edition pour les copier dans le buffer en zone mémoire. Puis nous appelons la procédure CmdIDM_SAVE qui va commencer par appeler la fonction GetSaveFileNameA pour choisir le nom du fichier sur lequel nous allons écrire. Ensuite nous créons la structure du fichier par CreateFileA puis nous écrivons le buffer par WriteFile.
Et voilà un petit éditeur tout simple !!! et qui peut être amélioré .. au travail !!
Attention : le format du fichier est .zip car je n'ai pas pu joindre un fichier au format .txt ni .doc. Dans ce fichier compressé, vous trouverez le source l'image de l'icône et le fichier des includes.
Fichiers joints
fencomplete.zip Vous n'avez pas la permission de télécharger les fichiers joints.(22 Ko) Téléchargé 0 fois
avatar
Admin
Admin

Messages : 38
Date d'inscription : 28/11/2016

Voir le profil de l'utilisateur http://assembleur64.forumactif.com

Revenir en haut Aller en bas

Voir le sujet précédent Voir le sujet suivant Revenir en haut

- Sujets similaires

 
Permission de ce forum:
Vous ne pouvez pas répondre aux sujets dans ce forum