Basic Univers
; Author : Denis
; Date :  07/05/07
; Description : Dégradé linéaire avec GDI+

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