Page 1 of 1

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

Posted: Mon Jun 07, 2010 1:58 pm
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

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

Posted: Mon Jun 07, 2010 2:48 pm
by yrreti
Thanks much Arctic Fox. :!: :D :D :D
I like it a lot, and can definitely use this.

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

Posted: Mon Jul 05, 2010 12:03 am
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

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

Posted: Mon Jul 05, 2010 10:19 am
by srod
Nice.

Thanks for this.

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

Posted: Mon Jul 05, 2010 3:05 pm
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

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

Posted: Mon Jul 05, 2010 6:03 pm
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)

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

Posted: Tue Jul 06, 2010 9:26 am
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

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

Posted: Tue Jul 06, 2010 12:05 pm
by Kwai chang caine
Hello Kernadec :wink:

Bravo at you three 8)
Very nice button :shock: