FAIRE DE LA GUI EN ASM32WIN
INTRODUCTION
j'ai mis un exemple (avec source) pour illustrer mon article dans le repertoire "stupide"
alors voila mon article sur la GUI
mais d'abord qu'est ce que la gui ? c la Graphic User Interface,
c a dire : l'interface graphique !
alors ça sert a faire des boutons ronds des fenetre avec une
gueule cassé, des texte à la waleguéne, etc ...
c bien hein ! :) hmmm vous avez envie de savoir
et bin je vais faire durer le suspence .......
non non encore un peu plus ........
FAIRE UNE FENETRE NON NORMALISER
faire un programme c bien, faire un bo programme c mieux ! :)
alors au lieu de faire un programme pas bo avec une fenetre
carré (c pas bo hein ! :))
on va plutot faire un programme trés bo avec une fenetre pas
carré(c bo hein :))
alors comment qu'on fait ?
NUM_PTS equ 27
pt POINT <25, 95>, <15, 50>, <10, 35>, <15, 25>, <25, 15>, <90, 5>, <100, 10>, <110, 5>, <175, 15>, <185, 25>, <190, 35>, <185, 50>, <175, 95>, <175, 110>, <185, 150>, <190, 165>, <185, 175>, <175, 185>, <110, 195>, <100, 190>, <90, 195>, <25, 185>, <15, 175>, <10, 165>, <15, 150>, <25, 105>, <25, 95>invoke CreatePolygonRgn, ADDR pt, NUM_PTS, WINDING
invoke SetWindowRgn, hWin, eax, FALSE
boudiou quoi que c que ça ?
deja désolé pour les TASMalien :) mais moi je fait tous sous masm32, c plus facile :) et je suis un grand fénéant :)
NUM_PTS c une
constante elle designe le nbre de point là y'en as 27 (je le dit
on sait jamais y'en as qui sont long as comprendre)
pt c'est les point
<x,y>
CreatePolygonRgn c'est :
The CreatePolygonRgn function creates a polygonal region.
HRGN CreatePolygonRgn(
CONST POINT *lppt, // address of array of points
int cPoints, // number of points in array
int fnPolyFillMode // polygon-filling mode
);
Parameters
lppt
Points to an array of POINT structures that define the vertices
of the polygon. The polygon is presumed closed. Each vertex can
be specified only once.
cPoints
Specifies the number of points in the array.
fnPolyFillMode
Specifies the fill mode used to determine which pixels are in the
region. This parameter can be one of the following values:
Value Meaning
ALTERNATE Selects alternate mode (fills area between
odd-numbered and even-numbered polygon sides on each scan line).
WINDING Selects winding mode (fills any region with a nonzero
winding value).
For more information about these modes, see the SetPolyFillMode
function.
Return Value
If the function succeeds, the return value is the handle of the
region.
If the function fails, the return value is NULL.
source win32.hlp (y'as des anglophobes ici ? :)) et puis vous avez pas d'excuse, je suis nul anglais et je traduit ça direct en le lisant ! c que des mots transparents ! (par exemple winding ça veut dire venter (expression : oh, il vente fort aujourd'hui))
SetWindowRgn c'est :
The SetWindowRgn function sets the window region of a window. The window region determines the area within the window where the operating system permits drawing. The operating system does not display any portion of a window that lies outside of the window region
int
SetWindowRgn(
HWND hWnd, // handle to window whose window
region is to be set
HRGN hRgn, // handle to region
BOOL bRedraw // window redraw flag
);
Parameters
hWnd
Handle to the window whose window region is to be set.
hRgn
Handle to a region. The function sets the window region
of the window to this region.
If hRgn is NULL, the function sets the window region to NULL.
bRedraw
Boolean value that specifies whether the operating
system redraws the window after setting the window region. If
bRedraw is TRUE, the operating system does so; otherwise, it does
not.
Typically, you set bRedraw to TRUE if the window is visible.
Return
Value
If the function succeeds, the return value is non-zero.
If the function fails, the return value is zero.
Comments
If the bRedraw parameter is
TRUE, the system sends the WM_WINDOWPOSCHANGING and
WM_WINDOWPOSCHANGED messages to the window.
The coordinates of a window's window region are relative to the
upper-left corner of the window, not the client area of the
window.
After a successful call to SetWindowRgn, the operating system
owns the region specified by the region handle hRgn. The
operating system does not make a copy of the region. Thus, you
should not make any further function calls with this region
handle. In particular, do not close this region handle.
ah c bo l'anglais ! :)
bon maintenant on est HEUREUX on as tout les truc qu'il nous faut
je place ou les fonction
que tu m'as donné ?
faut mettre :
NUM_PTS equ 27
pt POINT <25, 95>, <15, 50>, <10, 35>, <15, 25>, <25, 15>, <90, 5>, <100, 10>, <110, 5>, <175, 15>, <185, 25>, <190, 35>, <185, 50>, <175, 95>, <175, 110>, <185, 150>, <190, 165>, <185, 175>, <175, 185>, <110, 195>, <100, 190>, <90, 195>, <25, 185>, <15, 175>, <10, 165>, <15, 150>, <25, 105>, <25, 95>
au debut dans .date et faut mettre :
invoke CreatePolygonRgn, ADDR pt, NUM_PTS, WINDING
invoke SetWindowRgn, hWin, eax, FALSE
faut le mettre dans un endroit ou il passera au debut, exemple dans : WM_CREATE
bon c OK ? let's go for la suite !
METTRE UNE ZOLI IMAGE DANS LE FOND
bon notre fenetre elle est encore pas belle :( je veut une meuf a poil dans le fond de la fenetre ! (ah sacré toi !) et bin d'abord met ton image en bmp NON compressé, vi je sais c enorme ça fait plein de kilooctet bon now tu met dans : (on va dire que ton image s'appelle fond.bmp)
le fichier .rc
FOND BITMAP "fond.bmp"
et dans votre programme, dans WM_CREATE par exemple :
invoke ImageList_Create,300,200,ILC_COLOR32,1,1
mov hImageList, eax
invoke LoadBitmap,hInstance,offset MainBmp
push eax
invoke ImageList_Add,hImageList,eax,NULL
pop eax
invoke DeleteObject, eax
et dans WM_PAINT faut mettre :
invoke BeginPaint,hWin,ADDR Ps
mov hDC, eax
invoke ImageList_Draw,hImageList,0,hDC,0,0,1h
invoke EndPaint,hWin,ADDR Ps
et dans les variable il faut rajouter :
MainBmp db "fond",0
hImageList dd 0
alors heureux ?
MAINTENANT VOUS VOULEZ DES BOUTONS COOL !
c'est bien beau de faire une belle fenetre avec un beau fond
mais si c'est pour avoir les boutons de microsoft par dessus ....
donc voila : alors j'ai pas envie de vous mettre un listing de 10
km de long alors j'ai mis une source ! YeEpEe ! :)
le principe est simple, quand on appuie sur le bouton de la
souris, le programme envoi un msg WM_LBUTTONDOWN au programme et
dans eax il met les coordonnés de
la souris et pour les recuperer on fait :
mov eax,lParam
and eax,0ffffh
mov hitpoint.x,eax
mov eax,lParam
shr eax,16
mov hitpoint.y,eax
alors voila maintenant on va voir si on as clické a l'interieur d'une zone qui sera notre bouton :
.if hitpoint.x > 100 && hitpoint.x < 200 && hitpoint.y > 100 && hitpoint.y < 120
mov but1,TRUE
invoke InvalidateRect,hWnd,NULL,FALSE
.end if
invalidate rectangle sert a faire repaindre la fenetre mais
juste là ou il faut le faire.
but1 est une variable booleéne qui va nous servir a savoir si le
bouton est enfoncé
la limite de la zone est a l'horizontal entre 100 et 200 et a
l'horizontal ente 100 et 120
voila c tout pour WM_LBOUTTONDOWN maintenant on va voir WM_LBUTTONUP, comme vous vous en doutez surement ce msg est envoyé quand le bouton gauche de la souris et relaché (etonnant ! :p ) dans eax est egalement stocké la position de la souris
.if hitpoint.x > 100 && hitpoint.x < 200 && hitpoint.y > 100 && hitpoint.y < 120 && but1
;operation as effectué
.end if.if but1
mov but1, FALSE
invoke InvalidateRect,hWnd,NULL,FALSE
.end if
bon maintenant la partie la plus importante dans notre programme : WM_PAINT
invoke BeginPaint, hWin, ADDR Pnt
mov hDC, eax
invoke ImageList_Draw,hImageList,0,hDC,0,0,0.if but1
invoke ImageList_Draw,hImageBut1,0,hDC,100,100,0
.endifinvoke EndPaint, hDC, ADDR Pnt
hImageList est l'image de fond qui
contient le bouton non enfoncé
hImageBut1 est l'image contenant le bouton enfoncé, 100 et 100
correspondent a l'emplacement x,y du point en haut a gauche de
l'image
JE VEUT DEPLACER MA FENETRE !
quand je n'utilise pas la technique au
dessus pour faire mes boutons, je peut m'utiliser d'une technique
simple pour deplacer la fenetre :
quand le message WM_NCHITTEST est envoyé on fait ça :
mov eax, HTCAPTION
mais helas quand on s'utilise de la technique du dessus, on peut pas faire ça :( donc j'ai du faire autrement :
.elseif uMsg == WM_LBUTTONDOWN
mov eax,lParam
and eax,0ffffh
mov hitpoint.x,eax
mov eax,lParam
shr eax,16
mov hitpoint.y,eax.if hitpoint.x > 100 && hitpoint.x < 200 && hitpoint.y > 100 && hitpoint.y < 120
mov but1,TRUE
invoke InvalidateRect,hWnd,NULL,FALSE
.else
mov move,TRUE
mov eax, hitpoint.x
mov hitpointold.x, eax
mov eax, hitpoint.y
mov hitpointold.y, eax
.endif.elseif uMsg == WM_MOUSEMOVE
invoke GetCursorPos,ADDR hitpoint
mov eax,hitpointold.x
mov ebx,hitpointold.y
sub hitpoint.x,eax
sub hitpoint.y,ebx.if move
invoke SetWindowPos,hWin,NULL,hitpoint.x,hitpoint.y,NULL,NULL,SWP_NOSIZE or SWP_NOZORDER
.endif.elseif uMsg == WM_LBUTTONUP
mov eax,lParam
and eax,0ffffh
mov hitpoint.x,eax
mov eax,lParam
shr eax,16
mov hitpoint.y,eax.if hitpoint.x > 100 && hitpoint.x < 200 && hitpoint.y > 100 && hitpoint.y < 120 && but1
;operation as effectué
.end if.if but1
mov but1, FALSE
invoke InvalidateRect,hWnd,NULL,FALSE
.end if.if move
mov move,FALSE
.endif
en fait c tout con, tant que le bouton gauche est enfoncé, dés que la souris bouge, la fenetre bouge d'autant, probleme, si on donne un coup brusque et qu'on sort de la fenetre et ben on est niqué sa marche plus :( et vu que la fenetre n'est pas carré on ne peut pas clippé la souris a l'interrieur
QUELQUE TRUC POUR FERMER UNE FENETRE AVEC UN BOUTON OU LA REDUIRE
quand on fait de la gui generalement on enleve les boutons system (en haut à droite) et meme generalement toute la barre qui va avec, donc si on veut quitter on doit faire alt+F4 mais j'ai là quelque fonctions interressant :) ! :
pour fermer le programme :
invoke SendMessage,hWin,WM_SYSCOMMAND,SC_CLOSE,NULL
pour reduire la fenetre :
invoke SendMessage,hWin,WM_SYSCOMMAND,SC_MINIMIZE,NULL
et hop je vous rebalance un petit coup de win32.hlp !
SC_CLOSE.......... : Closes the window. This command sends a WM_CLOSE message to the window. The window carries out any steps needed to clean up and destroy itself.
SC_MAXIMIZE . : Maximizes the window.
SC_MINIMIZE .. : Minimizes the window.
SC_RESTORE ... : Restores a minimized or maximized window to its previous size and position.
SC_SIZE ............. : Starts a Size command. The user can change the size of the window by using the mouse or keyboard.
alors .... heureux ?
CROQMORT