Modify

#4080 new Feature Request

Tree View Extended Styles

Reported by: MattyD Owned by:
Milestone: Component: Standard UDFs
Version: Severity: None
Keywords: Cc:

Description

Hey jpm,

I noticed the extended styles for treeviews weren't defined in our libraries - so here they are if we wish to include them.

Thanks,
Matt

For: TreeViewConstants.au3
source: commctrl.h

Documentation to be updated:
Appendix\GUI Control Styles
_GUICtrlTreeView_Create

Global Const $TVS_EX_NOSINGLECOLLAPSE = 0x0001
Global Const $TVS_EX_MULTISELECT = 0x0002
Global Const $TVS_EX_DOUBLEBUFFER = 0x0004
Global Const $TVS_EX_NOINDENTSTATE = 0x0008
Global Const $TVS_EX_RICHTOOLTIP = 0x0010
Global Const $TVS_EX_AUTOHSCROLL = 0x0020
Global Const $TVS_EX_FADEINOUTEXPANDOS = 0x0040
Global Const $TVS_EX_PARTIALCHECKBOXES = 0x0080
Global Const $TVS_EX_EXCLUSIONCHECKBOXES = 0x0100
Global Const $TVS_EX_DIMMEDCHECKBOXES = 0x0200
Global Const $TVS_EX_DRAWIMAGEASYNC = 0x0400

Attachments (0)

Change History (13)

comment:1 by pixelsearch, on Mar 16, 2026 at 11:34:15 PM

When these TreeView extended styles will be added, please add also these 2 functions to the appropriate UDF & help file :

_GUICtrlTreeView_SetExtendedStyle (message TVM_SETEXTENDEDSTYLE)
_GUICtrlTreeView_GetExtendedStyle (message TVM_GETEXTENDEDSTYLE)

If not mistaken, _GUICtrlTreeView_SetExtendedStyle should be the only way to add any TreeView extended style (TVS_EX_*) i.e. always after the TreeView creation (which contains eventual window extended styles WS_EX_* for example $WS_EX_CLIENTEDGE)

comment:2 by MattyD, on Mar 17, 2026 at 10:16:47 AM

Ah OK - that's my mistake. pixelsearch is very much correct.
from here:

"The extended styles for a tree-view control have nothing to do with the extended styles used with function CreateWindowEx or function SetWindowLong."

apologies for the bum steer.

comment:3 by Jpm, on Mar 17, 2026 at 10:34:31 AM

Can you provide examples for these new UDFs?
for a simple constant addition I will take me a lot of work ...
Cheers

comment:5 by MattyD, on Mar 18, 2026 at 7:22:25 AM

Fair call, clearly I've raised the ticket before properly doing my homework.
I've started a working/discussion thread here, and when we have something more substantial I'll ping this ticket.

comment:6 by Jpm, on Mar 18, 2026 at 8:49:40 AM

Many thanks
I will commit with all example

Version 0, edited on Mar 18, 2026 at 8:49:40 AM by Jpm (next)

comment:7 by Jpm, on Mar 18, 2026 at 12:17:27 PM

Any reason you check 0x7FFD and if $i<15
I understand 1000 to 5000 are related to icons
what about 6000 to 7000 or F000?

comment:8 by anonymous, on Mar 18, 2026 at 10:43:47 PM

The wparam of TVM_SETEXTENDEDSTYLE is Mask used to select the styles to be set.

I've used 0x7FFD to validate the user input. All defined flags are 0x7FFF, but $TVS_EX_MULTISELECT is essentially illegal. If we explicitly ignore that bit, the mask comes to 0x7FFD. Alternately we could use 0xFFFFFFFF to accept anything for $iExStyle. Or apparently 0 - but that's undocumented!

For the $i<15 part - its possible setup a custom imagelist in place of the checkbox images. I believe you can technically have more states this way. Only 4 bits are used to set the check state with TV_SETITEM though, so anything over 0x0F is illegal and will spill over the TVIS_STATEIMAGEMASK mask after the bitshift.

comment:9 by Jpm, on Mar 19, 2026 at 1:04:06 AM

if $i<15 is legal for me 0x7FFD need to be 0xFFFD
Right ?

comment:10 by MattyD, on Mar 19, 2026 at 5:48:32 AM

Nah they're separate things...

#include <GuiTreeView.au3>
#include <GuiConstants.au3>

Global Const $TVM_GETEXTENDEDSTYLE = 0x112D

Example()

Func Example()
        Local $hGUI = GUICreate("Example", 300, 400)
        GUICtrlCreateLabel("Custom checkboxes", 4, 4, 292, 18, BitOR($SS_CENTER, $SS_CENTERIMAGE))
        Local $hTreeView = _GUICtrlTreeView_Create($hGUI, 4, 26, 292, 3922, BitOR($TVS_DEFAULT, $TVS_CHECKBOXES))

        Local $hImgList = _CreateFillImageList()
        _SendMessage($hTreeView, $TVM_SETIMAGELIST, $TVSIL_STATE, $hImgList)

        ConsoleWrite("TV Extended Style: 0x" & Hex(_GUICtrlTreeView_GetExtendedStyle($hTreeView), 8) & @CRLF)

        Local $iState
        For $i = 0 To 15
                $hItem = _GUICtrlTreeView_AddChild($hTreeView, $TVI_ROOT, "Tree View Item " & $i)
                _GUICtrlTreeView_SetCheck($hTreeView, $hItem, $i)
                $iState = _GUICtrlTreeView_GetCheck($hTreeView, $hItem)
                ConsoleWrite(StringFormat("Item: %d    | Index: 0x%02X    | State for TVItemEx struct: 0x%08X", $i, $iState, BitShift($iState, -12)) & @CRLF)
        Next

        _GUICtrlTreeView_Expand($hTreeView)

        GUISetState()

        Do
        Until GUIGetMsg() = $GUI_EVENT_CLOSE
        GUIDelete($hGUI)
        _GUIImageList_Destroy($hImgList)
EndFunc

Func _GUICtrlTreeView_SetCheck($hWnd, $hItem, $iIndex)
        If Not IsHWnd($hItem) Then $hItem = _GUICtrlTreeView_GetItemHandle($hWnd, $hItem)

        Local $tItem = $__g_tTVItemEx
        DllStructSetData($tItem, "Mask", BitOR($TVIF_HANDLE, $TVIF_STATE))
        DllStructSetData($tItem, "hItem", $hItem)
        DllStructSetData($tItem, "State", BitShift($iIndex, -12)) ;INDEXTOSTATEIMAGEMASK macro (https://learn.microsoft.com/en-us/windows/win32/api/commctrl/nf-commctrl-indextostateimagemask)
        DllStructSetData($tItem, "StateMask", $TVIS_STATEIMAGEMASK)

        Return __GUICtrlTreeView_SetItem($hWnd, $tItem)
EndFunc

Func _GUICtrlTreeView_GetCheck($hWnd, $hItem)
        If Not IsHWnd($hItem) Then $hItem = _GUICtrlTreeView_GetItemHandle($hWnd, $hItem)

        Local $tItem = $__g_tTVItemEx
        DllStructSetData($tItem, "Mask", $TVIF_STATE)
        DllStructSetData($tItem, "hItem", $hItem)
        DllStructSetData($tItem, "StateMask", $TVIS_STATEIMAGEMASK)
        __GUICtrlTreeView_GetItem($hWnd, $tItem)

        Return BitShift(DllStructGetData($tItem, "State"), 12)
EndFunc

Func _GUICtrlTreeView_GetExtendedStyle($hTreeView)
        Local $iResult = _SendMessage($hTreeView, $TVM_GETEXTENDEDSTYLE)
        Return SetError(@error, @extended, $iResult)
EndFunc

Func _ImageList_AddIcon($hImgList, $hIcon)
        Local $aCall = DllCall("comctl32.dll", "int", "ImageList_AddIcon", "handle", $hImgList, "handle", $hIcon)
        If @error Then Return SetError(@error, @extended, $aCall)
        Return $aCall[0]
EndFunc

Func _CreateFillImageList()
        Local $hImgList = _GUIImageList_Create(16, 16, 5, 0, 16, 0)
        Local $hLib = _WinAPI_LoadLibrary("ddores.dll")
        Local $hMod = _WinAPI_GetModuleHandle("ddores.dll")
        _ImageList_AddIcon($hImgList, 0)

        Local $hIcon
        Local $iImgCount = 0, $iImgResIdx = 1
        Do
                $hIcon = _WinAPI_LoadImage($hMod, $iImgResIdx, $IMAGE_ICON, 16, 16, 1)
                If $hIcon Then
                        If Not $iImgCount Then _ImageList_AddIcon($hImgList, $hIcon)
                        $iImgCount += 1
                        _ImageList_AddIcon($hImgList, $hIcon)
                EndIf

                $iImgResIdx += 1
        Until $iImgCount = 16

        _WinAPI_FreeLibrary($hLib)
        Return $hImgList
EndFunc

comment:11 by pixelsearch, on Mar 19, 2026 at 12:51:16 PM

In case it helps, I found a web page concerning the TVS_EX_RICHTOOLTIP style.
Also it's interesting to see how they use wParam & lParam in TVM_SETEXTENDEDSTYLE
https://codexpertro.wordpress.com/2014/10/05/tree-view-control-tvs_ex_richtooltip-style/

comment:12 by Jpm, on Mar 19, 2026 at 2:03:35 PM

Thanks
Infact your new _GUICtrlTreewView_GetCheck is infact _GUICtrlTreeView_GetStateImageIndex

I am wondering what _GUICtrlTreewView_GetChecked must return on $TVS_EX_*
In fact Dimmed and Exclusion return False

comment:13 by MattyD, on Mar 20, 2026 at 5:20:00 PM

Ah ok thanks, I've somehow missed that.

But yeah, dunno what the best approach is.

I see _GUICtrlTreewView_GetChecked() currently returns:

BitAND(DllStructGetData($tItem, "State"), $TVIS_CHECKED) = $TVIS_CHECKED

Which probably isn't ideal as the check indexes aren't a bit field. Just as a point of interest, TVIS_CHECKED and TVIS_UNCHECKED aren't actually windows constants either, so I guess they were made up to avoid magic numbers.

I'd almost be inclined to do something this, and say in the doco that $TVS_CHECKBOXES is required here. You cant use TV_EX* checks with the TVS_CHECKBOXES style, so this would just support the check/uncheck toggle.

Func _GUICtrlTreeView_GetChecked($hWnd, $hItem)
        Local $iError, $iCheckState = _GUICtrlTreeView_GetStateImageIndex($hWnd, $hItem)
        If ($iCheckState < 1) Or ($iCheckState > 2) Then $iError = 1
        Return SetError($iError, 0, ($iCheckState = 2))
EndFunc

This kinda makes sense as the inverse to SetChecked too?

Modify Ticket

Action
as new The ticket will remain with no owner.

Add Comment


E-mail address and name can be saved in the Preferences .
 
Note: See TracTickets for help on using tickets.