Owner Draw verursacht schwarzes Textgadget in 6.02

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
NicknameFJ
Beiträge: 324
Registriert: 03.06.2007 14:36
Wohnort: Von der Sonne aus gesehen der dritte Planet

Owner Draw verursacht schwarzes Textgadget in 6.02

Beitrag von NicknameFJ »

Hallo zusammen,

ich habe ein Panelgadget bei dem ich den aktiven Reiter farbig markieren wollte. Ich habe es schon vor langer Zeit über einen Callback mit OwnerDraw realisiert. Bis 6.01 hat das auch einwandfrei funktioniert. So wie ich es sehe ist der OwnerDraw aber nur für das Panelgadget, die Textgadget´s sollten eigentlich davon nicht beeinträchtigt werden.

Seit 6.02 (sowohl ASM als auch C-Backend) werden die TextGadget´s die sich in dem Panel befinden komplett in schwarz angezeigt. PB 6.02 64 Bit auf Windows 10.

Kann hier bitte einer von den Profis mal drüber schauen was hier seit 6.02 schief läuft.

Vielen Dank im Voraus

NicknameFJ

Code: Alles auswählen

#Window_Einstellung_Benutzer = 1
#Panel_Einstellungen_Benutzer = 1
#Text_HauptAnsicht = 2


Procedure Callback(hwnd, msg, wParam, lParam)
  
  Protected OldProc, result, defaultBrush, Gadget, tabText$
  Protected *PGdis.DrawItemstruct
  
  OldProc = GetProp_(hWnd, "OldProc")
  result = CallWindowProc_(OldProc, hwnd, msg, wParam, lParam)
  
  Select msg
    Case #WM_DRAWITEM
      
      *PGdis.DRAWITEMSTRUCT = lParam
      If *PGdis\CtlType = #ODT_TAB
        
        defaultBrush = CreateSolidBrush_(GetSysColor_(#COLOR_3DFACE))
        
        Gadget = GetProp_(*PGdis\hwnditem, "PB_ID")
        
        If *PGdis\itemID = GetGadgetState(Gadget)
          SetTextColor_(*PGdis\hdc, #Red)
        EndIf
        
        tabText$ = GetGadgetItemText(Gadget, *PGdis\itemID)
        FillRect_(*PGdis\hdc, *PGdis\rcItem, defaultBrush)
        SetBkMode_(*PGdis\hdc, #TRANSPARENT)
        DrawText_(*PGdis\hdc, @tabText$, Len(tabText$), *PGdis\rcItem, #DT_CENTER | #DT_SINGLELINE | #DT_VCENTER | #DT_NOCLIP)
        
        DeleteObject_(defaultBrush)
        
      EndIf       
      
  EndSelect
  
  ProcedureReturn  result 
EndProcedure 


FensterBreite = 720
FensterHoehe  = 400


If OpenWindow(#Window_Einstellung_Benutzer, 0, 0, FensterBreite,FensterHoehe, "Einstellungen",#PB_Window_ScreenCentered | #PB_Window_SystemMenu)
  
  PanelGadget(#Panel_Einstellungen_Benutzer,0,0,FensterBreite,350)
  AddGadgetItem(#Panel_Einstellungen_Benutzer,-1,"Auswertung")
  TextGadget(#Text_HauptAnsicht,10,20,100,24,"Vollauswertung")
  AddGadgetItem(#Panel_Einstellungen_Benutzer,-1,"Ansicht")
  
  SetWindowLong_(GadgetID(#Panel_Einstellungen_Benutzer), #GWL_STYLE, GetWindowLong_(GadgetID(#Panel_Einstellungen_Benutzer), #GWL_STYLE) | #TCS_OWNERDRAWFIXED) 
  Oldproc = SetWindowLong_(GetParent_(GadgetID(#Panel_Einstellungen_Benutzer)), #GWL_WNDPROC, @Callback()) 
  SetProp_(GetParent_(GadgetID(#Panel_Einstellungen_Benutzer)),@"OldProc",OldProc)
  
  
  Repeat :  Until WaitWindowEvent() = #PB_Event_CloseWindow
  
EndIf

PS: Alle im Text enthaltenen Schreibfehler sind beabsichtigt und dienen der Belustigung aller

Bild
Axolotl
Beiträge: 154
Registriert: 31.12.2008 16:34

Re: Owner Draw verursacht schwarzes Textgadget in 6.02

Beitrag von Axolotl »

Im englischen Forum wurde das Thema schon diskutiert. Subclassing ist der Lösungsansatz. Nur so auf die schnelle, bin gerade nicht am Rechner.....
Mostly running PureBasic <latest stable version and current alpha/beta> (x64) on Windows 11 Home
Axolotl
Beiträge: 154
Registriert: 31.12.2008 16:34

Re: Owner Draw verursacht schwarzes Textgadget in 6.02

Beitrag von Axolotl »

Moin NicknameFJ,

hier mal eine Lösung, so wie ich denke, dass es grundsätzlich funktionieren sollte.

Leider sind bei der Fehlerbehebung auch liebgewonnene Eigenschaften verloren gegangen....
Bisher wurde scheinbar intern dafür gesorgt, dass die Callback Routine vom "richtigen" Parent-Window bearbeitet wurde.
Dieser "Fehler" ist in der neusten Version (6.02) behoben worden und weil API müssen wir uns selbst drum kümmern.

Code: Alles auswählen

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 = 1
#Text_HauptAnsicht = 2



; Procedure Callback(hwnd, msg, wParam, lParam)
;   
;   Protected OldProc, result, defaultBrush, Gadget, tabText$
;   Protected *PGdis.DrawItemstruct
;   
;   OldProc = GetProp_(hWnd, "OldProc")
;   result = CallWindowProc_(OldProc, hwnd, msg, wParam, lParam)
;   
;   Select msg
;     Case #WM_DRAWITEM
; 
;       *PGdis.DRAWITEMSTRUCT = lParam
;       If *PGdis\CtlType = #ODT_TAB
;         
;         defaultBrush = CreateSolidBrush_(GetSysColor_(#COLOR_3DFACE))
;         
;         Gadget = GetProp_(*PGdis\hwnditem, "PB_ID")
;         
;         If *PGdis\itemID = GetGadgetState(Gadget)
;           SetTextColor_(*PGdis\hdc, #Red)
;         EndIf
;         
;         tabText$ = GetGadgetItemText(Gadget, *PGdis\itemID)
;         FillRect_(*PGdis\hdc, *PGdis\rcItem, defaultBrush)
;         SetBkMode_(*PGdis\hdc, #TRANSPARENT)
;         DrawText_(*PGdis\hdc, @tabText$, Len(tabText$), *PGdis\rcItem, #DT_CENTER | #DT_SINGLELINE | #DT_VCENTER | #DT_NOCLIP)
;         
;         DeleteObject_(defaultBrush)
;         
;       EndIf       
;   EndSelect
;   
;   ProcedureReturn  result 
; EndProcedure 



; ---------------------------------------------------------------------------------------------------------------------
;  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
  



FensterBreite = 720
FensterHoehe  = 400


If OpenWindow(#Window_Einstellung_Benutzer, 0, 0, FensterBreite,FensterHoehe, "Einstellungen",#PB_Window_ScreenCentered | #PB_Window_SystemMenu)
  
  PanelGadget(#Panel_Einstellungen_Benutzer,0,0,FensterBreite,350)
  AddGadgetItem(#Panel_Einstellungen_Benutzer,-1,"Auswertung")
  TextGadget(#Text_HauptAnsicht,10,20,100,24,"Vollauswertung")
  AddGadgetItem(#Panel_Einstellungen_Benutzer,-1,"Ansicht")
  CloseGadgetList()  ; <-- this should be added 

  SetWindowLong_(GadgetID(#Panel_Einstellungen_Benutzer), #GWL_STYLE, GetWindowLong_(GadgetID(#Panel_Einstellungen_Benutzer), #GWL_STYLE) | #TCS_OWNERDRAWFIXED) 

  SetWindowSubclass_(GetParent_(GadgetID(#Text_HauptAnsicht)), @SubclassWindowProc(), 0, 0) 
  SetWindowSubclass_(WindowID(#Window_Einstellung_Benutzer), @SubclassWindowProc(), #Panel_Einstellungen_Benutzer, 0) 

;   SetWindowLong_(GadgetID(#Panel_Einstellungen_Benutzer), #GWL_STYLE, GetWindowLong_(GadgetID(#Panel_Einstellungen_Benutzer), #GWL_STYLE) | #TCS_OWNERDRAWFIXED) 
;   Oldproc = SetWindowLong_(GetParent_(GadgetID(#Panel_Einstellungen_Benutzer)), #GWL_WNDPROC, @Callback()) 
;   SetProp_(GetParent_(GadgetID(#Panel_Einstellungen_Benutzer)),@"OldProc",OldProc)
  
  
  Repeat :  Until WaitWindowEvent() = #PB_Event_CloseWindow
  
EndIf

Mostly running PureBasic <latest stable version and current alpha/beta> (x64) on Windows 11 Home
Benutzeravatar
hjbremer
Beiträge: 822
Registriert: 27.02.2006 22:30
Computerausstattung: von gestern
Wohnort: Neumünster

Re: Owner Draw verursacht schwarzes Textgadget in 6.02

Beitrag von hjbremer »

Solange es nur um ein Textgadget geht reicht folgendes

TextGadget(#Text_HauptAnsicht,10,20,100,24,"Vollauswertung", #WS_BORDER|#SS_CENTER|#SS_CENTERIMAGE)
SetGadgetColor(#Text_HauptAnsicht, #PB_Gadget_BackColor, $f0f0f0)
SetGadgetColor(#Text_HauptAnsicht, #PB_Gadget_FrontColor, #Magenta)

ButtonGadget(22,10,80,100,24,"Mist Rahmen")

soll heißen eigene Farben setzen

bei anderen Gadgets wie z.B. Buttons muß man sicherlich ähnliches machen, habe ich aber nicht weiter probiert
Purebasic 5.70 x86 5.72 X 64 - Windows 10

Der Computer hat dem menschlichen Gehirn gegenüber nur einen Vorteil: Er wird benutzt
grüße hjbremer
Axolotl
Beiträge: 154
Registriert: 31.12.2008 16:34

Re: Owner Draw verursacht schwarzes Textgadget in 6.02

Beitrag von Axolotl »

yupp,
einmal die hintergrundfarbe setzen reicht bei TextGadget tatsächlich aus :allright:

Code: Alles auswählen

  SetGadgetColor(#Text_HauptAnsicht, #PB_Gadget_BackColor, $f0f0f0)
Mostly running PureBasic <latest stable version and current alpha/beta> (x64) on Windows 11 Home
Benutzeravatar
NicknameFJ
Beiträge: 324
Registriert: 03.06.2007 14:36
Wohnort: Von der Sonne aus gesehen der dritte Planet

Re: Owner Draw verursacht schwarzes Textgadget in 6.02

Beitrag von NicknameFJ »

Danke Euch beiden.

Es sind mehr und auch andere Gadgets im Panel, aber mir ist nur beim Textgadget ein Fehler aufgefallen.

Ich teste mal Eure Vorschläge im richtigen Programm und sehe ob es so geht.

NicknameFJ
PS: Alle im Text enthaltenen Schreibfehler sind beabsichtigt und dienen der Belustigung aller

Bild
Axolotl
Beiträge: 154
Registriert: 31.12.2008 16:34

Re: Owner Draw verursacht schwarzes Textgadget in 6.02

Beitrag von Axolotl »

... und wenn der Button dann noch nach Standard aussehen soll....

Hier mal am Beispiel

Code: Alles auswählen

; EnableExplicit 

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 = 1
#Text_HauptAnsicht = 2

Global hBrushStatic  ; static variable (or global) 

Procedure SubclassGadgetProc(hWnd, uMsg, wParam, lParam, uIdSubclass, dwRefData) 
  Protected bkcolor 

  Select uMsg 
    Case #WM_NCDESTROY                                                        ;:Debug "WM_NCDESTROY " + uIdSubclass  
      RemoveWindowSubclass_(hWnd, @SubclassGadgetProc(), uIdSubclass) 

    Case #WM_DESTROY 
      DeleteObject_(hBrushStatic) 

    Case #WM_CTLCOLORBTN 
      ; wParam := Handle to the device context for the static control window. 
      ; lParam := Handle to the static control. 
      SetTextColor_(wParam, #Black) 
      bkcolor = GetSysColor_(#COLOR_BTNFACE) 
      SetBkColor_(wParam, bkcolor) 

      If hBrushStatic = #Null 
        hBrushStatic = CreateSolidBrush_(bkcolor) 
      EndIf 
      ProcedureReturn hBrushStatic 

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



Procedure Callback(hwnd, msg, wParam, lParam)
  
  Protected OldProc, result, defaultBrush, Gadget, tabText$
  Protected *PGdis.DrawItemstruct
  
  OldProc = GetProp_(hWnd, "OldProc")
  result = CallWindowProc_(OldProc, hwnd, msg, wParam, lParam)
  
  Select msg
    Case #WM_DRAWITEM
      
      *PGdis.DRAWITEMSTRUCT = lParam
      If *PGdis\CtlType = #ODT_TAB
        
        defaultBrush = CreateSolidBrush_(GetSysColor_(#COLOR_3DFACE))
        
        Gadget = GetProp_(*PGdis\hwnditem, "PB_ID")
        
        If *PGdis\itemID = GetGadgetState(Gadget)
          SetTextColor_(*PGdis\hdc, #Red)
        EndIf
        
        tabText$ = GetGadgetItemText(Gadget, *PGdis\itemID)
        FillRect_(*PGdis\hdc, *PGdis\rcItem, defaultBrush)
        SetBkMode_(*PGdis\hdc, #TRANSPARENT)
        DrawText_(*PGdis\hdc, @tabText$, Len(tabText$), *PGdis\rcItem, #DT_CENTER | #DT_SINGLELINE | #DT_VCENTER | #DT_NOCLIP)
        
        DeleteObject_(defaultBrush)
        
      EndIf       
      
  EndSelect
  
  ProcedureReturn  result 
EndProcedure 


Define FensterBreite = 720 
Define FensterHoehe  = 400 


If OpenWindow(#Window_Einstellung_Benutzer, 0, 0, FensterBreite,FensterHoehe, "Einstellungen",#PB_Window_ScreenCentered | #PB_Window_SystemMenu)
  
  PanelGadget(#Panel_Einstellungen_Benutzer,0,0,FensterBreite,350)
  AddGadgetItem(#Panel_Einstellungen_Benutzer,-1,"Auswertung")
  TextGadget(#Text_HauptAnsicht,10,20,100,24,"Vollauswertung")
;TextGadget(#Text_HauptAnsicht,10,20,100,24,"Vollauswertung", #SS_CENTER|#SS_CENTERIMAGE)
  SetGadgetColor(#Text_HauptAnsicht, #PB_Gadget_BackColor, $f0f0f0)
;SetGadgetColor(#Text_HauptAnsicht, #PB_Gadget_FrontColor, #Magenta)

  AddGadgetItem(#Panel_Einstellungen_Benutzer,-1,"Ansicht")
  
  ButtonGadget(22,10,80,100,24,"Mist Rahmen") 
  CloseGadgetList() 

  ButtonGadget(23,10,360,100,24,"Standard") ; compare the standard appearance 
  
  SetWindowLong_(GadgetID(#Panel_Einstellungen_Benutzer), #GWL_STYLE, GetWindowLong_(GadgetID(#Panel_Einstellungen_Benutzer), #GWL_STYLE) | #TCS_OWNERDRAWFIXED) 
  Oldproc = SetWindowLong_(GetParent_(GadgetID(#Panel_Einstellungen_Benutzer)), #GWL_WNDPROC, @Callback()) 
  SetProp_(GetParent_(GadgetID(#Panel_Einstellungen_Benutzer)),@"OldProc",OldProc)
  

  SetWindowSubclass_(GetParent_(GadgetID(22)), @SubclassGadgetProc(), 22, 0)  ; Button on panel 

Repeat :  Until WaitWindowEvent() = #PB_Event_CloseWindow
Mostly running PureBasic <latest stable version and current alpha/beta> (x64) on Windows 11 Home
Benutzeravatar
NicknameFJ
Beiträge: 324
Registriert: 03.06.2007 14:36
Wohnort: Von der Sonne aus gesehen der dritte Planet

Re: Owner Draw verursacht schwarzes Textgadget in 6.02

Beitrag von NicknameFJ »

Axolotl hat geschrieben: 02.06.2023 15:40 yupp,
einmal die hintergrundfarbe setzen reicht bei TextGadget tatsächlich aus :allright:

Code: Alles auswählen

  SetGadgetColor(#Text_HauptAnsicht, #PB_Gadget_BackColor, $f0f0f0)
Nachtrag:
Wenn das Textgadget jetzt schwarz ist dann einfach die Farbe ändern. Warum bin ich da nicht draufgekommen? :oops:

Manchmal sieht man den Wald vor lauter Bäumen nicht

Grüße
PS: Alle im Text enthaltenen Schreibfehler sind beabsichtigt und dienen der Belustigung aller

Bild
Axolotl
Beiträge: 154
Registriert: 31.12.2008 16:34

Re: Owner Draw verursacht schwarzes Textgadget in 6.02

Beitrag von Axolotl »

... und noch ein kleiner (klugsch...) Tipp.
Wenn du 32 und 64 bit versionen unterstützen möchtest...
dann besser

Code: Alles auswählen

SetWindowLongPtr_() 
anstelle von

Code: Alles auswählen

SetWindowLong_()
verwenden.
Sagt zumindest M$.
Mostly running PureBasic <latest stable version and current alpha/beta> (x64) on Windows 11 Home
Benutzeravatar
NicknameFJ
Beiträge: 324
Registriert: 03.06.2007 14:36
Wohnort: Von der Sonne aus gesehen der dritte Planet

Re: Owner Draw verursacht schwarzes Textgadget in 6.02

Beitrag von NicknameFJ »

Axolotl hat geschrieben: 02.06.2023 16:21 ... und noch ein kleiner (klugsch...) Tipp.
Wenn du 32 und 64 bit versionen unterstützen möchtest...
dann besser

Code: Alles auswählen

SetWindowLongPtr_() 
anstelle von

Code: Alles auswählen

SetWindowLong_()
verwenden.
Sagt zumindest M$.
Was heißt da klugsch... - bin doch für jeden Tipp dankbar.

TextGadget und CheckboxGadget waren schwarz, ComboboxGadget hat auch ohne Subclassing noch funktioniert

Ich habe auf das 1. Panel noch ein weiteres Unterpanel gelegt. Da hat die Einfärbung des Unterpanels nicht geklappt, habe es aber hinbekommen.

Muss ich jetzt nur noch in meinen verschiedenen Projekten anpassen - oh je, das gibt eine Fleißarbeit. Ich habe das in allen meinen Projekten so drin dass der aktive Reiter bei den Panels eingefärbt wird.


Code: Alles auswählen

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


Grüße

NicknameFJ
PS: Alle im Text enthaltenen Schreibfehler sind beabsichtigt und dienen der Belustigung aller

Bild
Antworten