Code Update for TreeGadget() with NM_CUSTOMDRAW [Win only]
Posted: Fri Nov 15, 2024 5:29 pm
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)
This is an update to the following examples: (pretty sure, this list is incomplete)
CustomDraw treegadget
Disable TreeGadget Item
Multi-Line TreeGadget [Windows]
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
CustomDraw treegadget
Disable TreeGadget Item
Multi-Line TreeGadget [Windows]