TextGadget Transparent Background

Just starting out? Need help? Post your questions and find answers here.
User avatar
singo
User
User
Posts: 35
Joined: Mon Apr 23, 2007 4:50 am
Location: Nabiac NSW Australia

TextGadget Transparent Background

Post by singo »

Just wondering if anyone knew some code that would make a normal textgadget's background color transparent.

This is for Windows, but xplatform would be nice, I want to display some (changeable) text over a picture without a background color to the text.

Could probably turn the text into a graphic, I know...

Thanks
Singo
Win10, Win7, Debian x86 & OSX ~ PB 5.70 LTS
Minimbah NSW Australia
User avatar
RSBasic
Moderator
Moderator
Posts: 1228
Joined: Thu Dec 31, 2009 11:05 pm
Location: Gernsbach (Germany)
Contact:

Re: TextGadget Transparent Background

Post by RSBasic »

Image
Image
ozzie
Enthusiast
Enthusiast
Posts: 443
Joined: Sun Apr 06, 2008 12:54 pm
Location: Brisbane, Qld, Australia
Contact:

Re: TextGadget Transparent Background

Post by ozzie »

Thanks - could be useful. Any advice on how to set the text color? SetGadgetColor(...) seems to be ignored, although SetGadgetFont(...) is processed OK.
User avatar
RSBasic
Moderator
Moderator
Posts: 1228
Joined: Thu Dec 31, 2009 11:05 pm
Location: Gernsbach (Germany)
Contact:

Re: TextGadget Transparent Background

Post by RSBasic »

Code: Select all

EnableExplicit

Procedure WCB(WindowID, Message, wParam, lParam)
  Select Message
    Case #WM_CTLCOLORSTATIC
      Select lparam
        Case GadgetID(1)
          SetBkMode_(wparam, #TRANSPARENT)
          SetTextColor_(wparam, RGB(255, 0, 0))
          ProcedureReturn GetStockObject_(#HOLLOW_BRUSH)
      EndSelect
  EndSelect
  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

If OpenWindow(0, 0, 0, 500, 250, "Window", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  TextGadget(1, 10, 10, 400, 20, "Transparenter Text", 0)
  
  SetWindowColor(0, RGB(255, 255, 0))
  SetWindowCallback(@WCB(), 0)
  
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Image
Image
ozzie
Enthusiast
Enthusiast
Posts: 443
Joined: Sun Apr 06, 2008 12:54 pm
Location: Brisbane, Qld, Australia
Contact:

Re: TextGadget Transparent Background

Post by ozzie »

Many thanks.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: TextGadget Transparent Background

Post by netmaestro »

I can't let this one go by without offering my two cents. This code has been kicking around the forums for at least as long as I've been here and that's ten years. But there's a hole in it you could drive a truck through. It looks fine and dandy until you go to change the text to something different. Then you realize that the hollow brush won't erase what was there before and everything turns to crap. Here's the code with a 2-second timer added that will change the text. See what happens when the timer fires:

Code: Select all

Procedure WCB(WindowID, Message, wParam, lParam)
  Select Message
    Case #WM_CTLCOLORSTATIC
      Select lparam
        Case GadgetID(1)
          SetBkMode_(wparam, #TRANSPARENT)
          SetTextColor_(wparam, RGB(255, 0, 0))
          ProcedureReturn GetStockObject_(#HOLLOW_BRUSH)
      EndSelect
  EndSelect
  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

If OpenWindow(0, 0, 0, 500, 250, "Window", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  TextGadget(1, 10, 10, 400, 20, "Transparenter Text", 0)
  AddWindowTimer(0,1,2000)
  
  SetWindowColor(0, RGB(255, 255, 0))
  SetWindowCallback(@WCB(), 0)
  
  Repeat 
    ev = WaitWindowEvent()
    If ev = #PB_Event_Timer
      SetGadgetText(1, "Hello World!")
    EndIf
    
  Until ev = #PB_Event_CloseWindow
EndIf
So how to fix it? The problem is the hollow brush. A null brush is no better and so this is the way I approach it when I need transparency:

1. Create a background brush for the window. It can be a solid color, pattern or image. Apply it to the main window.
2. Create a background brush for the gadget from the image used for the window.
3. Return your gadget background from #WM_CTLCOLORSTATIC instead of the hollow or null brush.
4. Update your gadget background brush any time the gadget is moved or sized.

Here is a sample with the above approach applied:

Code: Select all

Global imgWindowBackground, hBrWindowBackground0, hBrGadgetBackground1

Procedure CreateWindowBackground(windownumber)
  imgWindowBackground = CreateImage(#PB_Any, WindowWidth(windownumber), WindowHeight(windownumber), 24)
  StartDrawing(ImageOutput(imgWindowBackground))
  DrawingMode(#PB_2DDrawing_Gradient)
  FrontColor(#Black)
  BackColor(#White)
  LinearGradient(0, 0, ImageWidth(imgWindowBackground), ImageHeight(imgWindowBackground))
  Box(0,0,ImageWidth(imgWindowBackground), ImageHeight(imgWindowBackground))
  StopDrawing()
  hBrWindowBackground0 = CreatePatternBrush_(ImageID(imgWindowBackground))
EndProcedure

Procedure GetGadgetBackground(gadgetnumber)
  this_image = GrabImage(imgWindowBackground, #PB_Any, GadgetX(gadgetnumber), GadgetY(gadgetnumber), GadgetWidth(gadgetnumber), GadgetHeight(gadgetnumber))
  If hBrGadgetBackground1
    DeleteObject_(hBrGadgetBackground1)
  EndIf
  hBrGadgetBackground1 = CreatePatternBrush_(ImageID(this_image))
  FreeImage(this_image)
EndProcedure

Procedure WCB(WindowID, Message, wParam, lParam)
  Select Message
    Case #WM_CTLCOLORSTATIC
      Select lparam
        Case GadgetID(1)
          SetBkMode_(wparam, #TRANSPARENT)
          SetTextColor_(wparam, RGB(255, 0, 0))
          ProcedureReturn hBrGadgetBackground1
      EndSelect
  EndSelect
  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

If OpenWindow(0, 0, 0, 500, 250, "Window", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  CreateWindowBackground(0)
  SetClassLongPtr_(WindowID(0), #GCL_HBRBACKGROUND, hBrWindowBackground0)
  InvalidateRect_(WindowID(0),0,1)
  TextGadget(1, 200, 100, 200, 20, "Transparenter Text")
  GetGadgetBackground(1)
  SetWindowCallback(@WCB(), 0)
  InvalidateRect_(GadgetID(1),0,1)
    
  AddWindowTimer(0,1,1000)

  Repeat 
    ev = WaitWindowEvent()
    If ev = #PB_Event_Timer
      ResizeGadget(1, Random(300), Random(200), #PB_Ignore, #PB_Ignore)
      GetGadgetBackground(1) 
      SetGadgetText(1, "Hello World! "+Str(Random(100000)))
    EndIf
    
  Until ev = #PB_Event_CloseWindow
EndIf

DeleteObject_(hBrWindowBackground0)
DeleteObject_(hBrGadgetBackground1)
Now it's gonna work and you've got total control.
BERESHEIT
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4946
Joined: Sun Apr 12, 2009 6:27 am

Re: TextGadget Transparent Background

Post by RASHAD »

Hi NM
Thanks for the catch

# 1:

Code: Select all

Procedure WCB(WindowID, Message, wParam, lParam)
  Select Message      
    Case #WM_CTLCOLORSTATIC
      Select lparam
        Case GadgetID(1)
          SetBkMode_(wparam, #TRANSPARENT)
          SetTextColor_(wparam, RGB(255, 0, 0))          
          ProcedureReturn GetStockObject_(#NULL_BRUSH	)
      EndSelect
  EndSelect
  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

If OpenWindow(0, 0, 0, 500, 250, "Window", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  TextGadget(1, 10, 10, 400, 20, "Transparenter Text")
  ButtonGadget(2,10,210,40,20,"TEST")
  AddWindowTimer(0,1,5000)
 
  SetWindowColor(0, RGB(255, 255, 0))
  SetWindowCallback(@WCB(), 0)
 
Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Quit = 1
      
    Case #PB_Event_Timer
      InvalidateRect_(WindowID(0),0,1)
      SetGadgetText(1, "Firing Timer")
      
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 2
          InvalidateRect_(WindowID(0),0,1)
          SetGadgetText(1, "Hello World 4 Second Time")
      EndSelect
  EndSelect   
Until Quit = 1
EndIf
#2:

Code: Select all

#ODT_STATIC  = 5

Global Text$

Procedure winCB(hWnd, uMsg, wParam, lParam)
 Result = #PB_ProcessPureBasicEvents
  Select uMsg  
   Case #WM_DRAWITEM
    *lpdis.DRAWITEMSTRUCT = lParam
      Select *lpdis\CtlType
       Case #ODT_STATIC
        hdc=GetDC_(GadgetID(0))
        SetBkMode_(hdc, #TRANSPARENT)
        SetTextColor_(hdc,$0000FF)
        TextOut_(hdc, 0, 0, @Text$, Len(Text$))
      EndSelect
  EndSelect
 ProcedureReturn Result
EndProcedure

If OpenWindow(0, 0,0, 400, 200, "OwnerDrawing ",  #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  SetWindowCallback(@winCB())
  SetWindowColor(0,#Yellow)
  Text$ = "Test Text"   
  TextGadget(0,10,10,190,20,"",#SS_OWNERDRAW)
  ButtonGadget(1,10,170,40,20,"Test")
  SetGadgetText(0,Text$)
EndIf
Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Quit = 1
      
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 1
          InvalidateRect_(WindowID(0),0,1)
          text ! 1
          If text = 1
            Text$ = "New Text"
          Else
            text$ = "Back to Normal"
          EndIf
          SetGadgetText(0,Text$)
      EndSelect
  EndSelect
Until Quit = 1
End
Edit : Added another tech.
Egypt my love
ozzie
Enthusiast
Enthusiast
Posts: 443
Joined: Sun Apr 06, 2008 12:54 pm
Location: Brisbane, Qld, Australia
Contact:

Re: TextGadget Transparent Background

Post by ozzie »

Thanks for the updates - all useful code.
Lebostein
Addict
Addict
Posts: 826
Joined: Fri Jun 11, 2004 7:07 am

Re: TextGadget Transparent Background

Post by Lebostein »

I have tried all these examples with Win 11. The TextGadget is never transparent. Has anything changed with Win 11? I need a code to make various text gadgets (and if possible check box gadgets) transparent.
ebs
Enthusiast
Enthusiast
Posts: 557
Joined: Fri Apr 25, 2003 11:08 pm

Re: TextGadget Transparent Background

Post by ebs »

Lebostein wrote: Wed Jan 03, 2024 3:29 pm I have tried all these examples with Win 11. The TextGadget is never transparent. Has anything changed with Win 11? I need a code to make various text gadgets (and if possible check box gadgets) transparent.
That's odd - I'm running Windows 11 Pro and the text gadget is transparent with both #1 and #2 from @Rashad.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4946
Joined: Sun Apr 12, 2009 6:27 am

Re: TextGadget Transparent Background

Post by RASHAD »

Hi
It seems that something changed with Windows 11 the latest update
Workaround for such situations
Tested with PB 6.04 x86 and Windows 11 x64

Code: Select all

Procedure winCB(hWnd,uMsg, wParam, lParam)
  Select uMsg      
    Case #WM_CTLCOLORSTATIC
      SetBkMode_(wParam,#TRANSPARENT)
      SetTextColor_(wParam,$0000FF)
      ProcedureReturn GetStockObject_(#HOLLOW_BRUSH)
  EndSelect
  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

If OpenWindow(0, 0, 0, 500, 250, "TextGadget Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  TextGadget(1, 10, 10, 400, 20, "Transparent Text Gadget")  
  
  AddWindowTimer(0,125,5000)
  
  hBrush = CreateSolidBrush_($00FFFF)
  SetClassLongPtr_(WindowID(0),#GCL_HBRBACKGROUND,hBrush)
  InvalidateRect_(WindowID(0),0,1)
  
  SetWindowCallback(@winCB())
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        Quit = 1
        
      Case #PB_Event_Timer
        Run ! 1
        If Run = 1
          InvalidateRect_(WindowID(0),0,1)
          SetGadgetText(1, "Firing Timer")
        Else
          InvalidateRect_(WindowID(0),0,1)
          SetGadgetText(1, "Transparent Text Gadget")
        EndIf
    EndSelect   
  Until Quit = 1
EndIf

Egypt my love
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4946
Joined: Sun Apr 12, 2009 6:27 am

Re: TextGadget Transparent Background

Post by RASHAD »

BTW
I just discovered that the problem is with PB 6.04 not with Windows :wink:
Tested fine with PB 5.72
Egypt my love
ebs
Enthusiast
Enthusiast
Posts: 557
Joined: Fri Apr 25, 2003 11:08 pm

Re: TextGadget Transparent Background

Post by ebs »

RASHAD wrote: Wed Jan 03, 2024 5:28 pm BTW
I just discovered that the problem is with PB 6.04 not with Windows :wink:
Tested fine with PB 5.72
That makes sense - I was testing with an older PB version also, so either way works.
Post Reply