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
.endif

invoke 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