BeginPaint code débutant

Signaler
Messages postés
93
Date d'inscription
mercredi 18 septembre 2002
Statut
Membre
Dernière intervention
20 juillet 2006
-
Messages postés
1466
Date d'inscription
vendredi 2 janvier 2004
Statut
Modérateur
Dernière intervention
14 février 2014
-
Bonjour,
le problème est tout simple je comprends absolument pas ce qui marche pas. Le "programme" est censé créer une fenêtre est afficher du texte en plein milieu. Le problème est que la partie qui crée la fenêtre ne marche que quand le code qui "peint" le texte est absent du programme. Je comprends pas pourquoi puisque il refuse de créer (CreateWindow) la fenêtre (génère une erreur).

Code:

[EXTERN MessageBoxA]
[import MessageBoxA user32.dll]

[EXTERN ExitProcess]
[import ExitProcess kernel32.dll]
[EXTERN CreateWindowExA]
[import CreateWindowExA user32.dll]
[extern GetModuleHandleA]
[import GetModuleHandleA kernel32.dll]
[extern GetCommandLineA]
[import GetCommandLineA kernel32.dll]
[EXTERN RegisterClassExA]
[import RegisterClassExA user32.dll]
[EXTERN ShowWindow]
[import ShowWindow user32.dll]
[EXTERN LoadIconA]
[import LoadIconA user32.dll]
[EXTERN LoadCursorA]
[import LoadCursorA user32.dll]
[EXTERN DefWindowProcA]
[import DefWindowProcA user32.dll]
[EXTERN PostQuitMessage]
[import PostQuitMessage user32.dll]
[EXTERN TranslateMessage]
[import TranslateMessage user32.dll]
[EXTERN DispatchMessageA]
[import DispatchMessageA user32.dll]
[EXTERN GetMessageA]
[import GetMessageA user32.dll]
[EXTERN CreateFontIndirectA]
[import CreateFontIndirectA gdi32.dll]
[EXTERN DeleteObject]
[import DeleteObject gdi32.dll]
[EXTERN PostMessageA]
[import PostMessageA user32.dll]

[EXTERN BeginPaint]
[import BeginPaint user32.dll]
[EXTERN GetClientRect]
[import GetClientRect user32.dll]
[EXTERN DrawTextA]
[import DrawTextA user32.dll]
[EXTERN EndPaint]
[import EndPaint user32.dll]

;_______________________________________________

[SECTION CODE USE32 CLASS=CODE]

..start:

push dword 00h ; null
call [GetModuleHandleA]
mov dword [instance], eax

Call [GetCommandLineA]
mov dword [commandline], eax

push dword 0Ah ; SW_SHOW
push dword eax
push dword 00h ; null
push dword [instance]
call WinMain

push dword eax
call [ExitProcess]

;************************************************
;* winMain *
;************************************************
;%define hInstance ebp+8
;%define hPrevInstance ebp+12
;%define lpCmdLine ebp+16
;%define nCmdShow ebp+20

WinMain:
enter 0,0
mov dword [winclass+0], 30h ; 48(d)
mov dword [winclass+4], 03h ; CS_HREDRAW | CS_VREDRAW
mov dword [winclass+8], WinProc
mov dword [winclass+12], 0
mov dword [winclass+16], 0
mov eax, dword [instance]
mov dword [winclass+20], eax

push word 0
push word 101
mov eax, dword [instance]
push dword eax
call [LoadIconA]
mov dword [winclass+24], eax
mov dword [winclass+44], eax

push dword 07F00h ; IDC_ARROW
push dword 00h ; NULL
call [LoadCursorA]
mov dword [winclass+28], eax

mov dword [winclass+32], 10h ; background COLOR_BTNFACE+1
mov dword [winclass+36], 00h ; (MenuName)
mov dword [winclass+40], nomclass

push dword winclass
call [RegisterClassExA]

cmp eax,0
jne RegisterOk

push dword 00h
push dword message1
push dword message2
push dword 00h
call [MessageBoxA]

push word 00h
call [ExitProcess]

RegisterOk:

mov dword [atom], eax

push dword 00h ; null
mov eax, dword [instance]
push dword eax
push dword 00h ; null
push dword 00h ; null
push dword 500 ; Wigth
push dword 500 ; Height
push dword 20 ; Left
push dword 20 ; Top
push dword 00CF0000h ; WS_TILEDWINDOW
push dword nom
push dword nomclass
push dword 00h ; WS_EX_LEFT
call [CreateWindowExA]

cmp eax , 0
jne CreateWindowOk

push dword 00h
push dword message1
push dword message3
push dword 00h
call [MessageBoxA]

push word 00h
call [ExitProcess]

CreateWindowOk:

mov dword [handle], eax

push dword 5h ; SW_SHOW
push dword [handle]
call [ShowWindow]

BoucleMessages:

push dword 0
push dword 0
push dword [handle]
push dword msg1
call [GetMessageA]

cmp eax, 12h ; WM_QUIT
je FinBoucle

cmp eax, -1
jne GetMEssageOk

push dword 00h
push dword message1
push dword message4
push dword 00h
call [MessageBoxA]

push word 00h
call [ExitProcess]

GetMEssageOk:

push dword msg1
call [TranslateMessage]
push dword msg1
call [DispatchMessageA]

jmp BoucleMessages

FinBoucle:
mov eax, dword [msg1+8]

Fin:
leave
ret 16

;*********************************************
;* WindowProc *
;*********************************************
%define hwnd ebp+8
%define uMsg ebp+12
%define wParam ebp+16
%define lParam ebp+20

WinProc:
enter 0,0
mov eax,[uMsg]

cmp eax,01b
je near Create
cmp eax,10b
je near Destroy

Defaut:
push dword [lParam]
push dword [wParam]
push dword [uMsg]]
push dword [hwnd]
call [DefWindowProcA]

;==========================================================
push dword PAINTSTRUCT
push dword [handle]
call [BeginPaint]

mov dword [hdc] ,eax

push dword RECT1
push dword [handle]
call [GetClientRect]

push dword 1
push dword RECT1
push dword -1
push dword mon_text
push dword [hdc]
call [DrawTextA]

push dword PAINTSTRUCT
push dword [handle]
call [EndPaint]
;==========================================================
Fin2:
leave
ret 16

Create: ;**************************************
push dword FontStandard
call [CreateFontIndirectA]
mov dword [hFontStandard], eax

jmp Fin2

Destroy: ;*************************************
push dword [hFontStandard]
call [DeleteObject]
jmp Fin2
;_______________________________________________


; Procedures et fonctions secondaires
;_______________________________________________

;Procedure qui assigne une font standard à un contrôle
; Param : Handle du contrôle dans eax

SetFontStandard:
push dword 01b
push dword [hFontStandard]
push dword 30h
push dword eax
call [PostMessageA]
ret
;_______________________________________________


[SECTION DATA USE32 CLASS=DATA]

; Données
;_______________________________________________
instance resd 1
commandline resd 1
winclass resd 12
atom resd 1
handle resd 1
msg1 resd 9
nomclass db "WindowClass01",0
nom db "premiere fenetre window",0
message1 db "Erreur !",0
message2 db "Première erreur !",0
message3 db "Deuxsième erreur !",0
message4 db "bye !",0

FontStandard dd 10
resd 6
db "MS sans Serif",0

hFontStandard resd 1

mon_text db "Mon texte !!",0
hdc resd 1

STRUC PAINTSTRUCT
.hdc resd 1
.fErase resd 1
.rcPaint resb 16
.fRestore resd 1
.fIncUpdate resd 1
.rgbReserved resb 32
ENDSTRUC

STRUC RECT1
.left resd 1
.top resd 1
.right resd 1
.bottom resd 1
ENDSTRUC
;_______________________________________________



Merci
TRAX
A voir également:

11 réponses

Messages postés
570
Date d'inscription
jeudi 28 novembre 2002
Statut
Membre
Dernière intervention
18 janvier 2021
2
Salut,
Je ne vois pas trop dans quel assembleur c'est écrit.
Par contre je remarque que l'essai est d'écrire en pure assembleur sans aucune macro ,sans structure ,sans lib ,sans .. comme invoke et sans qu'on puisse distinguer la boucle d'attente .
C'est illisible rapidement.
Conseil : Mettre des invoke ,utiliser des structures (c'est beaucoup plus lisible) et s'inspirer d'exemples existants et faisant la même chose.Les exemples 1 de masm32 contienne un exemple faisant exactement la même chose.
ToutEnMasm
Messages postés
93
Date d'inscription
mercredi 18 septembre 2002
Statut
Membre
Dernière intervention
20 juillet 2006

Bonsoir,
si il n'ya pas d'invoke c'est parceque je travail sous nasm, les structures si c de cela que l'on parle sont totalement a la fin du program (sauf pour la première partie de prog qui consiste à créer une fénêtre !)
Le code présentant un problème est celui qui est censé afficher le message et est repérré par deux lignes de "="
Merci
TRAX
Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
25
TRAX44 > prends pas mal mais il est vrai que quand on voit cela on comprend pourquoi MASM32 est si repandu. On peut y ecrire aussi du vrai asm mais c'est d'une autre clarte.

ciao...
BruNews, Admin CS, MVP Visual C++
Messages postés
93
Date d'inscription
mercredi 18 septembre 2002
Statut
Membre
Dernière intervention
20 juillet 2006

Salut,
juste une question "if" en asm sa donne quoi ? Je n'ai jamias vu çà en désassemblant un program, les invoke non plus! Si j'ai choisie l'asm c'est pour cette notion de language bas !!
Pour simplifier le programme, le problème est là:

push dword PAINTSTRUCT 
push dword [handle] 
call [BeginPaint] 

mov dword [hdc] ,eax 

push dword RECT1 
push dword [handle] 
call [GetClientRect] 

push dword 1 
push dword RECT1 
push dword -1 
push dword mon_text 
push dword [hdc] 
call [DrawTextA] 

push dword PAINTSTRUCT 
push dword [handle] 
call [EndPaint] 



et je dirais même dès l'appel de la première api (BeginPaint d'ou le titre du sujet)!!
Merci
TRAX
p.s. tout les programmer disent que windaube c de la daube mais masm sa vien d'ou?? M comme ...
Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
25
dependra du if, cas en C:
if(value) {ACTION ICI}
on aura 'value dans EAX:
test eax, eax
je short noAction
; ACTION ICI
; .....
noAction:
.....

Moi ce qui me chagrine(façon de parler) c'est ce:
push dword PAINTSTRUCT
c'est sensé faire quoi ? normalement tu dois pusher adresse d'une structure PAINTSTRUCT que tu auras placee sur la pile ou dans un segment. Est-ce le cas dans ton code vu que je ne connais pas cette syntaxe.

ciao...
BruNews, Admin CS, MVP Visual C++
Messages postés
93
Date d'inscription
mercredi 18 septembre 2002
Statut
Membre
Dernière intervention
20 juillet 2006

En fait j'ai essayer de mettre en place une structure :

STRUC PAINTSTRUCT
.hds resd 1
...
ENDSTRUC

mais quand je pusher PAINTSTRUCT, sa pusher 00000000
j'ai donc fais comme pour la strcuture de winclass, j'ai mis ma "propre variable"!
Merci
TRAX
Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
25
c'est simple de mettre sa proprevariable:
sub esp, 64
et voila un PAINTSTRUCT de mis.
push esp ; adresse de ta PAINTSTRUCT
si tu as un petit truc a inserer entre les 2 lignes histoire d'eviter les cycles de penalite d'AGI stall et sera impec.

ciao...
BruNews, Admin CS, MVP Visual C++
Messages postés
93
Date d'inscription
mercredi 18 septembre 2002
Statut
Membre
Dernière intervention
20 juillet 2006

Salut,
tu m'éxcusera mais comme je l'ai dit dans le titre, suis débutant et là, j'ai totalment décollé!!
Merci
TRAX
Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
25
BeginPaint est defini comme suit (MSDN):
HDC BeginPaint(HWND hwnd, LPPAINTSTRUCT lpPaint);

On doit donc pusher l'adresse ou se trouve les 64 octets disponibles representant une structure PAINTSTRUCT que le systeme remplira. Il est donc inutile d'encombrer un segment .data avec de la donnee qui de toute façon n'est valable QUE pendant le traitement de WM_PAINT, on va donc placer une struct PAINTSTRUCT sur la pile et l'enlever en sortie.

sub esp, 64 ; struc PAINTSTRUCT sur pile
push esp ; param lpPaint
push hwnd ; ici tu vois si est deja en registre ou non
call BeginPaint

A ce stade il reste ta struct sur la pile pour l'appel EndPaint ulterieur. Devra suivre: add esp, 64

ciao...
BruNews, Admin CS, MVP Visual C++
Messages postés
93
Date d'inscription
mercredi 18 septembre 2002
Statut
Membre
Dernière intervention
20 juillet 2006

Salut,
je viens trouvé ce qui marché pas : il fallait mettre le code qui ecrit le texte après

Defaut: 
push dword [lParam] 
push dword [wParam] 
push dword [uMsg]] 
push dword [hwnd] 
call [DefWindowProcA] 

Ce qui donne:

[EXTERN MessageBoxA] 
[import MessageBoxA user32.dll] 

[EXTERN ExitProcess] 
[import ExitProcess kernel32.dll] 
[EXTERN CreateWindowExA] 
[import CreateWindowExA user32.dll] 
[extern GetModuleHandleA] 
[import GetModuleHandleA kernel32.dll] 
[extern GetCommandLineA] 
[import GetCommandLineA kernel32.dll] 
[EXTERN RegisterClassExA] 
[import RegisterClassExA user32.dll] 
[EXTERN ShowWindow] 
[import ShowWindow user32.dll] 
[EXTERN LoadIconA] 
[import LoadIconA user32.dll] 
[EXTERN LoadCursorA] 
[import LoadCursorA user32.dll] 
[EXTERN DefWindowProcA] 
[import DefWindowProcA user32.dll] 
[EXTERN PostQuitMessage] 
[import PostQuitMessage user32.dll] 
[EXTERN TranslateMessage] 
[import TranslateMessage user32.dll] 
[EXTERN DispatchMessageA] 
[import DispatchMessageA user32.dll] 
[EXTERN GetMessageA] 
[import GetMessageA user32.dll] 
[EXTERN CreateFontIndirectA] 
[import CreateFontIndirectA gdi32.dll] 
[EXTERN DeleteObject] 
[import DeleteObject gdi32.dll] 
[EXTERN PostMessageA] 
[import PostMessageA user32.dll] 

[EXTERN BeginPaint] 
[import BeginPaint user32.dll] 
[EXTERN GetClientRect] 
[import GetClientRect user32.dll] 
[EXTERN DrawTextA] 
[import DrawTextA user32.dll] 
[EXTERN EndPaint] 
[import EndPaint user32.dll] 

;_______________________________________________ 

[SECTION CODE USE32 CLASS=CODE] 

..start: 

push dword 00h ; null 
call [GetModuleHandleA] 
mov dword [instance], eax 

Call [GetCommandLineA] 
mov dword [commandline], eax 

push dword 0Ah ; SW_SHOW 
push dword eax 
push dword 00h ; null 
push dword [instance] 
call WinMain 

push dword eax 
call [ExitProcess] 

;************************************************ 
;* winMain * 
;************************************************ 
;%define hInstance ebp+8 
;%define hPrevInstance ebp+12 
;%define lpCmdLine ebp+16 
;%define nCmdShow ebp+20 

WinMain: 
enter 0,0 
mov dword [winclass+0], 30h ; 48(d) 
mov dword [winclass+4], 03h ; CS_HREDRAW | CS_VREDRAW 
mov dword [winclass+8], WinProc 
mov dword [winclass+12], 0 
mov dword [winclass+16], 0 
mov eax, dword [instance] 
mov dword [winclass+20], eax 

push word 0 
push word 101 
mov eax, dword [instance] 
push dword eax 
call [LoadIconA] 
mov dword [winclass+24], eax 
mov dword [winclass+44], eax 

push dword 07F00h ; IDC_ARROW 
push dword 00h ; NULL 
call [LoadCursorA] 
mov dword [winclass+28], eax 

mov dword [winclass+32], 10h ; background COLOR_BTNFACE+1 
mov dword [winclass+36], 00h ; (MenuName) 
mov dword [winclass+40], nomclass 

push dword winclass 
call [RegisterClassExA] 

cmp eax,0 
jne RegisterOk 

push dword 00h 
push dword message1 
push dword message2 
push dword 00h 
call [MessageBoxA] 

push word 00h 
call [ExitProcess] 

RegisterOk: 

mov dword [atom], eax 

push dword 00h ; null 
mov eax, dword [instance] 
push dword eax 
push dword 00h ; null 
push dword 00h ; null 
push dword 500 ; Wigth 
push dword 500 ; Height 
push dword 20 ; Left 
push dword 20 ; Top 
push dword 00CF0000h ; WS_TILEDWINDOW 
push dword nom 
push dword nomclass 
push dword 00h ; WS_EX_LEFT 
call [CreateWindowExA] 

cmp eax , 0 
jne CreateWindowOk 

push dword 00h 
push dword message1 
push dword message3 
push dword 00h 
call [MessageBoxA] 

push word 00h 
call [ExitProcess] 

CreateWindowOk: 

mov dword [handle], eax 

push dword 5h ; SW_SHOW 
push dword [handle] 
call [ShowWindow] 

BoucleMessages: 

push dword 0 
push dword 0 
push dword [handle] 
push dword msg1 
call [GetMessageA] 

cmp eax, 12h ; WM_QUIT 
je FinBoucle 

cmp eax, -1 
jne GetMEssageOk 

push dword 00h 
push dword message1 
push dword message4 
push dword 00h 
call [MessageBoxA] 

push word 00h 
call [ExitProcess] 

GetMEssageOk: 

push dword msg1 
call [TranslateMessage] 
push dword msg1 
call [DispatchMessageA] 

jmp BoucleMessages 

FinBoucle: 
mov eax, dword [msg1+8] 

Fin: 
leave 
ret 16 

;********************************************* 
;* WindowProc * 
;********************************************* 
%define hwnd ebp+8 
%define uMsg ebp+12 
%define wParam ebp+16 
%define lParam ebp+20 

WinProc: 
enter 0,0 
mov eax,[uMsg] 

cmp eax,01b 
je near Create 
cmp eax,10b 
je near Destroy 

;========================================================== 
push dword PAINTSTRUCT 
push dword [handle] 
call [BeginPaint] 

mov dword [hdc] ,eax 

push dword RECT1 
push dword [handle] 
call [GetClientRect] 

push dword 1 
push dword RECT1 
push dword -1 
push dword mon_text 
push dword [hdc] 
call [DrawTextA] 

push dword PAINTSTRUCT 
push dword [handle] 
call [EndPaint] 
;========================================================== 

Defaut: 
push dword [lParam] 
push dword [wParam] 
push dword [uMsg]] 
push dword [hwnd] 
call [DefWindowProcA] 
Fin2: 
leave 
ret 16 

Create: ;************************************** 
push dword FontStandard 
call [CreateFontIndirectA] 
mov dword [hFontStandard], eax 

jmp Fin2 

Destroy: ;************************************* 
push dword [hFontStandard] 
call [DeleteObject] 
jmp Fin2 
;_______________________________________________ 

; Procedures et fonctions secondaires 
;_______________________________________________ 

;Procedure qui assigne une font standard à un contrôle 
; Param : Handle du contrôle dans eax 

SetFontStandard: 
push dword 01b 
push dword [hFontStandard] 
push dword 30h 
push dword eax 
call [PostMessageA] 
ret 
;_______________________________________________ 

[SECTION DATA USE32 CLASS=DATA] 

; Données 
;_______________________________________________ 
instance resd 1 
commandline resd 1 
winclass resd 12 
atom resd 1 
handle resd 1 
msg1 resd 9 
nomclass db "WindowClass01",0 
nom db "premiere fenetre window",0 
message1 db "Erreur !",0 
message2 db "Première erreur !",0 
message3 db "Deuxsième erreur !",0 
message4 db "bye !",0 

FontStandard dd 10 
resd 6 
db "MS sans Serif",0 

hFontStandard resd 1 

mon_text db "Mon texte !!",0 
hdc resd 1 

PAINTSTRUCT resd 16
RECTO resd 1
;_______________________________________________ 

Messages postés
1466
Date d'inscription
vendredi 2 janvier 2004
Statut
Modérateur
Dernière intervention
14 février 2014
1
salut,

si il est vrai que la synthaxe de nasm est assez repoussante de premier abord, la gestion des macros est assez puissante pour permettre de creer un environnement plus simple et plus lisible.

Comme "invoke" pour masm qui est à la base,... une macro...

@++