GDIPLUS.DLL

Partagez votre expérience de PureBasic avec les autres utilisateurs.
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message par Flype »

à mais non, suis-je bete, j'avais mal regardé.

en fait, il faut absolument le savoir :

avec GDIPLUS toute couleur est sous la forme AARRVVBB car il supporte l'alpha (0 à 255 aussi).

donc il faut utiliser la Macro dans l'include :

MAKECOLOR(100, 255, 0, 0) plutot que RGB(255, 0, 0)

Code : Tout sélectionner

Macro MAKECOLOR(a,r,g,b)
  ((b)|(g)<<8|(r)<<16|(a)<<24)
EndMacro
ou

Code : Tout sélectionner

Macro ARGB(Alpha, RGB) 
  (Blue(RGB)|Green(RGB)<<8|Red(RGB)<<16|Alpha<<24) 
EndMacro
ou encore mieux (dans mon include actuelle) :

Code : Tout sélectionner

ProcedureDLL.l ARGB(rgb.l, a.b = 255) ; $00RRGGBB --> $AABBGGRR
  !MOV eax, [p.v_rgb]
  !BSWAP eax 
  !SHR eax, 8 
  !MOV [p.v_rgb], eax 
  !MOV eax, [p.v_a]
  !MOV dword [p.v_rgb+3], eax
  ProcedureReturn rgb
EndProcedure
ProcedureDLL.l ABGR(bgr.l, a.b = 255) ; $00BBGGRR --> $AABBGGRR
  !MOV eax, [p.v_a]
  !MOV dword [p.v_bgr+3], eax
  ProcedureReturn bgr
EndProcedure
et là comme par magie çà fonctionne :wink:
Image
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

Ah la galère, j'arrive toujours pas à utiliser la fonction. :evil:

Code : Tout sélectionner

XIncludeFile "gdiplus.pbi" 

If OpenWindow(0, 0, 0, 640, 480, "GdiPlus 1.0", #PB_Window_SystemMenu|#PB_Window_ScreenCentered) 

  SetWindowColor(0, #Blue) 
  
  *token = Gdiplus_New() 
  
  GdipCreatePen1(ARGB(#White, 4), 30, 30, @*pen) 
  
  *gfx = Gdiplus_StartDrawing(WindowOutput(0)) 
      GdipDrawEllipseI(*gfx, *pen, 50, 50, 100, 100) 
  Gdiplus_StopDrawing() 
        
        
  Repeat 
    Select WaitWindowEvent() 
      Case #WM_MOUSEMOVE 

      Case #PB_Event_CloseWindow 
        Break 
    EndSelect 
  ForEver 
  
  GdipDeletePen(*pen) 
  Gdiplus_Del(*token) 

EndIf 
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message par Flype »

ah, bah faut lire la doc MSDN sinon tu aura encore à peu près 10000 nouvelles surprises. :D
http://msdn.microsoft.com/library/defau ... s/unit.asp

le 3ème argument de GdipCreatePen1() est en 'unit', pas en pixel ;-)

Code : Tout sélectionner

XIncludeFile "gdiplus.pbi" 

Enumeration 0 ; unit
  #UnitWorld 
  #UnitDisplay 
  #UnitPixel 
  #UnitPoint 
  #UnitInch 
  #UnitDocument 
  #UnitMillimeter 
EndEnumeration

If OpenWindow(0, 0, 0, 640, 480, "GdiPlus 1.0", #PB_Window_SystemMenu|#PB_Window_ScreenCentered) 
  
  SetWindowColor(0, #Blue) 
  
  *token = Gdiplus_New() 
  
  GdipCreatePen1(ARGB(#White, 4), 30, #UnitPixel, @*pen) 
  
  Repeat 
    Select WaitWindowEvent() 
      Case #WM_MOUSEMOVE 
        *gfx = Gdiplus_StartDrawing(WindowOutput(0)) 
        GdipDrawEllipseI(*gfx, *pen, WindowMouseX(0), WindowMouseY(0), 100, 100) 
        Gdiplus_StopDrawing() 
      Case #PB_Event_CloseWindow 
        Break 
    EndSelect 
  ForEver 
  
  GdipDeletePen(*pen) 
  Gdiplus_Del(*token) 
  
EndIf
Image
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

Merci pour tes explications, et pour le package que tu as fais ça aide beaucoup bien que je ne comprenne pas complètement ce que j'écris.

Je souhaiterais que tu m'aides si tu peux sur un dernier point; j'aimerais dans ce code ci-dessous mettre une image pour remplir l'ellipse; je n'ai pas trouvé comment faire dans les exemples fournis:

Code : Tout sélectionner

XIncludeFile "gdiplus.pbi"

If OpenWindow(0, 0, 0, 640, 480, "GdiPlus 1.0", #PB_Window_SystemMenu|#PB_Window_ScreenCentered) 
  
  *token = Gdiplus_New()
  
  GdipCreateFromHWND(WindowID(0), @*gfx)
    
  Dim pt.Point(3)
  
  pt(0)\x = 0
  pt(0)\y = 0
  pt(1)\x = 200
  pt(1)\y = 0
  pt(2)\x = 200
  pt(2)\y = 200
  pt(3)\x = 0
  pt(3)\y = 200
  
  GdipCreatePathGradientI(@pt(0), 4, #WrapModeTile, @*path)
  GdipSetPathGradientCenterColor(*path, MakeColor(255,0,0,255))
  
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        Break
      Case #PB_Event_Repaint
        GdipFillEllipseI(*gfx, *path, 0, 0, WindowWidth(0), WindowHeight(0))
    EndSelect  
  ForEver
  
  GdipDeleteBrush(*path)
  GdipDeleteGraphics(*gfx)
  GdiplusShutdown(*token)
  
EndIf 
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

En attendant, j'ai suivi ton conseil (faire un tour sur MSDN :lol: )
et donc voici le code pour utiliser créer un brush à partir d'un bitmap:


XIncludeFile "gdiplus.pbi"

If OpenWindow (0, 0, 0, 640, 480, "GdiPlus 1.0" , #PB_Window_SystemMenu|#PB_Window_ScreenCentered )
  
  *token = Gdiplus_New()
  
  GdipCreateFromHWND( WindowID (0), @*gfx)
  
  GdipCreateBitmapFromFile( "GDIPlusData\1.wmf" , @*image)
  GdipCreateTexture(*image, #WrapModeTile ,@*TextureImage)
  
  
   Repeat
     Select WaitWindowEvent ()
       Case #PB_Event_CloseWindow
        Break
       Case #PB_Event_Repaint
        GdipFillEllipseI(*gfx, *TextureImage, 100, 100, 200, 200)
     EndSelect
  ForEver
  
  GdipDeleteBrush(*TextureImageimage)
  GdipDeleteGraphics(*gfx)
  GdiplusShutdown(*token)
  
EndIf

Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

Flype a écrit : ou encore mieux (dans mon include actuelle) :

Code : Tout sélectionner

ProcedureDLL.l ARGB(rgb.l, a.b = 255) ; $00RRGGBB --> $AABBGGRR
  !MOV eax, [p.v_rgb]
  !BSWAP eax 
  !SHR eax, 8 
  !MOV [p.v_rgb], eax 
  !MOV eax, [p.v_a]
  !MOV dword [p.v_rgb+3], eax
  ProcedureReturn rgb
EndProcedure

ProcedureDLL.l ABGR(bgr.l, a.b = 255) ; $00BBGGRR --> $AABBGGRR
  !MOV eax, [p.v_a]
  !MOV dword [p.v_bgr+3], eax
  ProcedureReturn bgr
EndProcedure
:wink:
Voici une petite optimisation

Code : Tout sélectionner

ProcedureDLL.l ARGB(rgb.l, a.b = 255)   ; $??RRGGBB --> $AABBGGRR avec AA = a
  ; retourne à partir d'une valeur RGB, la valeur convertie en BGR
  ; avec la couche alpha passée par a,  avec opacité complète par défaut (a = 255)
  
  !MOV   eax, [p.v_rgb]   ; eax = $??RRGGBB avec ?? = couche alpha d'origine
  !SHL   eax, 8           ; eax = $RRGGBB00
  !MOV   al, [p.v_a]      ; eax = $RRGGBBAA avec AA = a
  !BSWAP eax              ; eax = $AABBGGRR
  !RET   8                ; pour terminer tout de suite
EndProcedure


ProcedureDLL.l ABGR(bgr.l, a.b = 255) ; $??xxxxxx --> $AAxxxxxx avec AA = a
  ; Modifie la valeur alpha de la couleur quelque soit le type
  ; RGB ou BGR avec opacité complète par défaut (a = 255)
  
  !MOV al, [p.v_a] 
  !MOV [p.v_bgr+3], al
  !MOV eax, [p.v_bgr] 
  !RET   8                ; pour terminer tout de suite
EndProcedure
Même si ABGR semble avoir plus d'instructions, au final après transformation par PB, il y a une instruction de moins d'effectuée

Il y a peut-être mieux, à suivre :D
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message par Flype »

j'étais sur qu'un jour tu me la retaperais cette fonction. :D
d'ailleurs j'attendais secrètement que tu me l'optimises. :wink:
Image
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

J'ai essayé d'en faire une macro car ça irait plus vite mais je ne suis arrivé à rien. Je pensais que Fred aurais utilisé les macro de FASM mais au moins pour ce qui est simple ce n'est pas le cas, c'est problématique de récupérer le passage d'arguments des macros en ASM.
erix14
Messages : 480
Inscription : sam. 27/mars/2004 16:44
Contact :

Message par erix14 »

Je me suis penché sur votre problème d'optimisation (pour la procedure ARGB). J'ai réussi à faire une macro. :)
@Denis, ton !RET 8 à la fin de la procédure, c'est bien... mais dans une boucle for de 100000, ta procédure plante. :? Pour mon test de rapidité, j'ai dû remettre un retour normal.

Code : Tout sélectionner

Structure couleur
     b.b
     g.b
     r.b
     a.b
EndStructure
Structure ARGB
     StructureUnion
          rgb.l
          c.couleur
     EndStructureUnion
EndStructure

Procedure.l ARGB2(rgb.l, a.b = 255)   ; $??RRGGBB --> $AABBGGRR avec AA = a
  ; retourne à partir d'une valeur RGB, la valeur convertie en BGR
  ; avec la couche alpha passée par a,  avec opacité complète par défaut (a = 255)
 
  !MOV   Eax, [p.v_rgb]   ; eax = $??RRGGBB avec ?? = couche alpha d'origine
  !SHL   Eax, 8           ; eax = $RRGGBB00
  !MOV   al, [p.v_a]      ; eax = $RRGGBBAA avec AA = a
  !BSWAP Eax              ; eax = $AABBGGRR
  !RET   8                ; pour terminer tout de suite
EndProcedure

Macro ARGB_macro(var,aa)
     (aa<<24|var\c\b<<16|var\c\g<<8|var\c\r)
EndMacro

Couleur.ARGB\rgb = $112233
Alpha.b = $FF

;/   Test de la vitesse
;/   Avec procedure
Time1 = GetTickCount_()
For t=1 To 50000000
     tmp1 = ARGB2(Couleur\rgb,$FF)
     tmp2 = ARGB2(Couleur\rgb,Alpha)
Next
Time2 = GetTickCount_()
;/  Avec macro
For t=1 To 50000000
     tmp3 = ARGB_macro(Couleur,$FF)
     tmp4 = ARGB_macro(Couleur,Alpha)
Next
Time3 = GetTickCount_()
;/        Resultat
Message$ = "Avec procedure : "+Str(Time2-Time1)+" ms"+Chr(13)
Message$ + "     Avec paramètres : variable, constante :  "+Hex(tmp1)+Chr(13)
Message$ + "     Avec paramètres : variable, variable :  "+Hex(tmp2)+Chr(13)

Message$ + "Avec macro : "+Str(Time3-Time2)+" ms"+Chr(13)
Message$ + "     Avec paramètres : variable, constante :  "+Hex(tmp3)+Chr(13)
Message$ + "     Avec paramètres : variable, variable :  "+Hex(tmp4)

MessageRequester("Test de vitesse",Message$,#PB_MessageRequester_Ok) 
Dernière modification par erix14 le mar. 29/août/2006 8:38, modifié 2 fois.
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message par Dr. Dri »

@erix14
mets les expressions de tes macros entre parenthèse pour éviter des éventuels problèmes de priorité de calcul si tu utilises tes macros dans des expressions

Dri
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

erix14 a écrit : @Denis, ton !RET 8 à la fin de la procédure, c'est bien... mais dans une boucle for de 100000, ta procédure plante. :? Pour mon test de rapidité, j'ai dû remettre un retour normal.

Code : Tout sélectionner

[/quote]

Salut Erix14, 
C'est bizarre ce plantage car le procedurereturn sans rien derrière ajoute un JMP à un RET 8. Le RET 8 force simplement le retour sans effectuer le JMP

Je vais essayer de voir ce qui cloche  :roll:

Les 2 procedures plantent ?
erix14
Messages : 480
Inscription : sam. 27/mars/2004 16:44
Contact :

Message par erix14 »

En fait, ça plante seulement avec le débogueur. J'ai mis à jour mon code dans le poste plus haut, donc à utiliser avec le débogueur off. :mrgreen:
Ce n'est pas la première fois que je constate des dysfonctionnements du débogueur avec des codes contenant de l'assembleur... :?
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

:D

Merci pour l'indo, toujours bon à savaoir
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

Avec procedure

703 ms (idem pour les 2)

avec macros

422 ms (idem pour les 2)
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Boutons XP couleur avec Brush GDI+

Message par Anonyme2 »

Voici un petit code pour coloriser les boutons XP (tous les cas ne sont pas prévus, en autre le survol et les boutons par défaut) avec des fonction GDI

Je n'ai pas encore regardé les fonctions des font et d'écriture mais ça vient :D

Un grand Merci à Flype pour son fichier d'impotr GDI + qui est nécessaire pour faire tourner mon code.

Je me répète, ça ne tourne que sous XP, j'ai pas fait de tests pour les boutons non XP mais il doit être assez simple de coloriser les boutons non XP

Il faut utiliser le fichier de Flype et y rajouter la brush suivante :

Code : Tout sélectionner

   GdipCreateLineBrushFromRectI(*rc, fgCol.l, bgCol.l, mode.l, wrapMode.l, *lineGradient)
dans la zone d'import des fonctions de la Dll

Ceux qui s'interessent à GDI n'auront pas trop de mal à comprendre, c'est proche du code standart.

J'ai aussi détourné une de ses procédure (Gdiplus_New) pour écrire la mienne Gdiplus_NewEx

J'ai commenté un peu le code

Je stocke les données propres à chaque bouton dans une liste chaînée (il y a pas mal de paramètres et on pourrait en ajouter d'autres) et j'utilise SetgadgetData pour stocker l'adresse de l'élément correspondant et dans la callback il suffit de se repositionner sur le bon élément avec un GetgadgetData qui va bien :D

Code : Tout sélectionner

XIncludeFile "gdiplus.pbi"

EnableExplicit

Enumeration
     #MainWindow
     #Bouton1 = 0
     #Bouton2
     #Bouton3
     #Bouton4
     #Bouton5
     #Bouton6
EndEnumeration

Enumeration
     #Ok = 0
     #GenericError = 1
     #InvalidParameter = 2
     #OutOfMemory = 3
     #ObjectBusy = 4
     #InsufficientBuffer = 5
     #NotImplemented = 6
     #Win32Error = 7
     #WrongState = 8
     #Aborted = 9
     #FileNotFound = 10
     #ValueOverflow = 11
     #AccessDenied = 12
     #UnknownImageFormat = 13
     #FontFamilyNotFound = 14
     #FontStyleNotFound = 15
     #NotTrueTypeFont = 16
     #UnsupportedGdiplusVersion = 17
     #GdiplusNotInitialized = 18
     #PropertyNotFound = 19
     #PropertyNotSupported = 20
     #ProfileNotFound = 21
EndEnumeration

Enumeration 0 ; LinearGradientMode
     #LinearGradientModeHorizontal
     #LinearGradientModeVertical
     #LinearGradientModeForwardDiagonal
     #LinearGradientModeBackwardDiagonal
EndEnumeration

; UxTheme :  Part = PushButton --> States
#PBS_NORMAL = 1
#PBS_HOT = 2
#PBS_PRESSED = 3
#PBS_DISABLED = 4
#PBS_DEFAULTED = 5

; UxTheme : Button type
#BP_PUSHBUTTON = 1
#BP_RADIOBUTTON = 2
#BP_CHECKBOX = 3
#BP_GROUPBOX = 4
#BP_USERBUTTON = 5

; styles boutons
#BS_MULTILINE = $2000
#BS_BOTTOM = $800 
#BS_CENTER = $300 
#BS_MULTILINE = $2000 
#BS_TOP = $400
#BS_VCENTER = $C00
#BS_ICON = $40 
#BS_BITMAP = $80
#BS_FLAT = $8000
#DT_SINGLELINE = $20
#BS_LEFT = $100
#BS_RIGHT = $200

Structure OwnerDrawButtton
     StatiqueID.l ; #Gadget du bouton
     NormalBkGndUpperColor.l ; couleur du gradient supérieur mode normal
     NormalBkGndLowerColor.l ; couleur du gradient inférieur mode normal
     SelectedBkGndUpperColor.l ; couleur du gradient supérieur mode bouton selectionné
     SelectedBkGndLowerColor.l ; couleur du gradient inférieur mode bouton selectionné
     HotBkGndUpperColor.l ; couleur du gradient supérieur mode normal
     HotBkGndLowerColor.l ; couleur du gradient inférieur mode normal
     TextColor.l ; Couleur du texte bouton normal
     SelectedTextColor.l ; Couleur du texte bouton sélectionné
     HotTextColor.l ; Couleur du texte  bouton survolé
     LinearGradientMode.l ; Type du gradient
EndStructure


Global NewList Bouton.OwnerDrawButtton()
Global i.l, App.s

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

Procedure ButtonCallback(WindowID, Message, wParam, lParam)
     Protected partID.l, stateID.l, hTheme.l, ButtonText.s
     Protected LargeurBouton.l, HauteurBouton.l, hBmpTampon.l
     Protected BoutonStyle.l, TexteStyle.l, Font.l, textWidth.l, textHeight.l
     Protected TextColor.l, Color1.l, Color2.l, hdcMem.l, SavedDC.l
     Protected rc_Interior.RECT
     Protected *di.DRAWITEMSTRUCT = lParam
     Protected *token.l, *gfx.l, *brush.l
     
     Select Message
               
               ;- #WM_DRAWITEM
          Case #WM_DRAWITEM
               If *di\CtlType = #ODT_BUTTON
                    ; sélectionne l'élément de la liste chaînée ou se trouve
                    ; les valeurs correspondant à chaque bouton
                    If Not((*di\itemState & #ODS_DISABLED = #ODS_DISABLED))
                       ChangeCurrentElement(Bouton(), GetGadgetData(*di\CtlID))
                    EndIf
                    If *di\itemState & #ODS_SELECTED = #ODS_SELECTED
                         partID	 = #BP_PUSHBUTTON
                         If Bouton()\LinearGradientMode = #LinearGradientModeHorizontal
                              stateID = #PBS_NORMAL
                         Else
                              stateID = #PBS_PRESSED
                         EndIf
                         TextColor = Bouton()\SelectedTextColor
                         Color1 = Bouton()\SelectedBkGndUpperColor
                         Color2 = Bouton()\SelectedBkGndLowerColor
                    ElseIf (*di\itemState & #ODS_DISABLED = #ODS_DISABLED) Or (*di\itemState & #ODS_GRAYED = #ODS_GRAYED)
                         partID	 = #BP_PUSHBUTTON
                         stateID = #PBS_DISABLED
                         TextColor = GetSysColor_(#COLOR_GRAYTEXT)
                         Color1 = #White
                         Color2 = GetSysColor_(#COLOR_BTNFACE)
                    ElseIf *di\itemState & #ODS_HOTLIGHT = #ODS_HOTLIGHT
                         partID	 = #BP_PUSHBUTTON
                         stateID = #PBS_HOT
                         TextColor = Bouton()\HotTextColor
                         Color1 = Bouton()\HotBkGndUpperColor
                         Color2 = Bouton()\HotBkGndLowerColor
                    ElseIf *di\itemState & #ODS_DEFAULT = #ODS_DEFAULT
                         partID	 = #BP_PUSHBUTTON
                         stateID = #PBS_DEFAULTED
                         TextColor = Bouton()\TextColor
                         Color1 = Bouton()\NormalBkGndUpperColor
                         Color2 = Bouton()\NormalBkGndLowerColor
                    Else ; sans état ou en mode #ODS_FOCUS
                         partID	 = #BP_PUSHBUTTON
                         stateID = #PBS_NORMAL
                         TextColor = Bouton()\TextColor
                         Color1 = Bouton()\NormalBkGndUpperColor
                         Color2 = Bouton()\NormalBkGndLowerColor
                    EndIf
                    
                    LargeurBouton = *di\rcItem\right - *di\rcItem\left
                    HauteurBouton = *di\rcItem\bottom - *di\rcItem\top
                    hdcMem = CreateCompatibleDC_(*di\hDC)
                    hBmpTampon = CreateCompatibleBitmap_(*di\hDC, GetDeviceCaps_(*di\hDC, #HORZRES), GetDeviceCaps_(*di\hDC, #VERTRES))
                    If hdcMem And hBmpTampon
                         SavedDC = SaveDC_(*di\hDC)
                         SelectObject_(hdcMem, hBmpTampon)
                         *token = Gdiplus_NewEx()
                         If *token < #Ok Or *token > #ProfileNotFound
                              ; création du graphique à partir du DC en mémoire et non celui du bouton
                              ; pour éviter des problèmes de scintiment lorsque les boutons sont redessinés
                              GdipCreateFromHDC(hdcMem, @*gfx)
                              hTheme = OpenThemeData_(WindowID, @App)
                              ; on récupère le le theme XP du bouton
                              If hTheme
                                   ; on dessine le fond du bouton avec les bords
                                   DrawThemeParentBackground_(*di\hwndItem, hdcMem, *di\rcItem)
                                   DrawThemeBackground_(hTheme, hdcMem, partID, stateID, *di\rcItem, 0)
                                   ; on récupère les coordonnées du rectangle intérieur du bouton
                                   GetThemeBackgroundContentRect_(hTheme, *di\hDC, partID, stateID, *di\rcItem, @rc_Interior)
                                   ; création de la brush
                                   GdipCreateLineBrushFromRectI(@rc_Interior, ARGB(Color1), ARGB(Color2), Bouton()\LinearGradientMode, #WrapModeTileFlipX, @*brush)
                                   ; on réduit le rectangle intérieur de 1 pixel
                                   rc_Interior\left + 1
                                   rc_Interior\right - 1
                                   rc_Interior\top + 1
                                   rc_Interior\bottom - 1
                                   ; remplissage du rectangle intérieur
                                   GdipFillRectangleI(*gfx, *brush, rc_Interior\left, rc_Interior\top, rc_Interior\right - rc_Interior\left, rc_Interior\bottom - rc_Interior\top)
                                   GdipDeleteBrush(*brush)
                                   
                                   ; écriture du texte du bouton
                                   ButtonText = GetGadgetText(*di\CtlID)
                                   
                                   If Len(ButtonText)
                                        ; couleur texte , fond transparent
                                        SetTextColor_(hdcMem, TextColor)
                                        SetBkMode_(hdcMem, #TRANSPARENT)
                                        Font = GetGadgetFont(*di\CtlID)
                                        SelectObject_(hdcMem, Font)
                                        ; lecture du style du bouton
                                        BoutonStyle = 0
                                        BoutonStyle = GetWindowLong_(*di\hwndItem, #GWL_STYLE)
                                        If BoutonStyle & #BS_RIGHT
                                             TexteStyle | #DT_RIGHT
                                        ElseIf BoutonStyle & #BS_LEFT
                                             TexteStyle | #DT_LEFT
                                        Else
                                             TexteStyle | #DT_CENTER
                                        EndIf
                                        
                                        If (Not(BoutonStyle & #BS_MULTILINE))
                                             TexteStyle | #DT_SINGLELINE | #DT_WORDBREAK | #DT_VCENTER
                                        Else
                                             TexteStyle | #DT_WORDBREAK
                                             ; calcul du rectangle du texte à centrer et centrage
                                             DrawText_(hdcMem, @ButtonText, -1, @rc_Interior, #DT_CALCRECT | TexteStyle)
                                             textWidth = rc_Interior\right - rc_Interior\left
                                             textHeight = rc_Interior\bottom - rc_Interior\top
                                             rc_Interior\left = (LargeurBouton - textWidth) / 2
                                             rc_Interior\right = rc_Interior\left + textWidth
                                             rc_Interior\top = (HauteurBouton - textheight) / 2
                                             rc_Interior\bottom = rc_Interior\top + textheight
                                        EndIf
                                        
                                        ; on écrit le texte
                                        DrawTextEx_(hdcMem, @ButtonText, -1, @rc_Interior, TexteStyle | #DT_EXPANDTABS | #DT_NOCLIP, 0)
                                   EndIf
                                   ; on copie le hDC de la mémoire vers celui du bouton
                                   BitBlt_(*di\hDC, 0, 0, LargeurBouton, HauteurBouton, hdcMem, 0, 0, #SRCCOPY)
                                   ; on ferme le theme XP
                                   CloseThemeData_(hTheme)
                              EndIf
                              GdipDeleteGraphics(*gfx)
                              Gdiplus_Del(*token)
                         EndIf
                         DeleteDC_(hdcMem)
                         DeleteObject_(hBmpTampon)
                         RestoreDC_(*di\hDC, SavedDC)
                    EndIf
               EndIf
     EndSelect
     ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

If OpenWindow(#MainWindow, 0, 0, 480, 360, "GdiPlus 1.0 - XP buttons color", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
     If CreateGadgetList(WindowID(#MainWindow))
          
          ; premier bouton
          If AddElement(Bouton())
               Bouton()\StatiqueID = #Bouton1 ; #Gadget du bouton
               Bouton()\NormalBkGndUpperColor = #Yellow ; couleur du gradient supérieur mode normal
               Bouton()\NormalBkGndLowerColor = #Blue ; couleur du gradient inférieur mode normal
               Bouton()\SelectedBkGndUpperColor = #Blue ; couleur du gradient supérieur mode bouton selectionné
               Bouton()\SelectedBkGndLowerColor = #Yellow ; couleur du gradient inférieur mode bouton selectionné
               ; Bouton()\HotBkGndUpperColor  =     ; couleur du gradient supérieur mode normal
               ; Bouton()\HotBkGndLowerColor  =     ; couleur du gradient inférieur mode normal
               Bouton()\TextColor = #White ; Couleur du texte bouton normal
               Bouton()\SelectedTextColor = #White ; Couleur du texte bouton sélectionné
               ; Bouton()\HotTextColor          ; Couleur du texte  bouton survolé
               Bouton()\LinearGradientMode = #LinearGradientModeVertical ; Type du gradient
          EndIf
          
          If AddElement(Bouton())
               Bouton()\StatiqueID = #Bouton2 ; #Gadget du bouton
               Bouton()\NormalBkGndUpperColor = #White ; couleur du gradient supérieur mode normal
               Bouton()\NormalBkGndLowerColor = #Red ; couleur du gradient inférieur mode normal
               Bouton()\SelectedBkGndUpperColor = #Red ; couleur du gradient supérieur mode bouton selectionné
               Bouton()\SelectedBkGndLowerColor = #White ; couleur du gradient inférieur mode bouton selectionné
               Bouton()\HotBkGndUpperColor = #White ; couleur du gradient supérieur mode normal
               Bouton()\HotBkGndLowerColor = $979DBE ; couleur du gradient inférieur mode normal
               Bouton()\TextColor = #White ; Couleur du texte bouton normal
               Bouton()\SelectedTextColor = #White ; Couleur du texte bouton sélectionné
               Bouton()\HotTextColor = #Black ; Couleur du texte  bouton survolé
               Bouton()\LinearGradientMode = #LinearGradientModeHorizontal ; Type du gradient
          EndIf
          
          If AddElement(Bouton())
               Bouton()\StatiqueID = #Bouton3 ; #Gadget du bouton
               Bouton()\NormalBkGndUpperColor = #White ; couleur du gradient supérieur mode normal
               Bouton()\NormalBkGndLowerColor = #Blue ; couleur du gradient inférieur mode normal
               Bouton()\SelectedBkGndUpperColor = #Blue ; couleur du gradient supérieur mode bouton selectionné
               Bouton()\SelectedBkGndLowerColor = #White ; couleur du gradient inférieur mode bouton selectionné
               ; Bouton()\HotBkGndUpperColor  =     ; couleur du gradient supérieur mode normal
               ; Bouton()\HotBkGndLowerColor  =     ; couleur du gradient inférieur mode normal
               Bouton()\TextColor = #White ; Couleur du texte bouton normal
               Bouton()\SelectedTextColor = #Black ; Couleur du texte bouton sélectionné
               ; Bouton()\HotTextColor          ; Couleur du texte  bouton survolé
               Bouton()\LinearGradientMode = #LinearGradientModeVertical ; Type du gradient
          EndIf
          
          If AddElement(Bouton())
               Bouton()\StatiqueID = #Bouton4 ; #Gadget du bouton
               Bouton()\NormalBkGndUpperColor = #White ; couleur du gradient supérieur mode normal
               Bouton()\NormalBkGndLowerColor = $C5C47F ; couleur du gradient inférieur mode normal
               Bouton()\SelectedBkGndUpperColor = $C5C47F ; couleur du gradient supérieur mode bouton selectionné
               Bouton()\SelectedBkGndLowerColor = #White ; couleur du gradient inférieur mode bouton selectionné
               ; Bouton()\HotBkGndUpperColor  =     ; couleur du gradient supérieur mode normal
               ; Bouton()\HotBkGndLowerColor  =     ; couleur du gradient inférieur mode normal
               Bouton()\TextColor = #Red ; Couleur du texte bouton normal
               Bouton()\SelectedTextColor = #Black ; Couleur du texte bouton sélectionné
               ; Bouton()\HotTextColor          ; Couleur du texte  bouton survolé
               Bouton()\LinearGradientMode = #LinearGradientModeForwardDiagonal ; Type du gradient
          EndIf
          
          If AddElement(Bouton())
               Bouton()\StatiqueID = #Bouton5 ; #Gadget du bouton
               Bouton()\NormalBkGndUpperColor = #White ; couleur du gradient supérieur mode normal
               Bouton()\NormalBkGndLowerColor = $C5C47F ; couleur du gradient inférieur mode normal
               Bouton()\SelectedBkGndUpperColor = $C5C47F ; couleur du gradient supérieur mode bouton selectionné
               Bouton()\SelectedBkGndLowerColor = #White ; couleur du gradient inférieur mode bouton selectionné
               ; Bouton()\HotBkGndUpperColor  =     ; couleur du gradient supérieur mode normal
               ; Bouton()\HotBkGndLowerColor  =     ; couleur du gradient inférieur mode normal
               Bouton()\TextColor = #Red ; Couleur du texte bouton normal
               Bouton()\SelectedTextColor = #Black ; Couleur du texte bouton sélectionné
               ; Bouton()\HotTextColor          ; Couleur du texte  bouton survolé
               Bouton()\LinearGradientMode = #LinearGradientModeBackwardDiagonal ; Type du gradient
          EndIf

          ; création de la string unicode pour récupérer le theme XP des boutons
          App.s = Space((Len("Button") * 2)+1)
          PokeS(@App, "Button", -1, #PB_Unicode)
          
          ButtonGadget(#Bouton1, 50, 50, 170, 50, "Bouton  XP  OWNERDRAW", #BS_OWNERDRAW)
          ButtonGadget(#Bouton2, 250, 50, 170, 50, "Bouton  XP MULTILIGNES A VOIR", #BS_OWNERDRAW | #PB_Button_Default | #PB_Button_MultiLine)
          ButtonGadget(#Bouton3, 250, 150, 170, 50, "Bouton  XP  OWNERDRAW", #BS_OWNERDRAW)
          ButtonGadget(#Bouton4, 50, 150, 170, 50, "Bouton  XP  OWNERDRAW", #BS_OWNERDRAW)
          ButtonGadget(#Bouton5, 50, 250, 170, 50, "Bouton  XP  OWNERDRAW", #BS_OWNERDRAW)
          ButtonGadget(#Bouton6, 250, 250, 170, 50, "Bouton  XP  OWNERDRAW", #BS_OWNERDRAW)
          SetGadgetFont(#Bouton2, LoadFont(0, "ARIAL", 9, #PB_Font_Bold))
          DisableGadget(#Bouton6, 1)
          
          FirstElement(Bouton())
          For i = #Bouton1 To #Bouton6
               SetGadgetData(Bouton()\StatiqueID, @Bouton())
               NextElement(Bouton())
          Next i
          
          SetWindowCallback( @ButtonCallback())
          Repeat
               Select WaitWindowEvent()
                    Case #PB_Event_Gadget
                          Select EventGadget()
                               Case #Bouton2
                                    MessageRequester("Infos","ID : #Bouton2"+Chr(10)+"Gradient mode: #LinearGradientModeHorizontal",16)
                               Case #Bouton3
                                    MessageRequester("Infos","ID : #Bouton3"+Chr(10)+"Gradient mode: #LinearGradientModeVertical",16)
                               Case #Bouton4
                                    MessageRequester("Infos","ID : #Bouton4"+Chr(10)+"Gradient mode: #LinearGradientModeForwardDiagonal",16)
                               Case #Bouton5
                                    MessageRequester("Infos","ID : #Bouton5"+Chr(10)+"Gradient mode: #LinearGradientModeBackwardDiagonal",16)
                          EndSelect
                    Case #PB_Event_CloseWindow : Break
               EndSelect
          ForEver
     EndIf
EndIf
Répondre