Page 1 of 1

Code Update for TreeGadget() with NM_CUSTOMDRAW [Win only]

Posted: Fri Nov 15, 2024 5:29 pm
by Axolotl
Hi all,

I am using a TreeGadget and want to display some formatted text. My idea is to use the custom draw feature for that and I started searching for some examples on the forum and I found some nice ones (see list below).
Unfortunatly all codes are older and not working anymore.... (see the following code for details)
To make a long story short: Here is an update of the sources. (not sure who was the first coder)

Code: Select all

Enumeration 
  #MainWindow 
  #TreeGadget 
EndEnumeration 

; #DT_WORD_ELLIPSIS = $40000 
; #DT_END_ELLIPSIS = $8000 
; #DT_PATH_ELLIPSIS = $4000 
; #DT_MODIFYSTRING = $10000 
; 
; #CDIS_CHECKED = 8 
; #CDIS_DEFAULT = $20 
; #CDIS_DISABLED = 4 
; #CDIS_FOCUS = $10 
; #CDIS_GRAYED = 2 
; #CDIS_HOT = $40 
; #CDIS_INDETERMINATE = $100 
; #CDIS_MARKED = $80 
; #CDIS_SELECTED = 1 
; #CDIS_SHOWKEYBOARDCUES = $200 
; 
; #CDDS_ITEM = $10000 
; #CDDS_MAPPART = 5 
; #CDDS_POSTERASE = 4 
; #CDDS_POSTPAINT = 2 
; #CDDS_PREERASE = 3 
; #CDDS_PREPAINT = 1 
; #CDDS_ITEMPOSTERASE = #CDDS_ITEM | #CDDS_POSTERASE 
; #CDDS_ITEMPOSTPAINT = #CDDS_ITEM | #CDDS_POSTPAINT 
; #CDDS_ITEMPREERASE = #CDDS_ITEM | #CDDS_PREERASE 
; #CDDS_ITEMPREPAINT = #CDDS_ITEM | #CDDS_PREPAINT 
; #CDDS_SUBITEM = $20000 
; 
; #CDRF_DODEFAULT = 0 
; #CDRF_NEWFONT = 2 
; #CDRF_NOTIFYITEMDRAW = $20 
; #CDRF_NOTIFYPOSTERASE = $40 
; #CDRF_NOTIFYPOSTPAINT = $10 
; #CDRF_NOTIFYSUBITEMDRAW = $20 
; #CDRF_SKIPDEFAULT = 4 

; PB undefined constant (for this example) 
;
#TVM_SETBKCOLOR = #TV_FIRST + 29


; Axolotl: NEW for e.g. PB 6.12 (all PB versions after the windows handle behavior has changed, don't know the right wording) 
; 
Structure TRect   ; <- NEW structure replacement for tvItemRect.RECT 
  StructureUnion 
    Item.i        ; this value is needed to forward the item handle (which must be a integer) 
    Rc.RECT       ; the RECT structure has only long members, but the long is needed later  
  EndStructureUnion 
EndStructure 

; --- 

Global hBrush
hBrush = CreateSolidBrush_(RGB(90,30,40))

Procedure myWindowCallback(WindowID, Message, WParam, LParam) 
  Protected *tvCD.NMTVCUSTOMDRAW, tvi.TV_ITEM 
  Protected tvItemRect.TRect  ; Axolotl: <- NEW structure (see above) 
  Protected tvi$

  Select Message 
    Case  #WM_NOTIFY 
      *tvCD = LParam 

      If *tvCD\nmcd\hdr\hwndFrom = GadgetID(#TreeGadget) And *tvCD\nmcd\hdr\code = #NM_CUSTOMDRAW   
        Select *tvCD\nmcd\dwDrawStage 
          Case #CDDS_PREPAINT
            ProcedureReturn #CDRF_NOTIFYITEMDRAW 

          Case #CDDS_ITEMPREPAINT 
            ProcedureReturn #CDRF_NOTIFYPOSTPAINT

          Case #CDDS_ITEMPOSTPAINT 
            thisItem = *tvCD\nmcd\dwItemSpec  
            tvItemRect\Item = thisItem        ; Axolotl: NEW *** use the member item to forward the handle 
            
            If SendMessage_(*tvCD\nmcd\hdr\hwndFrom, #TVM_GETITEMRECT, #True, @tvItemRect) = 0 
              ; Axolotl: added this to see the failure with old structure 
              Debug "ERROR with #TVM_GETITEMRECT" 
            EndIf 

            tvi$ = Space(256) 
            tvi\mask = #TVIF_HANDLE | #TVIF_PARAM | #TVIF_TEXT 
            tvi\pszText = @tvi$ 
            tvi\cchTextMax = 256 
            tvi\hItem = thisItem 
            tvFlags = #DT_END_ELLIPSIS  

            If SendMessage_(*tvCD\nmcd\hdr\hwndFrom, #TVM_GETITEM, 0, tvi) = 0 
              Debug "ERROR with #TVM_GETITEM" 
            EndIf 
            tvi$ = ReplaceString(tvi$,"[name]","Anthony")  
            SetTextColor_(*tvCD\nmcd\hdc,RGB(255,255,255))  
            FillRect_(*tvCD\nmcd\hdc, tvItemRect\Rc, hBrush)                ; Axolotl: NEW *** use the member Rc as RECT 
            If *tvCD\nmcd\uItemState = #CDIS_FOCUS | #CDIS_SELECTED
              SetBkColor_(*tvCD\nmcd\hdc,RGB(190,130,140)) 
            Else
              SetBkColor_(*tvCD\nmcd\hdc,RGB(90,30,40)) 
            EndIf
            DrawText_(*tvCD\nmcd\hdc,tvi$,Len(tvi$),tvItemRect\Rc,tvFlags)           ; Axolotl: NEW *** use the member Rc as RECT 
            ProcedureReturn #CDRF_DODEFAULT
        EndSelect 
      EndIf 
  EndSelect 
  ProcedureReturn #PB_ProcessPureBasicEvents 
EndProcedure 

If OpenWindow(#MainWindow,0,0,355,180,"Test TreeGadget", #PB_Window_SystemMenu|#PB_Window_ScreenCentered) 
  TreeGadget(#TreeGadget, 10,10,330,160)  
  AddGadgetItem (#TreeGadget,-1,"The following bit will change [name], heheh!") 
  AddGadgetItem (#TreeGadget,-1,"This is a node, click slightly to the left of the text") 

  AddGadgetItem(#TreeGadget,-1,"sub text") 
  AddGadgetItem(#TreeGadget,-1,"another change test: [name] !!!") 

  SetWindowCallback(@myWindowCallback(), #MainWindow, #PB_Window_ProcessChildEvents) 
  SendMessage_(GadgetID(#TreeGadget), #TVM_SETBKCOLOR, 0, RGB(90,30,40))
  Repeat : Until WaitWindowEvent()=#PB_Event_CloseWindow 
  DeleteObject_(hBrush)
EndIf 
This is an update to the following examples: (pretty sure, this list is incomplete)
CustomDraw treegadget
Disable TreeGadget Item
Multi-Line TreeGadget [Windows]