Page 1 of 1

TextGadget Transparent Background

Posted: Tue May 10, 2016 9:09 pm
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

Re: TextGadget Transparent Background

Posted: Tue May 10, 2016 9:25 pm
by RSBasic

Re: TextGadget Transparent Background

Posted: Wed May 11, 2016 6:08 am
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.

Re: TextGadget Transparent Background

Posted: Wed May 11, 2016 8:32 am
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

Re: TextGadget Transparent Background

Posted: Thu May 12, 2016 1:51 am
by ozzie
Many thanks.

Re: TextGadget Transparent Background

Posted: Fri May 13, 2016 4:42 pm
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.

Re: TextGadget Transparent Background

Posted: Fri May 13, 2016 7:11 pm
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.

Re: TextGadget Transparent Background

Posted: Sat May 14, 2016 2:23 am
by ozzie
Thanks for the updates - all useful code.

Re: TextGadget Transparent Background

Posted: Wed Jan 03, 2024 3:29 pm
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.

Re: TextGadget Transparent Background

Posted: Wed Jan 03, 2024 4:26 pm
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.

Re: TextGadget Transparent Background

Posted: Wed Jan 03, 2024 4:52 pm
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


Re: TextGadget Transparent Background

Posted: Wed Jan 03, 2024 5:28 pm
by RASHAD
BTW
I just discovered that the problem is with PB 6.04 not with Windows :wink:
Tested fine with PB 5.72

Re: TextGadget Transparent Background

Posted: Wed Jan 03, 2024 5:32 pm
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.