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
, j'ai pas fait de tests pour les boutons non XP mais il doit être assez simple de coloriser les boutons non XP
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
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
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