Page 1 of 1

TextGadget on PanelGadget with panels with background color

Posted: Wed Jun 07, 2023 12:14 pm
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
    

Re: TextGadget on PanelGadget with panels with background color

Posted: Wed Jun 07, 2023 12:20 pm
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.

Re: TextGadget on PanelGadget with panels with background color

Posted: Wed Jun 07, 2023 6:46 pm
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


Re: TextGadget on PanelGadget with panels with background color

Posted: Fri Nov 01, 2024 9:46 pm
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
    

Re: TextGadget on PanelGadget with panels with background color

Posted: Sat Nov 02, 2024 9:18 am
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

Re: TextGadget on PanelGadget with panels with background color

Posted: Tue Nov 05, 2024 1:25 pm
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

Re: TextGadget on PanelGadget with panels with background color

Posted: Tue Nov 05, 2024 3:21 pm
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)

Re: TextGadget on PanelGadget with panels with background color

Posted: Fri Nov 08, 2024 8:19 pm
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)

Re: TextGadget on PanelGadget with panels with background color

Posted: Fri Nov 08, 2024 8:28 pm
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