Programme de boîte de dialogue simple

Nouveaux concepts:

Création d'une application basée sur une boîte de dialogue
Utilisation des contrôles de fenêtre enfant - boutons
Création d'un script de ressources
Prototypes de fonctions
Utilisation des messages de fenêtre

Nouvelles fonctions API:

GetModuleHandle
DialogBoxParam
SetDlgItemText
SendMessage
EndDialog

 


Dans cette section, nous allons créer un programme avec une boîte de dialogue simple comprenant un bouton qui affiche un message et un bouton de sortie. Lancez WinAsm et ouvrez un nouveau projet exe. Tout d'abord, nous allons créer le modèle de boîte de dialogue en utilisant l'Éditeur de ressources visuelles de WinAsm. Cela affiche les contrôles sur une grille à l'intérieur de votre boîte de dialogue telle qu'elle apparaîtra dans votre programme. Les barres d'outils Boîte à outils et Boîte de dialogue (dans le menu Affichage) vous permettent d'ajouter plus de contrôles et de les organiser visuellement. Plutôt que de taper manuellement un script de ressources, toute la boîte de dialogue peut être conçue de cette manière.

Sélectionnez Projet > Ajouter une nouvelle ressource, ou faites un clic droit dans la barre d'exploration du projet et sélectionnez Ajouter une nouvelle ressource. Le mode visuel est activé par défaut, alors cliquez sur "Ajouter une nouvelle boîte de dialogue" (le premier bouton dans la barre d'outils Boîte à outils) et vous devriez voir ceci :

1

Maintenant, nous allons ajouter un titre, 2 boutons et une zone de saisie. Cliquez sur l'onglet "Ressources" en bas à droite de l'écran, double-cliquez sur la zone de titre et entrez "Programme de boîte de dialogue simple". Ensuite, cliquez sur le bouton "Modifier" (4ème bouton dans la barre d'outils) et dessinez une boîte comme ceci :

1

Maintenant, dans la barre d'exploration, cliquez sur IDC_EDIT1002 et videz son champ de texte. Ensuite, cliquez sur "Bouton" dans la barre d'outils et ajoutez 2 boutons, en modifiant leurs champs de légende dans la barre d'exploration pour qu'ils affichent "Say Hello" et "Exit", comme ceci :

1

Les boutons de la barre d'outils Boîte de dialogue vous permettent d'aligner et de dimensionner les contrôles pour les rendre plus agréables à l'œil. Pour voir le script de ressources créé par WinAsm, désactivez le mode visuel en appuyant sur F12, en désélectionnant "Mode visuel" dans le menu Ressources ou en cliquant sur le bouton de la barre d'outils :

1

Désactiver le mode visuel vous permettra également de taper un script de ressources manuellement ou d'utiliser celui que j'ai inclus dans la section du code source en collant le script à partir de dialogbox1.rc :

1

Pour commencer à écrire le code autour de notre modèle de boîte de dialogue, nous devons connaître les noms et les ID des contrôles de la boîte de dialogue, de la zone de saisie et des boutons, comme indiqué dans les 4 premières lignes du script de ressources ci-dessus.

Sélectionnez Untitled1.asm dans la barre d'exploration du projet et collez dialogbox1.asm depuis la section du code source :

1

Le petit signe "+" en bas à gauche indique le début et la fin de la procédure de la boîte de dialogue. En cliquant dessus, la procédure complète est développée comme indiqué ci-dessous :

1

Enfin, enregistrez votre projet, le script de ressources et les fichiers asm, puis cliquez sur le bouton "Go All". Vous devriez voir ceci lorsque vous cliquez sur le bouton "Say Hello".

1

En cliquant sur "Go All", le script de ressources sera compilé, ainsi que l'assemblage et la liaison. Si vous modifiez la disposition de la boîte de dialogue ou de ses contrôles, vous pouvez recompiler le script de ressources sans réassembler ni lier en sélectionnant Make>Compile RC. Maintenant, nous allons analyser le code. Les fichiers d'en-tête et de bibliothèque devraient être explicites à présent.

Prototypes

DlgProc proto :DWORD,:DWORD,:DWORD,:DWORD - Tout d'abord, nous déclarons le prototype de la fonction DlgProc afin de pouvoir y faire référence avec l'opérateur addr lorsque nous invoquons DialogBoxParam ultérieurement.

Variables

Message - notre chaîne "Hello World!" terminée par un caractère nul.

hInstance - (défini dans windows.inc en tant que DWORD) non initialisé, mais contiendra la poignée du module de notre boîte de dialogue pour l'appel à DialogBoxParam.

Code du programme

invoke GetModuleHandle - récupère la poignée du module ou la poignée d'instance de notre programme. Il s'agit de l'ID de votre programme et est utilisé comme paramètre pour plusieurs fonctions API que notre programme doit appeler, il est donc habituel de le récupérer au début de notre programme.

mov hInstance,eax  - déplace le résultat de l'appel à GetModuleHandle depuis eax dans la variable que nous avons déclarée pour cela ci-dessus (à son retour d'une fonction Win32, la valeur de retour de la fonction, le cas échéant, est placée dans eax). 

invoke DialogBoxParam - crée une boîte de dialogue modale et retourne lorsque la boîte de dialogue est détruite. Prend 5 paramètres : la poignée d'instance, le modèle de boîte de dialogue, la poignée de la fenêtre parent, l'adresse de la procédure de la boîte de dialogue et des données spécifiques à la boîte de dialogue.

invoke ExitProcess - l'instruction finale telle que décrite dans notre chapitre de base.

Procédure de la boîte de dialogue

La procédure de la boîte de dialogue est une fonction de rappel qui traite les messages envoyés à la boîte de dialogue. Elle a quatre paramètres et renvoie vrai ou faux en fonction de si elle traite ou non le message. Dans ce cas, les contrôles de la fenêtre enfant envoient des messages à la procédure de la boîte de dialogue en l'appelant et en passant le message dans les paramètres.

La première ligne est la déclaration de la fonction DlgProc. Remarquez les paires de paramètre:type qui suivent la directive PROC. Les paramètres comprennent la poignée de la fenêtre, un identifiant de message (uMsg) et deux paramètres de message (wParam & lParam) qui spécifient des informations de message supplémentaires.

Lorsque les contrôles de la fenêtre enfant envoient un message, le paramètre uMsg contient WM_COMMAND et wParam contient l'ID du contrôle. Le traitement des messages est effectué à l'aide d'une série SI-SINON-SI-FIN qui vérifie d'abord si uMsg contient un message WM_COMMAND provenant de l'un des contrôles ou un message WM_CLOSE.

Si le message est WM_CLOSE, alors EndDialog est appelé pour détruire la boîte de dialogue. EndDialog ne le fait pas immédiatement, il définit uniquement un indicateur pour le gestionnaire interne de boîte de dialogue et continue à exécuter les instructions suivantes.

Si le message est WM_COMMAND, alors une série IF-SINON-SI-FIN emboîtée vérifie la valeur de wParam pour déterminer comment réagir, dans ce cas, si le bouton "Say Hello" (ID 1003) ou le bouton "Exit" (ID 1004) a été appuyé.

SetDlgItemText - définit le texte d'un contrôle (l'éditeur de texte ID 1002).

SendMessage - envoie un message WM_CLOSE à la procédure de la boîte de dialogue.

La ligne suivante XOR eax,eax met simplement eax à zéro avant que RET ne renvoie l'exécution à DialogBoxParam et appelle par la suite ExitProcess.

Analyse dans le débogueur

Par habitude, nous ouvrons notre application dans Olly pour voir comment le code a été assemblé :

1

Étant donné que nous codons en assembleur, nous obtenons une désassemblage clair dans Olly. Le premier crochet à gauche entoure les 4 premières lignes de notre code, et le deuxième crochet entoure la procédure de la boîte de dialogue, qui est moins facile à comprendre au premier coup d'œil. MASM a converti les constructions haut niveau IF-SINON-SI-FIN en instructions de comparaison (CMP) et de saut conditionnel. Comme précédemment, le bloc final d'instructions surlignées en jaune sont des jump thunks pointant vers la table d'adresses d'importation.

Notes

Le champ "Name" de la boîte de dialogue et de ses contrôles peut être modifié pour quelque chose de plus significatif en double-cliquant dans l'éditeur visuel. Le script sera modifié en conséquence, par exemple :

1

Ces noms peuvent ensuite être déclarés comme des constantes dans le fichier ASM et utilisés dans le code à la place des ID numériques des contrôles afin d'améliorer la lisibilité :

1

Il y a quelques particularités concernant le paramètre du modèle de boîte de dialogue passé à DialogBoxParam. Si le nom de la boîte de dialogue et l'ID du contrôle sont définis dans le script des ressources (comme c'est le cas à la ligne 1 de l'exemple que WinAsm a créé pour nous), alors seul l'ID du contrôle peut être passé à DialogBoxParam. Si le nom et l'ID du contrôle sont également déclarés comme des constantes dans le fichier ASM, alors le nom peut être passé à DialogBoxParam. Si le nom et l'ID du contrôle ne sont pas définis dans le script des ressources, alors le nom peut être déclaré comme une variable de chaîne dans la section .data du fichier ASM et passé à DialogBoxParam avec l'opérateur "ADDR".

En incluant la ligne include resource.h en haut du script des ressources, cela permet d'utiliser les noms descriptifs plutôt que les nombres hexadécimaux des styles qui définissent l'apparence de la boîte de dialogue et de ses contrôles.

 


Copyright (C)- xtx Team (2021)

XHTML valide 1.1 CSS Valide !