Dégradé linéaire

Partagez votre expérience de PureBasic avec les autres utilisateurs.
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Dégradé linéaire

Message par Anonyme2 »

Voici un code qui pourra servir, on met un dégradé linéaire en couleur de fond d'une fenêtre, le dégradé est défini par une couleur de départ et la couleur d'arrivée, pour l'exemple c'est dans la callback, l'élément vert(0) du tableau est la couleur de départ et vert(1) la couleur d'arrivée, X et Y définissent le point de départ et le point d'arrivé du rectangle à remplir. Je ne rempli qu'à partir de la position Y = 100, ce qui est avant est mis en blanc avec SetWindowColor().

reportez-vous à la doc MS pour l'API GradientFill.

Dans l'exemple, au départ le dernier paramètre vaut #GRADIENT_FILL_RECT_V, le dégradé est vertical, si vous mettez #GRADIENT_FILL_RECT_H, il sera horizontal, c'est ce que fait le bouton, alternativement horizontal/vertical

Code : Tout sélectionner

EnableExplicit

Enumeration
   ; fenêtre
   #Fenetre
   ; gadget
   #Frame3DGadget = 0
   #bouton
EndEnumeration

#WindowTitle = "Dégradé linéaire"

Global FenetreID.l       ; WindowID(#Fenetre)
Global Largeur_Fenetre.l ; largeur de la fenêtre #Fenetre
Global Hauteur_Fenetre.l ; hauteur de la fenêtre #Fenetre
Global hauteur_FenetreBlanche.l = 100 ; Hauteur de la fenêtre blanche
Global OldProc.l         ; l'adresse de la procedure callback de windows
Global WindowEvent.l     ; mémorise l'événement
Global sens = #GRADIENT_FILL_RECT_V  ; sens du dégradé


; Import-File created by Lib2PBImport
; Libname: msimg32.lib
; created: 2007/05/06  18:19

Import "msimg32.lib"
GradientFill(a.l, b.l, c.l, d.l, e.l, f.l) As "_GradientFill@24"
EndImport

Procedure myCallback(window, message, wParam, lParam)
   Protected dc.l, ps.PAINTSTRUCT, lpRect.RECT
   Protected Dim vert.TRIVERTEX(1)
   Protected gRect.GRADIENT_RECT
   
   Select message
      Case #WM_PAINT
         dc = BeginPaint_(window, @ps)
         If dc
            If GetClientRect_(window, @lpRect)
               vert(0)\x = 0
               vert(0)\y = hauteur_FenetreBlanche
               vert(0)\Red = $2B00
               vert(0)\Green = $3900
               vert(0)\Blue = $4400
               vert(0)\Alpha = $FF00
               
               vert(1)\x = lpRect\right
               vert(1)\y = lpRect\bottom
               vert(1)\Red = $9F00
               vert(1)\Green = $D200
               vert(1)\Blue = $FA00
               vert(1)\Alpha = $FF00
               
               gRect\UpperLeft = 0
               gRect\LowerRight = 1
               GradientFill(dc, @vert(), 2, @gRect, 1, sens)
               
            EndIf
            EndPaint_(window, @ps)
            ProcedureReturn 0
         EndIf
   EndSelect
   ProcedureReturn CallWindowProc_(OldProc, window, message, wParam, lParam)
EndProcedure


Largeur_Fenetre = 600
Hauteur_Fenetre = Largeur_Fenetre / 1.618033988
If OpenWindow(#Fenetre, 0, 0, Largeur_Fenetre, Hauteur_Fenetre, #WindowTitle, #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_Invisible)
   SetWindowColor(#Fenetre, #White)
   
   ; initialisation variables
   FenetreID = WindowID(#Fenetre)
   
   If CreateGadgetList(FenetreID)
      Frame3DGadget(#Frame3DGadget, 0, hauteur_FenetreBlanche, WindowWidth(#Fenetre), 1, "", #PB_Frame3D_Flat)
      
      ButtonGadget(#bouton, 40, 320, 100, 30, "Sens du dégradé")
      
      HideWindow(#Fenetre, 0)
      OldProc = SetWindowLong_(WindowID(#Fenetre), #GWL_WNDPROC, @myCallback())
      Repeat
         WindowEvent = WaitWindowEvent()
         Select WindowEvent
            Case #PB_Event_CloseWindow
               Break
            Case #PB_Event_Gadget
               If sens = #GRADIENT_FILL_RECT_V
                  sens = #GRADIENT_FILL_RECT_H
               Else
                  sens = #GRADIENT_FILL_RECT_V
               EndIf
               RedrawWindow_(WindowID(#Fenetre), 0, 0,  #RDW_INVALIDATE)
         EndSelect
      ForEver
   EndIf
EndIf
End
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

La même chose avec GDI+, pas besoin d'avoir le wrapper, j'ai mis les fonctions nécessaires dans le code. Si vous n'avez pas GDI+ d'installé, le code ne fait rien.

Il y a plus de possibilités avec GDI+, en particulier les 4 modes horizontal, vertical, et les 2 en diagonale sont dispos avec des appuis successifs sur le bouton. Mais on pourrait faire beaucoup plus d'effets avec les différentes fonctions de GDI+.

Code : Tout sélectionner

EnableExplicit

Enumeration
   ; fenêtre
   #Fenetre
   ; gadget
   #Frame3DGadget = 0
   #bouton
EndEnumeration

#WindowTitle = "Dégradé linéaire"

;- LinearGradientMode
#LinearGradientModeHorizontal = 0
#LinearGradientModeVertical = 1
#LinearGradientModeForwardDiagonal = 2
#LinearGradientModeBackwardDiagonal = 3

;- WrapMode
#WrapModeTile = 0
#WrapModeTileFlipX = 1
#WrapModeTileFlipY = 2
#WrapModeTileFlipXY = 3
#WrapModeClamp = 4

;- Status
#Ok = 0

;- GdiplusStartupInput
Structure GdiplusStartupInput ;{
   GdiPlusVersion.l
   *DebugEventCallback.DebugEventProc
   SuppressBackgroundThread.l
   SuppressExternalCodecs.l
EndStructure ;}

;- GdiplusStartupOutput
Structure GdiplusStartupOutput ;{
   *NotificationHook.NotificationHookProc
   *NotificationUnhook.NotificationUnhookProc
EndStructure ;}


Global FenetreID.l ; WindowID(#Fenetre)
Global Largeur_Fenetre.l ; largeur de la fenêtre #Fenetre
Global Hauteur_Fenetre.l ; hauteur de la fenêtre #Fenetre
Global hauteur_FenetreBlanche.l = 100 ; Hauteur de la fenêtre blanche
Global OldProc.l ; l'adresse de la procedure callback de windows
Global WindowEvent.l ; mémorise l'événement
Global sens = #LinearGradientModeVertical ; sens du dégradé


; teste si GDI+ est présent
If Not(OpenLibrary(0, "Gdiplus.dll"))
   MessageRequester("Erreur/Error", "GDI+ n'est pas présent/GDI+ is not installed" + Chr(10) + "vous devez d'abord l'installer/you must first install it      ", 16)
   End
EndIf
CloseLibrary(0)



Import "gdiplus.lib" ;{
;- init
GdiplusStartup(*token, *input.GdiplusStartupInput, *output.GdiplusStartupOutput)
GdiplusShutdown(*token)
GdipCreateLineBrushFromRectI(*rect.Rect, color1.l, color2.l, mode.l, wrapMode.l, *lineGradient)
GdipCreateFromHDC(hdc.l, *graphics)
GdipDeleteBrush(*brush)
GdipDeleteGraphics(*graphics)
GdipFillRectangleI(*graphics, *brush, x.l, y.l, width.l, height.l)
EndImport ;}



Procedure.l Gdiplus_New(version.l = 1, *hEventCB = #Null, Codecs.l = #False, bgThread.l = #False)
   Protected *token, input.GdiplusStartupInput
   input\GdiPlusVersion = version
   input\DebugEventCallback = *hEventCB
   input\SuppressExternalCodecs = Codecs
   input\SuppressBackgroundThread = bgThread
   GdiplusStartup( @*token, @input, #Null)
   ProcedureReturn *token
EndProcedure


Procedure myCallback(window, message, wParam, lParam)
   Protected dc.l, ps.PAINTSTRUCT, lpRect.RECT, rc_Interior.RECT
   Protected *token, *graphics, *brush, couleur_Depart.l, couleur_arriver.l
   
   Select message
      Case #WM_PAINT
         dc = BeginPaint_(window, @ps)
         If dc
            ; initialisation de Gdi+
            *token = Gdiplus_New()
            ; on vérifie que l'initialisation est Ok
            If *token
               If GdipCreateFromHDC(dc, @*graphics) = #Ok
                  If GetClientRect_(window, @lpRect)
                     rc_Interior\left = 0
                     rc_Interior\right = lpRect\right
                     rc_Interior\top = hauteur_FenetreBlanche
                     rc_Interior\bottom = lpRect\bottom
                     
                     
                     couleur_Depart = $FF2B3944
                     couleur_arriver = $FF9FD2FA
                     
                     GdipCreateLineBrushFromRectI( @rc_Interior, couleur_Depart, couleur_arriver, sens, #WrapModeTileFlipX, @*brush)
                     ; remplissage du rectangle intérieur
                     GdipFillRectangleI(*graphics, *brush, rc_Interior\left, rc_Interior\top, rc_Interior\right - rc_Interior\left, rc_Interior\bottom - rc_Interior\top)
                     GdipDeleteBrush(*brush)
                     
                  EndIf
                  GdipDeleteGraphics(*graphics)
               EndIf
               GdiplusShutdown(*token)
            EndIf
            EndPaint_(window, @ps)
            
            ProcedureReturn 0
         EndIf
   EndSelect
   ProcedureReturn CallWindowProc_(OldProc, window, message, wParam, lParam)
EndProcedure


Largeur_Fenetre = 600
Hauteur_Fenetre = Largeur_Fenetre / 1.618033988
If OpenWindow(#Fenetre, 0, 0, Largeur_Fenetre, Hauteur_Fenetre, #WindowTitle, #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_Invisible)
   SetWindowColor(#Fenetre, #White)
   
   ; initialisation variables
   FenetreID = WindowID(#Fenetre)
   
   If CreateGadgetList(FenetreID)
      Frame3DGadget(#Frame3DGadget, 0, hauteur_FenetreBlanche, WindowWidth(#Fenetre), 1, "", #PB_Frame3D_Flat)
      
      ButtonGadget(#bouton, 40, 320, 100, 30, "Sens du dégradé")
      
      HideWindow(#Fenetre, 0)
      OldProc = SetWindowLong_(WindowID(#Fenetre), #GWL_WNDPROC, @myCallback())
      Repeat
         WindowEvent = WaitWindowEvent()
         Select WindowEvent
            Case #PB_Event_CloseWindow
               Break
            Case #PB_Event_Gadget
               sens + 1
               If sens > #LinearGradientModeBackwardDiagonal
                  sens = #LinearGradientModeHorizontal
               EndIf
               Debug sens
               RedrawWindow_(WindowID(#Fenetre), 0, 0, #RDW_INVALIDATE)
         EndSelect
      ForEver
   EndIf
EndIf
End
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

ce serai pas mal si Fred incluait une librairie GDI dans purebasic :D
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

Il y a la librairie GDI qui est commune à tous les windows et il y a GDI+ qui n'est distribué qu'à partir de XP mais qui peut être installé sous W98 etc.

J'ai pratiquement fini l'ensemble des fonctions GDI+ au niveau de la doc (2 ne seront pour l'instant pas expliqué car moi pas comprendre :D ), ça demandera surement des éclaircissement et des ajouts voire des corrections, car c'est pas toujours simple à expliquer.

Il me reste les chapitres à compléter , je pense encore un bon mois de travail.
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

Denis a écrit :Il y a la librairie GDI qui est commune à tous les windows et il y a GDI+ qui n'est distribué qu'à partir de XP mais qui peut être installé sous W98 etc.

J'ai pratiquement fini l'ensemble des fonctions GDI+ au niveau de la doc (2 ne seront pour l'instant pas expliqué car moi pas comprendre :D ), ça demandera surement des éclaircissement et des ajouts voire des corrections, car c'est pas toujours simple à expliquer.

Il me reste les chapitres à compléter , je pense encore un bon mois de travail.
cool ! :D

tu crois que Fred accepterai d'inclure ton travail a Purebasic
histoire d'avoir ces possibilités en Natif ? :D

Pour Purebasic 5.00 ?? :lol:


PS: j'ai inserré tes 2 codes dans mon Forum "CodeFR" :D .. Merci :)
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

Dobro a écrit :
Denis a écrit :Il y a la librairie GDI qui est commune à tous les windows et il y a GDI+ qui n'est distribué qu'à partir de XP mais qui peut être installé sous W98 etc.

J'ai pratiquement fini l'ensemble des fonctions GDI+ au niveau de la doc (2 ne seront pour l'instant pas expliqué car moi pas comprendre :D ), ça demandera surement des éclaircissement et des ajouts voire des corrections, car c'est pas toujours simple à expliquer.

Il me reste les chapitres à compléter , je pense encore un bon mois de travail.
cool ! :D

tu crois que Fred accepterai d'inclure ton travail a Purebasic
histoire d'avoir ces possibilités en Natif ? :D

Pour Purebasic 5.00 ?? :lol:
Non je ne pense pas, ce n'est pas le but et en fait c'est pas des commandes PureBasic mais c'est des API.
Au départ je voulais faire une librairie mais après discussion avec Fred sur les imports (fonctions importés avec import) je ne le ferais pas car l'avantage des imports est de convertir automatiquement la chaine en unicode si c'est spécifié dans la déclaration d'import. Actuellement, ce n'est pas possible avec la création de librairie, donc je reste sur un fichier PB avec les commandes en import. Plusieurs fonctions de GDI+ utilisent exclusivement des chaines unicode.

Il ne reste plus que l'imagination pour utiliser les fonctions...
Répondre