[Windows] Change text colour in ButtonGadgets (for XP-skin)

Share your advanced PureBasic knowledge/code with the community.
User avatar
Arctic Fox
Enthusiast
Enthusiast
Posts: 609
Joined: Sun Dec 21, 2008 5:02 pm
Location: Aarhus, Denmark

[Windows] Change text colour in ButtonGadgets (for XP-skin)

Post by Arctic Fox »

Using an image with a depth of 32-bit and a transparent background (thanks to PB 4.40 and PB 4.50 respectively :)) this example shows how to set custom text colours in ButtonGadgets. It will only work properly with XP-skin enabled.

Tested on Windows Vista. A similar method with a ButtonImageGadget() can probably be used for MacOSX and Linux, but I have not tried this.

One question, however :wink:
Can I rely on #WM_SETTEXT as a notification message for text changing?

Please let me know if anything can be improved 8)

Code: Select all

EnableExplicit

Structure ColoredButtonGadgetStructure
  GadgetNumber.i
  EnabledImage.i
  DisabledImage.i
  TextColor.i
  OldProc.i
EndStructure

Global NewMap ColoredButtonGadgetMap.ColoredButtonGadgetStructure()

Procedure ColoredButtonGadgetEnabledImage(GadgetNumber)
  Protected EnabledImage
  
  If Not FindMapElement(ColoredButtonGadgetMap(), Str(GadgetID(GadgetNumber))) : ProcedureReturn 0 : EndIf
  If IsImage(ColoredButtonGadgetMap()\EnabledImage) : FreeImage(ColoredButtonGadgetMap()\EnabledImage) : EndIf
  
  ColoredButtonGadgetMap()\EnabledImage = 0
  
  EnabledImage = CreateImage(#PB_Any, GadgetWidth(GadgetNumber), GadgetHeight(GadgetNumber), 32 | #PB_Image_Transparent)
  
  If StartDrawing(ImageOutput(EnabledImage))
    DrawingMode(#PB_2DDrawing_AlphaBlend | #PB_2DDrawing_Transparent)
    DrawingFont(GetGadgetFont(GadgetNumber))
    DrawText((GadgetWidth(GadgetNumber) - TextWidth(GetGadgetText(GadgetNumber))) / 2, (GadgetHeight(GadgetNumber) - TextHeight(GetGadgetText(GadgetNumber))) / 2, GetGadgetText(GadgetNumber), ColoredButtonGadgetMap()\TextColor + 4278190080)
    StopDrawing()
    
    ColoredButtonGadgetMap()\EnabledImage = EnabledImage
  EndIf
EndProcedure

Procedure ColoredButtonGadgetDisabledImage(GadgetNumber)
  Protected DisabledImage
  
  If Not FindMapElement(ColoredButtonGadgetMap(), Str(GadgetID(GadgetNumber))) : ProcedureReturn 0 : EndIf
  If IsImage(ColoredButtonGadgetMap()\DisabledImage) : FreeImage(ColoredButtonGadgetMap()\DisabledImage) : EndIf
  
  ColoredButtonGadgetMap()\DisabledImage = 0
  
  DisabledImage = CreateImage(#PB_Any, GadgetWidth(GadgetNumber), GadgetHeight(GadgetNumber), 32 | #PB_Image_Transparent)
  
  If StartDrawing(ImageOutput(DisabledImage))
    DrawingMode(#PB_2DDrawing_AlphaBlend | #PB_2DDrawing_Transparent)
    DrawingFont(GetGadgetFont(GadgetNumber))
    DrawText((GadgetWidth(GadgetNumber) - TextWidth(GetGadgetText(GadgetNumber))) / 2, (GadgetHeight(GadgetNumber) - TextHeight(GetGadgetText(GadgetNumber))) / 2, GetGadgetText(GadgetNumber), 4278190080)
    StopDrawing()
    
    ColoredButtonGadgetMap()\DisabledImage = DisabledImage
  EndIf
EndProcedure

Procedure ColoredButtonGadgetProc(Handle, Message, wParam, lParam)
  Protected Result
  
  If Not FindMapElement(ColoredButtonGadgetMap(), Str(Handle)) : ProcedureReturn 0 : EndIf
  
  Select Message
    Case #WM_DESTROY
      Result = CallWindowProc_(ColoredButtonGadgetMap()\OldProc, Handle, Message, wParam, lParam)
      
      If IsImage(ColoredButtonGadgetMap()\DisabledImage) : FreeImage(ColoredButtonGadgetMap()\DisabledImage) : EndIf
      If IsImage(ColoredButtonGadgetMap()\EnabledImage) : FreeImage(ColoredButtonGadgetMap()\EnabledImage) : EndIf
      
      DeleteMapElement(ColoredButtonGadgetMap(), Str(GadgetID(ColoredButtonGadgetMap()\GadgetNumber)))
      
    Case #WM_ENABLE
      If wParam
        SendMessage_(GadgetID(ColoredButtonGadgetMap()\GadgetNumber), #BM_SETIMAGE, #IMAGE_BITMAP, ImageID(ColoredButtonGadgetMap()\EnabledImage))
      Else
        SendMessage_(GadgetID(ColoredButtonGadgetMap()\GadgetNumber), #BM_SETIMAGE, #IMAGE_BITMAP, ImageID(ColoredButtonGadgetMap()\DisabledImage))
      EndIf
      
      Result = CallWindowProc_(ColoredButtonGadgetMap()\OldProc, Handle, Message, wParam, lParam)
      
    Case #WM_SETTEXT
      Result = CallWindowProc_(ColoredButtonGadgetMap()\OldProc, Handle, Message, wParam, lParam)
      
      ColoredButtonGadgetEnabledImage(ColoredButtonGadgetMap()\GadgetNumber)
      ColoredButtonGadgetDisabledImage(ColoredButtonGadgetMap()\GadgetNumber)
      
      If IsWindowEnabled_(GadgetID(ColoredButtonGadgetMap()\GadgetNumber))
        SendMessage_(GadgetID(ColoredButtonGadgetMap()\GadgetNumber), #BM_SETIMAGE, #IMAGE_BITMAP, ImageID(ColoredButtonGadgetMap()\EnabledImage))
      Else
        SendMessage_(GadgetID(ColoredButtonGadgetMap()\GadgetNumber), #BM_SETIMAGE, #IMAGE_BITMAP, ImageID(ColoredButtonGadgetMap()\DisabledImage))
      EndIf
      
    Default
      Result = CallWindowProc_(ColoredButtonGadgetMap()\OldProc, Handle, Message, wParam, lParam)
  EndSelect
  
  ProcedureReturn Result
EndProcedure

Procedure ColoredButtonGadget(GadgetNumber, x, y, Width, Height, Text$, Flags = 0, FrontColor = 0)
  Protected Result = ButtonGadget(GadgetNumber, x, y, Width, Height, Text$, Flags | #BS_BITMAP)
  Protected DisabledImage = CreateImage(#PB_Any, Width, Height, 32 | #PB_Image_Transparent)
  Protected Gadget = GadgetNumber
  
  If GadgetNumber = #PB_Any : Gadget = Result : EndIf
  
  AddMapElement(ColoredButtonGadgetMap(), Str(GadgetID(Gadget)))
  ColoredButtonGadgetMap()\GadgetNumber = Gadget
  ColoredButtonGadgetMap()\TextColor = FrontColor
  
  ColoredButtonGadgetEnabledImage(Gadget)
  ColoredButtonGadgetDisabledImage(Gadget)
  
  ColoredButtonGadgetMap()\OldProc = SetWindowLongPtr_(GadgetID(Gadget), #GWL_WNDPROC, @ColoredButtonGadgetProc())
  SendMessage_(GadgetID(Gadget), #BM_SETIMAGE, #IMAGE_BITMAP, ImageID(ColoredButtonGadgetMap()\EnabledImage))
  
  ProcedureReturn Result
EndProcedure

Procedure SetColoredButtonGadgetColor(GadgetNumber, FrontColor)
  If Not FindMapElement(ColoredButtonGadgetMap(), Str(GadgetID(GadgetNumber))) : ProcedureReturn 0 : EndIf
  
  ColoredButtonGadgetMap()\TextColor = FrontColor
  ColoredButtonGadgetEnabledImage(GadgetNumber)
  
  If IsWindowEnabled_(GadgetID(ColoredButtonGadgetMap()\GadgetNumber))
    SendMessage_(GadgetID(ColoredButtonGadgetMap()\GadgetNumber), #BM_SETIMAGE, #IMAGE_BITMAP, ImageID(ColoredButtonGadgetMap()\EnabledImage))
  EndIf
  
EndProcedure



; Example.
Define Event, Clicked

OpenWindow(0, 100, 100, 300, 300, "")

ButtonGadget(0, 5, 5, 290, 25, "Enable all")
ButtonGadget(1, 5, 35, 290, 25, "Disable all")

ColoredButtonGadget(2, 5, 75, 290, 25, "Blue text color", 0, #Blue)
ColoredButtonGadget(3, 5, 105, 290, 25, "Green text color", 0, #Green)
ColoredButtonGadget(4, 5, 135, 290, 25, "Red text color", 0, #Red)
ColoredButtonGadget(5, 5, 165, 290, 25, "Yellow text color", 0, #Yellow)

ColoredButtonGadget(6, 5, 205, 290, 25, "Random color - click count: 0", 0, Random(16777215))


Repeat
  Event = WaitWindowEvent()
  
  If Event = #PB_Event_Gadget
    Select EventGadget()
      Case 0
        DisableGadget(2, 0)
        DisableGadget(3, 0)
        DisableGadget(4, 0)
        DisableGadget(5, 0)
        DisableGadget(6, 0)
        
      Case 1
        DisableGadget(2, 1)
        DisableGadget(3, 1)
        DisableGadget(4, 1)
        DisableGadget(5, 1)
        DisableGadget(6, 1)
        
      Case 2
        DisableGadget(2, 1)
        
      Case 3
        DisableGadget(3, 1)
        
      Case 4
        DisableGadget(4, 1)
        
      Case 5
        DisableGadget(5, 1)
        
      Case 6
        Clicked + 1
        
        SetColoredButtonGadgetColor(6, Random(16777215))
        SetGadgetText(6, "Random color - click count: " + Str(Clicked))
        
    EndSelect
  EndIf
  
Until Event = #PB_Event_CloseWindow

End
yrreti
Enthusiast
Enthusiast
Posts: 546
Joined: Tue Oct 31, 2006 4:34 am

Re: [Windows] Change text colour in ButtonGadgets (for XP-sk

Post by yrreti »

Thanks much Arctic Fox. :!: :D :D :D
I like it a lot, and can definitely use this.
c4s
Addict
Addict
Posts: 1981
Joined: Thu Nov 01, 2007 5:37 pm
Location: Germany

Re: [Windows] Change text colour in ButtonGadgets (for XP-sk

Post by c4s »

Just tried with ButtonImageGadget() and works just fine (with and without skin):

Code: Select all

Procedure ColoredButtonGadget(GadgetNr, X, Y, Width, Height, Text.s, TextColor=$000000, TextFontID=#PB_Font_Default)
	Protected ImageNr

	If GadgetNr = #PB_Any : ProcedureReturn -1 : EndIf


	ImageNr = CreateImage(#PB_Any, Width, Height, 32 | #PB_Image_Transparent)
	If ImageNr
		StartDrawing(ImageOutput(ImageNr))
			DrawingMode(#PB_2DDrawing_AlphaBlend | #PB_2DDrawing_Transparent)
			DrawingFont(TextFontID)
			DrawText((Width - TextWidth(Text)) / 2, (Height - TextHeight(Text)) / 2, Text, TextColor | $FF000000)
		StopDrawing()

		ButtonImageGadget(GadgetNr, X, Y, Width, Height, ImageID(ImageNr))
	EndIf

	ProcedureReturn ImageNr
EndProcedure


OpenWindow (0, #PB_Ignore, #PB_Ignore, 200, 200, "Button with text color!", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
Debug ColoredButtonGadget(1, 20, 20, 160, 160, "Test Text", $0000FF)  ; Returns ImageNr

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
Maybe PureBasic's SetGadgetColor() should do something like this internally?! I mean it works and beginners & all that forgot about that possibility would think PB isn't able to di it. :D
If any of you native English speakers have any suggestions for the above text, please let me know (via PM). Thanks!
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Re: [Windows] Change text colour in ButtonGadgets (for XP-sk

Post by srod »

Nice.

Thanks for this.
I may look like a mule, but I'm not a complete ass.
User avatar
kernadec
Enthusiast
Enthusiast
Posts: 146
Joined: Tue Jan 05, 2010 10:35 am

Re: [Windows] Change text colour in ButtonGadgets (for XP-sk

Post by kernadec »

Excellent ... thanks

Code: Select all

Enumeration
  #windows
  #ButtonGadget1
  #ButtonGadget2
  #TextGadget1
  #TextGadget2
  #TextGadget3
  #TextGadget4
  #StringGadget1
  #StringGadget2
  #StringGadget3
  #StringGadget4
  #StringGadget5
  #StringGadget6
  #StringGadget7
  #StringGadget8
EndEnumeration
Global cb.l,cf.l,TextColor.l,Textshadow.l,passe.l

Procedure ColoredButtonGadget(GadgetNr,X,Y,Width,Height,Text.s,TextFontID,TextColor,Textshadow)
  Protected ImageNr
  
  If GadgetNr = #PB_Any : ProcedureReturn -1 : EndIf
  
  ImageNr = CreateImage(#PB_Any,Width,Height,32 );| #PB_Image_Transparent
  If ImageNr
    StartDrawing(ImageOutput(ImageNr))
    DrawingMode(#PB_2DDrawing_Gradient) 
    If passe=0
      cb=BackColor(RGB(Random(255),Random(255),Random(255)))
      cf=FrontColor(RGB(Random(255),Random(255),Random(255)))
    Else
      BackColor(cb)
      FrontColor(cf)
    EndIf
    Debug "Back=RGB("+Str(Red(cb))+","+Str(Green(cb))+","+Str(Blue(cb))+") : Front=RGB("+Str(Red(cf))+","+Str(Green(cf))+","+Str(Blue(cf))+")"
    Debug "TextColor=RGB("+Str(Red(TextColor))+","+Str(Green(TextColor))+","+Str(Blue(TextColor))+") : Textshadow=RGB("+Str(Red(Textshadow))+","+Str(Green(Textshadow))+","+Str(Blue(Textshadow))+")"
    BoxedGradient(0,0,Width,Height)   
    ;LinearGradient(0,0,Width,Height)
    ;EllipticalGradient(Width/2,Height/2,Width/2,Height/3)
    Box(0,0,Width,Height)
    DrawingMode(#PB_2DDrawing_AlphaBlend | #PB_2DDrawing_Transparent)
    DrawingFont(TextFontID)
    DrawText((Width - TextWidth(Text)) / 2+1,(Height - TextHeight(Text)) / 2-1,Text,Textshadow | $FF000000)
    DrawText((Width - TextWidth(Text)) / 2,(Height - TextHeight(Text)) / 2,Text,TextColor | $FF000000)
    StopDrawing()
    
    ButtonImageGadget(GadgetNr,X,Y,Width,Height,ImageID(ImageNr))
  EndIf
  
  ProcedureReturn ImageNr
EndProcedure

OpenWindow (#windows,#PB_Ignore,#PB_Ignore,200,300,"Button with text color!",#PB_Window_SystemMenu | #PB_Window_ScreenCentered)
Text.s="Thanks"

TextGadget(#TextGadget1,20,20,80,20,"Text RGB:")
TextGadget(#TextGadget2,20,43,80,20,"ShadeTx RGB:")
TextGadget(#TextGadget3,20,242,40,20,"Back:")
TextGadget(#TextGadget4,20,267,40,20,"Front:")

StringGadget(#StringGadget1,95,15,25,20,"180",#PB_String_Numeric)
StringGadget(#StringGadget2,125,15,25,20,"128",#PB_String_Numeric)
StringGadget(#StringGadget3,155,15,25,20,"0",#PB_String_Numeric)

StringGadget(#StringGadget4,95,40,25,20,"50",#PB_String_Numeric)
StringGadget(#StringGadget5,125,40,25,20,"50",#PB_String_Numeric)
StringGadget(#StringGadget6,155,40,25,20,"50",#PB_String_Numeric)

StringGadget(#StringGadget7,60,240,120,20,"RGB("+Str(Red(cb))+","+Str(Green(cb))+","+Str(Blue(cb))+")",#PB_String_ReadOnly )
StringGadget(#StringGadget8,60,265,120,20,"RGB("+Str(Red(cf))+","+Str(Green(cf))+","+Str(Blue(cf))+")",#PB_String_ReadOnly )

TextColor=RGB(Val(GetGadgetText(#StringGadget1)),Val(GetGadgetText(#StringGadget2)),Val(GetGadgetText(#StringGadget3)))
Textshadow=RGB(Val(GetGadgetText(#StringGadget4)),Val(GetGadgetText(#StringGadget5)),Val(GetGadgetText(#StringGadget6)))

ColoredButtonGadget(#ButtonGadget1,20,70,160,160,Text,LoadFont(1,"Arial",26,#PB_Font_Bold),TextColor,Textshadow)  ; Returns ImageNr
ButtonGadget(#ButtonGadget2,73,16,20,20,"?")
SetGadgetText(#StringGadget7,"RGB("+Str(Red(cb))+","+Str(Green(cb))+","+Str(Blue(cb))+")")
SetGadgetText(#StringGadget8,"RGB("+Str(Red(cf))+","+Str(Green(cf))+","+Str(Blue(cf))+")")
Repeat 
  event= WaitWindowEvent()
  Select EventGadget()
    Case #ButtonGadget1
      passe=0
      If Text="Thanks":Text="Merci":Else:Text="Thanks":EndIf
      TextColor=RGB(Val(GetGadgetText(#StringGadget1)),Val(GetGadgetText(#StringGadget2)),Val(GetGadgetText(#StringGadget3)))
      Textshadow=RGB(Val(GetGadgetText(#StringGadget4)),Val(GetGadgetText(#StringGadget5)),Val(GetGadgetText(#StringGadget6)))
      ColoredButtonGadget(#ButtonGadget1,20,70,160,160,Text,LoadFont(1,"Arial",26,#PB_Font_Bold),TextColor,Textshadow)
      SetGadgetText(#StringGadget7,"RGB("+Str(Red(cb))+","+Str(Green(cb))+","+Str(Blue(cb))+")")
      SetGadgetText(#StringGadget8,"RGB("+Str(Red(cf))+","+Str(Green(cf))+","+Str(Blue(cf))+")")
    Case  #ButtonGadget2
      passe=1
      If Text="Thanks":Text="Merci":Else:Text="Thanks":EndIf
      TextColor=RGB(Val(GetGadgetText(#StringGadget1)),Val(GetGadgetText(#StringGadget2)),Val(GetGadgetText(#StringGadget3)))
      Textshadow=RGB(Val(GetGadgetText(#StringGadget4)),Val(GetGadgetText(#StringGadget5)),Val(GetGadgetText(#StringGadget6)))
      ColoredButtonGadget(#ButtonGadget1,20,70,160,160,Text,LoadFont(1,"Arial",26,#PB_Font_Bold),TextColor,Textshadow)
      SetGadgetText(#StringGadget7,"RGB("+Str(Red(cb))+","+Str(Green(cb))+","+Str(Blue(cb))+")")
      SetGadgetText(#StringGadget8,"RGB("+Str(Red(cf))+","+Str(Green(cf))+","+Str(Blue(cf))+")")
  EndSelect
Until event= #PB_Event_CloseWindow


;#;new  procedure ........

;#Procedure ColoredButtonGadget(GadgetNr,X,Y,Width,Height,Text.s,TextFontID,cf,cb,TextColor,Textshadow)
;#Protected ImageNr
;# If GadgetNr = #PB_Any : ProcedureReturn -1 : EndIf
;# ImageNr = CreateImage(#PB_Any,Width,Height,32 );| #PB_Image_Transparent
;# If ImageNr
;#   StartDrawing(ImageOutput(ImageNr))
;#   DrawingMode(#PB_2DDrawing_Gradient) 
;#   BackColor(cb)
;#   FrontColor(cf)
;#   BoxedGradient(0,0,Width,Height)      
;#   Box(0,0,Width,Height)
;#   DrawingMode(#PB_2DDrawing_AlphaBlend | #PB_2DDrawing_Transparent)
;#   DrawingFont(TextFontID)
;#   DrawText((Width - TextWidth(Text)) / 2+1,(Height - TextHeight(Text)) / 2-1,Text,Textshadow | $FF000000)
;#   DrawText((Width - TextWidth(Text)) / 2,(Height - TextHeight(Text)) / 2,Text,TextColor | $FF000000)
;#   StopDrawing()
;#   ButtonImageGadget(GadgetNr,X,Y,Width,Height,ImageID(ImageNr))
;# EndIf
;# 
;#ProcedureReturn ImageNr
;#EndProcedure
;#Global cb.l,cf.l,TextColor.l,Textshadow.l,front.l,back.l
;#OpenWindow (0,#PB_Ignore,#PB_Ignore,200,200,"Button with text color!",#PB_Window_SystemMenu | #PB_Window_ScreenCentered);#
;#
;#;------------- copy 2 lines debugger: ----------------
;#Back=RGB(78,89,221) : Front=RGB(185,211,38)
;#TextColor=RGB(180,128,0) : Textshadow=RGB(50,50,50)
;#;-----------------------------------------------------
;#ColoredButtonGadget(1,20,20,160,160,"CANCEL",LoadFont(1,"Arial",26,#PB_Font_Bold),front,back,TextColor,Textshadow)
;#
;#Repeat 
;#  event= WaitWindowEvent()
;#  Select EventGadget()
;#    Case 1
;#  EndSelect
;#Until event= #PB_Event_CloseWindow

good day
Last edited by kernadec on Wed Jul 07, 2010 10:35 pm, edited 4 times in total.
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: [Windows] Change text colour in ButtonGadgets (for XP-sk

Post by Kwai chang caine »

kernadec wrote:Excellent ... thanks

Code: Select all

Procedure ColoredButtonGadget(GadgetNr, X, Y, Width, Height, Text.s,TextFontID, TextColor=$000000)
  .....
  .....
  .....
  .....
  .....
  .....

Until event= #PB_Event_CloseWindow
good day
Woooouuuaaaaouu !!!! :shock:
Your button has more color than mine when I had measles :mrgreen:
Great great job 8)
ImageThe happiness is a road...
Not a destination
User avatar
kernadec
Enthusiast
Enthusiast
Posts: 146
Joined: Tue Jan 05, 2010 10:35 am

Re: [Windows] Change text colour in ButtonGadgets (for XP-sk

Post by kernadec »

hello, KCC
code search button effect
updated code
@ KCC I must thank C4S but especially the work and the idea of Arctic Fox

good day
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: [Windows] Change text colour in ButtonGadgets (for XP-sk

Post by Kwai chang caine »

Hello Kernadec :wink:

Bravo at you three 8)
Very nice button :shock:
ImageThe happiness is a road...
Not a destination
Post Reply