TextGadget on PanelGadget with panels with background color

Just starting out? Need help? Post your questions and find answers here.
Lima
User
User
Posts: 43
Joined: Tue Jul 14, 2015 2:52 pm

TextGadget on PanelGadget with panels with background color

Post by Lima »

The code I put together below works fine with PB 6.01.
With PB 6.02 the TextGadget(10,50,60,100,20,"ddgdfswewe") has a black background color, and nothing can be read.
The solutions I found are using ImageGadget() or ContainerGadget() to get the background color of the PanelGadget, or activating the commented line in the code SetGadgetColor(10,#PB_Gadget_BackColor,$ABABAB).
Any of these solutions requires changing many points of the application.
Is there a simpler solution?
Or wait for this problem to be fixed in future versions?

(The problem was found on Win 10 and Win 11.)

Thanks in advance for any ideas.

Code: Select all

 
 If OpenWindow(0, 0, 0, 322, 220, "PanelGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    PanelGadget     (0, 8, 8, 306, 203)
      AddGadgetItem (0, -1, "Panel 1")
        PanelGadget (1, 5, 5, 290, 166)
          AddGadgetItem(1, -1, "Sub-Panel 1")
          AddGadgetItem(1, -1, "Sub-Panel 2")
          AddGadgetItem(1, -1, "Sub-Panel 3")
        CloseGadgetList()
      AddGadgetItem (0, -1,"Panel 2")
        ButtonGadget(2, 10, 15, 80, 24,"Button 1")
        ButtonGadget(3, 95, 15, 80, 24,"Button 2")
        
        TextGadget(10,50,60,100,20,"ddgdfswewe")
;          SetGadgetColor(10,#PB_Gadget_BackColor,$ABABAB)
        
        CloseGadgetList()
        
        SetGadgetState(0, 1)
  
brush  = CreateSolidBrush_($ABABAB)

SetWindowTheme_(GadgetID(0), @null.w, @null.w)

        SetClassLongPtr_(GadgetID(0), #GCL_HBRBACKGROUND, brush)
      
    Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
  EndIf
    
BarryG
Addict
Addict
Posts: 4122
Joined: Thu Apr 18, 2019 8:17 am

Re: TextGadget on PanelGadget with panels with background color

Post by BarryG »

Lima wrote: Wed Jun 07, 2023 12:14 pm The code I put together below works fine with PB 6.01.
With PB 6.02 the TextGadget(10,50,60,100,20,"ddgdfswewe") has a black background color, and nothing can be read.
PureBasic 6.02 has changed the way it subclasses things, so it's not going to be fixed as such. You're in the same boat as me: lots of points in my code where things don't work in 6.02 anymore, so I have to stay with 6.01 now.
User avatar
NicknameFJ
User
User
Posts: 90
Joined: Tue Mar 17, 2009 6:36 pm
Location: Germany

Re: TextGadget on PanelGadget with panels with background color

Post by NicknameFJ »

Hi !

I´ve had the same/similar problem. I wanted to colorize the active Panel with OwnerDraw

See the german forum.

https://www.purebasic.fr/german/viewtopic.php?t=32987

Geetings

NicknameFJ


Code: Select all

Import "Comctl32.lib" 
  ; use the PureBasic Syntax (Windows API Functions using trailing underscore) 
  ; 
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
    SetWindowSubclass_(hWnd, *fnSubclass, uIdSubclass, dwRefData)  As "SetWindowSubclass" 
    GetWindowSubclass_(hWnd, *fnSubclass, uIdSubclass, *dwRefData) As "GetWindowSubclass"
    RemoveWindowSubclass_(hWnd, *fnSubclass, uIdSubclass)          As "RemoveWindowSubclass"
    DefSubclassProc_(hWnd, uMsg, wParam, lParam)                   As "DefSubclassProc"
  CompilerElse
    SetWindowSubclass_(hWnd, *fnSubclass, uIdSubclass, dwRefData)  As "_SetWindowSubclass@16" 
    GetWindowSubclass_(hWnd, *fnSubclass, uIdSubclass, *dwRefData) As "_GetWindowSubclass@16"
    RemoveWindowSubclass_(hWnd, *fnSubclass, uIdSubclass)          As "_RemoveWindowSubclass@12"
    DefSubclassProc_(hWnd, uMsg, wParam, lParam)                   As "_DefSubclassProc@16" 
  CompilerEndIf
EndImport 


#Window_Einstellung_Benutzer = 1
#Panel_Einstellungen_Benutzer = 10
#Panel_Option_2 = 11
#Text_HauptAnsicht = 20
#Checkbox_Hauptansicht = 21
#Combobox_hauptansicht = 22


; ---------------------------------------------------------------------------------------------------------------------
;  SubclasssWindowProc .. (all in one) 
; ---------------------------------------------------------------------------------------------------------------------

Define hBrushStatic 


Procedure SubclassWindowProc(hWnd, uMsg, wParam, lParam, uIdSubclass, dwRefData) 
  Shared hBrushStatic 
  Protected bkcolor 

  Select uMsg 
    Case #WM_NCDESTROY 
      RemoveWindowSubclass_(hWnd, @SubclassWindowProc(), uIdSubclass)  ; return is non-zero if successful 

    Case #WM_CTLCOLORSTATIC
      SetTextColor_(wParam, #Black) 
      bkcolor = GetSysColor_(#COLOR_BTNFACE) 
     ;bkcolor = GetSysColor_(#COLOR_INFOBK) 
      SetBkColor_(wParam, bkcolor) 

      If hBrushStatic = #Null 
        hBrushStatic = CreateSolidBrush_(bkcolor) 
      EndIf 
      ProcedureReturn hBrushStatic 
    
    Case #WM_DESTROY 
      DeleteObject_(hBrushStatic)  ; not needed with GetSysColorBrush_(), but with CreateSolidBrush_() 

    Case #WM_DRAWITEM 
      Protected *drawItem.DRAWITEMSTRUCT 
      Protected text.s, textColor, brush  

      *drawItem = lParam  ; type cast :) 

      ; 
      ; here we can use uIdSubclass (assigned #Panel_Einstellungen_Benutzer) 
      ;
      
      If wParam = uIdSubclass 
        If *drawItem\itemID <> -1 And *drawItem\CtlType = #ODT_TAB  
          text = GetGadgetItemText(wParam, *drawItem\itemID) 

          brush = CreateSolidBrush_(GetSysColor_(#COLOR_3DFACE)) 
          If (*drawItem\itemState & #ODS_SELECTED) <> 0  ; for the selected tab we use RED 
            textColor = #Red
          Else   
            textColor = GetSysColor_(#COLOR_WINDOWTEXT) 
          EndIf 

          FillRect_(*drawItem\hdc, *drawItem\rcItem, brush) 
          DeleteObject_(brush)  ; no longer needed 
          SetTextColor_(*drawItem\hdc, textColor) 
          SetBkMode_(*drawItem\hdc, #TRANSPARENT)  

          DrawText_(*drawItem\hdc, @text, Len(text), *drawItem\rcItem, #DT_CENTER | #DT_SINGLELINE | #DT_VCENTER | #DT_NOCLIP)
         ;TextOut_(*drawItem\hdc, *drawItem\rcItem\left+2, *drawItem\rcItem\top, @text, Len(text)) 

          ProcedureReturn 0  
        EndIf 
      EndIf ; wParam = uIdSubclass  

  EndSelect 
  ProcedureReturn DefSubclassProc_(hWnd, uMsg, wParam, lParam) 
EndProcedure
  


If OpenWindow(#Window_Einstellung_Benutzer, 0, 0, 720,400, "Einstellungen",#PB_Window_ScreenCentered | #PB_Window_SystemMenu)
  
  PanelGadget(#Panel_Einstellungen_Benutzer,0,0,720,350)
  SetWindowLong_(GadgetID(#Panel_Einstellungen_Benutzer), #GWL_STYLE, GetWindowLong_(GadgetID(#Panel_Einstellungen_Benutzer), #GWL_STYLE) | #TCS_OWNERDRAWFIXED) 
  SetWindowSubclass_(WindowID(#Window_Einstellung_Benutzer), @SubclassWindowProc(), #Panel_Einstellungen_Benutzer, 0) 
  
  AddGadgetItem(#Panel_Einstellungen_Benutzer,-1,"Auswertung")
  AddGadgetItem(#Panel_Einstellungen_Benutzer,-1,"Ansicht")
  
  PanelGadget(#Panel_Option_2,0,0,600,250)
  SetWindowLong_(GadgetID(#Panel_Option_2), #GWL_STYLE, GetWindowLong_(GadgetID(#Panel_Option_2), #GWL_STYLE) | #TCS_OWNERDRAWFIXED) 
  SetWindowSubclass_(GetParent_(GadgetID(#Panel_Option_2)), @SubclassWindowProc(), #Panel_Option_2, 0) 
  
  AddGadgetItem(#Panel_Option_2,-1,"TEST")
  AddGadgetItem(#Panel_Option_2,-1,"noch ein Test")
  
  TextGadget(#Text_HauptAnsicht,10,20,100,24,"Vollauswertung")
  SetWindowSubclass_(GetParent_(GadgetID(#Text_HauptAnsicht)), @SubclassWindowProc(), 0, 0) 
  CheckBoxGadget(#checkbox_Hauptansicht,10,50,100,24,"CHECK IT")
  ComboBoxGadget(#Combobox_Hauptansicht,10,80,100,24)
  
  AddGadgetItem(#Combobox_Hauptansicht,-1,"Auswahl 1")
  AddGadgetItem(#Combobox_Hauptansicht,-1,"Auswahl 2")
  AddGadgetItem(#Combobox_Hauptansicht,-1,"Auswahl 3")
  SetGadgetState(#Combobox_hauptansicht,1)
  
  
  CloseGadgetList()  ; <-- this should be added 
  CloseGadgetList()
  
  
  Repeat :  Until WaitWindowEvent() = #PB_Event_CloseWindow
  
EndIf

PS: Sorry for my weird english, but english is not my native language.



Image
PBJim
Enthusiast
Enthusiast
Posts: 294
Joined: Fri Jan 19, 2024 11:56 pm

Re: TextGadget on PanelGadget with panels with background color

Post by PBJim »

I'm interested to know if there is a way to change the background colour of the tabs of a PanelGadget to the usual Windows grey, without the unwanted border change at the bottom.

Also, I'd like change the colour of all the panel tabs, as the below only changes the last tab of the gadget.

I saw there are quite a number of posts requesting a colour option for this gadget.

Code: Select all

 
 If OpenWindow(0, 0, 0, 322, 220, "PanelGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    PanelGadget     (0, 8, 8, 306, 203)
      AddGadgetItem (0, -1, "Panel 1")
        PanelGadget (1, 5, 5, 290, 166)
          AddGadgetItem(1, -1, "Sub-Panel 1")
          AddGadgetItem(1, -1, "Sub-Panel 2")
          AddGadgetItem(1, -1, "Sub-Panel 3")
        CloseGadgetList()
      AddGadgetItem (0, -1,"Panel 2")
        ButtonGadget(2, 10, 15, 80, 24,"Button 1")
        ButtonGadget(3, 95, 15, 80, 24,"Button 2")
        CloseGadgetList()
        
        SetGadgetState(0, 1)
  
brush  = CreateSolidBrush_($f1f1f1)

SetWindowTheme_(GadgetID(0), @null.w, @null.w)

        SetClassLongPtr_(GadgetID(0), #GCL_HBRBACKGROUND, brush)
      
    Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
  EndIf
    
PBJim
Enthusiast
Enthusiast
Posts: 294
Joined: Fri Jan 19, 2024 11:56 pm

Re: TextGadget on PanelGadget with panels with background color

Post by PBJim »

I experimented by adapting this code further, to obtain a grey PanelGadget background, but it was largely unsuccessful.

1. SetWindowTheme_ only affects the last tab in the PanelGadget.
2. Setting the gadget state with -1, brought a result of grey for the first tab, but it didn't draw the sub-panels.

Unfortunately PanelGadgets are unusable for the needs of our application, as the visual appearance of a large area of white background with grey field gadgets is unsatisfactory. It's fine for small panels, but large panels look terrible. Would appreciate if others happen to be aware of better options.

Code: Select all

 
 If OpenWindow(0, 0, 0, 322, 220, "PanelGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    PanelGadget     (0, 8, 8, 306, 203)
      AddGadgetItem (0, -1, "Panel 1")
        PanelGadget (1, 5, 5, 290, 166)
          AddGadgetItem(1, -1, "Sub-Panel 1")
          AddGadgetItem(1, -1, "Sub-Panel 2")
          AddGadgetItem(1, -1, "Sub-Panel 3")
        CloseGadgetList()
      AddGadgetItem (0, -1,"Panel 2")
        ButtonGadget(2, 10, 15, 80, 24,"Button 1")
        ButtonGadget(3, 95, 15, 80, 24,"Button 2")
        CloseGadgetList()
        
        SetGadgetState(0, -1)
  
    SetWindowTheme_(GadgetID(0), @null.w, @null.w)

    
    Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
  EndIf
    
Image

Image

Image
breeze4me
Enthusiast
Enthusiast
Posts: 633
Joined: Thu Mar 09, 2006 9:24 am
Location: S. Kor

Re: TextGadget on PanelGadget with panels with background color

Post by breeze4me »

PBJim wrote: Fri Nov 01, 2024 9:46 pm I'm interested to know if there is a way to change the background colour of the tabs of a PanelGadget to the usual Windows grey, without the unwanted border change at the bottom.
Am I understanding correctly that you want to clear the bottom border of the unthemed panels?
You can clear the right and bottom borders as shown below.

Code: Select all


Procedure PanelWndProc(hwnd, msg, wparam, lparam)
  Protected Result, Gadget, hdc, rt0.RECT, rt1.RECT, hBrush
  Protected old = GetProp_(hwnd, "oldwndproc")
  
  If msg = #WM_PAINT
    Result = CallWindowProc_(old, hwnd, msg, wparam, lparam)
    
    Gadget = GetWindowLongPtr_(hwnd, #GWLP_ID)
    hdc = GetWindowDC_(hwnd)
    If hdc
      GetClientRect_(hwnd, rt0)
      hBrush = CreateSolidBrush_(GetSysColor_(#COLOR_BTNFACE))
      If hBrush
        rt0\top + GetGadgetAttribute(Gadget, #PB_Panel_TabHeight) - 2
        
        rt1 = rt0
        ; To delete the right border completely.
        ;rt1\left = rt1\right - 2
        rt1\left = rt1\right - 1
        FillRect_(hdc, rt1, hBrush)
        
        rt1 = rt0
        ; To delete the bottom border completely.
        ;rt1\top = rt1\bottom - 2
        rt1\top = rt1\bottom - 1
        FillRect_(hdc, rt1, hBrush)
        
        DeleteObject_(hBrush)
      EndIf
      ReleaseDC_(hwnd, hdc)
    EndIf
    
    ProcedureReturn Result
    
  ElseIf msg = #WM_NCDESTROY
    RemoveProp_(hwnd, "oldwndproc")
    
  EndIf
  
  ProcedureReturn CallWindowProc_(old, hwnd, msg, wparam, lparam)
EndProcedure

If OpenWindow(0, 0, 0, 322, 220, "PanelGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  PanelGadget     (0, 8, 8, 306, 203)
    AddGadgetItem (0, -1, "Panel 1")
      PanelGadget (1, 5, 5, 290, 166)
        AddGadgetItem(1, -1, "Sub-Panel 1")
        AddGadgetItem(1, -1, "Sub-Panel 2")
        AddGadgetItem(1, -1, "Sub-Panel 3")
      CloseGadgetList()
    AddGadgetItem (0, -1,"Panel 2")
      ButtonGadget(2, 10, 15, 80, 24,"Button 1")
      ButtonGadget(3, 95, 15, 80, 24,"Button 2")
  CloseGadgetList()
  
  SetWindowTheme_(GadgetID(0), "", "")
  SetProp_(GadgetID(0), "oldwndproc", SetWindowLongPtr_(GadgetID(0), #GWLP_WNDPROC, @PanelWndProc()))
  
  SetWindowTheme_(GadgetID(1), "", "")
  SetProp_(GadgetID(1), "oldwndproc", SetWindowLongPtr_(GadgetID(1), #GWLP_WNDPROC, @PanelWndProc()))
  
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4946
Joined: Sun Apr 12, 2009 6:27 am

Re: TextGadget on PanelGadget with panels with background color

Post by RASHAD »

Hi

Code: Select all

brush = CreateSolidBrush_(GetSysColor_(#COLOR_BTNFACE) )
If OpenWindow(0, 0, 0, 600,400, "PanelGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  PanelGadget     (0, 10,10, 580,380)
    AddGadgetItem (0, -1, "Panel 1")
      pan1 = PanelGadget (1, 5, 5, 580,380)
        AddGadgetItem(1, -1, "Sub-Panel 1")
        AddGadgetItem(1, -1, "Sub-Panel 2")
        AddGadgetItem(1, -1, "Sub-Panel 3")
      CloseGadgetList()
      SetWindowTheme_(pan1, @null.w, @null.w)
      SetClassLongPtr_(pan1, #GCL_HBRBACKGROUND, brush)
    AddGadgetItem (0, -1,"Panel 2")
      ButtonGadget(2, 10, 15, 80, 24,"Button 1")
      ButtonGadget(3, 95, 15, 80, 24,"Button 2")
  CloseGadgetList()
  SetWindowTheme_(GadgetID(0), @null.w, @null.w)
  SetClassLongPtr_(GadgetID(0), #GCL_HBRBACKGROUND, brush)

  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
DeleteObject_(brush)
Egypt my love
PBJim
Enthusiast
Enthusiast
Posts: 294
Joined: Fri Jan 19, 2024 11:56 pm

Re: TextGadget on PanelGadget with panels with background color

Post by PBJim »

RASHAD wrote: Tue Nov 05, 2024 3:21 pm Hi

Code: Select all

brush = CreateSolidBrush_(GetSysColor_(#COLOR_BTNFACE) )
Hi Rashad, many thanks for this.

I apologise for not replying back since Tuesday, but it has been a tough week with business. I struggled to get time to move the PB project forward.

Interestingly, I found that the two lines below can be removed and the result seems the same. Are they necessary?

Code: Select all

brush = CreateSolidBrush_(GetSysColor_(#COLOR_BTNFACE) )
SetClassLongPtr_(GadgetID(0), #GCL_HBRBACKGROUND, brush)
So the below works on its own.

Code: Select all

SetWindowTheme_(GadgetID(0), @null.w, @null.w)
PBJim
Enthusiast
Enthusiast
Posts: 294
Joined: Fri Jan 19, 2024 11:56 pm

Re: TextGadget on PanelGadget with panels with background color

Post by PBJim »

breeze4me wrote: Tue Nov 05, 2024 1:25 pm
PBJim wrote: Fri Nov 01, 2024 9:46 pm I'm interested to know if there is a way to change the background colour of the tabs of a PanelGadget to the usual Windows grey, without the unwanted border change at the bottom.
Am I understanding correctly that you want to clear the bottom border of the unthemed panels?
You can clear the right and bottom borders as shown below.
Hi breeze4me, many thanks. Yes, you are indeed correct, I hoped to remove the bottom and right-side border, as the solution does very well.

Apologies that I hadn't replied to your helpful post sooner — this week has passed without much chance to work on the PB project.

Your method gives me some useful options, because for large PanelGadgets, it looks so much better to elimate those thick borders and draw a grey background. There's sometimes quite a lot of work in getting PB's GUI to look just right and visually pleasing to the eye. For a screen where the PanelGadget covers only a small area, the white background looks perfect, but for large areas it looks absolutely terrible. Bring back the green-screen 80x25 character applications, I would be really happy :D
Post Reply