Jump to content
Sign in to follow this  

[Solved] TreeView: No way to set item text and background color for different TreeView level

Recommended Posts


Hi Community,

I have a problem with the usage of _GUICtrlTreeView_AddChild and setting different item text colors (and different background colors), separately for the TreeView levels.

I use the UDF GUITreeViewEx.au3 of 'Melba23' and I renamed the functions to increase my understanding about the content. I already talked to him about his UDF to respect his rights and intellectual property. I read many forum threads, I tried many ways to get it, but it's seems to be impossible in the way that I use the UDF.

How can I set different item text colors, separately for the TreeView levels?
How can I set different item background colors, separately for the TreeView levels?

I found out that _GUICtrlTreeView_AddChild don't let my set this properties directly. But after loading the TreeView content I can't change the items (children) too. Only the font weight to bold I could set with _GUICtrlTreeView_SetBold but I want to do this in a generic way directly at the creation (loading) of the TreeView.

Of course I tried the different functions to set text color or bkgColor, but it didn't work - maybe I do it wrong.
I really hope you can help me, give me a hint and understand what I want to do.

[Solved] final solution made by @LarsJ (see below)

Thanks for your help - I'm grateful!



As attachment you will find a *.zip which contains 3 files. Two *.au3 files and one *.ini file.
The ini contains the TreeView levels as ini sections. I think you will see what I mean, if you try it :) .



In the animated *.gif you can see that I only got bold text font for the parent items. But the parents and the next level 'Feature' should have different text colors and different background colors which should be dynamically created, not like I do with _setParentTextToBold( 'Section1' ) manually.






Edited by Sven-Seyfert

// Innovation creates curiosity - curiosity innovation //

Share this post

Link to post
Share on other sites

Mr. Sven-Seyfert, You do it this way:

#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6

; compiler informations for AutoIt
#AutoIt3Wrapper_Res_Description=ExecutionPlan (2018-05-11)

; includes ---------------------------------------------------------------------
#include <Array.au3>
#include <ButtonConstants.au3>
#include <GuiConstantsEx.au3>
#include <GuiTreeView.au3>
#include <WindowsConstants.au3>

; opt and just singleton -------------------------------------------------------
Opt( 'MustDeclareVars', 1 )
Global $aInst = ProcessList( 'ExecutionPlan.exe' )
If $aInst[0][0] > 1 Then Exit

; declaration ------------------------------------------------------------------
Global $sFileConfig              = @ScriptDir & '\ExecutionPlan_Config.ini'

Global $aSection1                = IniReadSection( $sFileConfig, 'Section1' )
Global $aSection2                = IniReadSection( $sFileConfig, 'Section2' )
Global $aSection3                = IniReadSection( $sFileConfig, 'Section3' )
Global $aSection4                = IniReadSection( $sFileConfig, 'Section4' )

Global $bCheck                   = True
Global $hItemSelected            = 0
Global $aTreeViewDataArray[1][2] = [[0, 0]]
Global $sTreeViewData

; gui --------------------------------------------------------------------------
Global $hMainGui      = GUICreate( 'ExecutionPlan', 625, 700 )
Global $cTreeView     = GUICtrlCreateTreeView( 0, 0, 625, 630, BitOR( $GUI_SS_DEFAULT_TREEVIEW, $TVS_CHECKBOXES ) )
Global $cBtnAllOrNone = GUICtrlCreateButton( '', 10, 640, 50, 50, $BS_ICON )
Global $cBtnRun       = GUICtrlCreateButton( '', 70, 640, 50, 50, $BS_ICON )
Global $cBtnExit      = GUICtrlCreateButton( '', 565, 640, 50, 50, $BS_ICON )

GUICtrlSetImage( $cBtnAllOrNone, 'shell32.dll', 274, 1 )
GUICtrlSetImage( $cBtnRun,       'shell32.dll', 25, 1 )
GUICtrlSetImage( $cBtnExit,      'shell32.dll', 28, 1 )

GUICtrlSetTip( $cBtnAllOrNone,   'Toggle Checkboxes' )
GUICtrlSetTip( $cBtnRun,         'Execute checked test scenarios' )
GUICtrlSetTip( $cBtnExit,        'Exit program' )

; functions --------------------------------------------------------------------
#include 'ExecutionPlan_Functions.au3'

; Register WM_NOTIFY message handler through subclassing
Global $pWM_NOTIFY = DllCallbackGetPtr( DllCallbackRegister( "WM_NOTIFY", "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr" ) )
DllCall( "comctl32.dll", "bool", "SetWindowSubclass", "hwnd", $hMainGui, "ptr", $pWM_NOTIFY, "uint_ptr", 9999, "dword_ptr", GUICtrlGetHandle( $cTreeView ) ) ; $iSubclassId = 9999, $pData = $hTreeView

; processing -------------------------------------------------------------------
_appendTreeViewDataByIniSection( 'Section1|', $aSection1 )
_appendTreeViewDataByIniSection( 'Section2|', $aSection2 )
_appendTreeViewDataByIniSection( 'Section3|', $aSection3 )
_appendTreeViewDataByIniSection( 'Section4|', $aSection4 )

_loadTreeViewData( $cTreeView, StringTrimRight( $sTreeViewData, 1 ) )

_GUICtrlTreeView_Expand( $cTreeView )

_setParentTextToBold( 'Section1' )
_setParentTextToBold( 'Section2' )
_setParentTextToBold( 'Section3' )
_setParentTextToBold( 'Section4' )

GUISetState( @SW_SHOW, $hMainGui )

GUIRegisterMsg( $WM_NOTIFY, '_treeView_WM_NOTIFY_Handler' )
_createArrayOfCurrentCheckboxState( $cTreeView )

While 1
    Global $eMsg = GUIGetMsg()

    Switch $eMsg
        Case $GUI_EVENT_CLOSE, $cBtnExit
            ; Remove WM_NOTIFY message handler
            DllCall( "comctl32.dll", "bool", "RemoveWindowSubclass", "hwnd", $hMainGui, "ptr", $pWM_NOTIFY, "uint_ptr", 9999 )
            _disposeAndExit( $cTreeView )
        Case $cBtnAllOrNone
            If $bCheck Then
                _toggleCheckboxes( $cTreeView, $bCheck )
                $bCheck = False
                _toggleCheckboxes( $cTreeView, $bCheck )
                $bCheck = True
        Case $cBtnRun
            Global $aData = _getDataAsArray( $cTreeView )
            _ArrayDisplay( $aData )


Func WM_NOTIFY( $hWnd, $iMsg, $wParam, $lParam, $iSubclassId, $hTreeView ) ; $pData = $hTreeView
  If $iMsg <> $WM_NOTIFY Then Return DllCall( "comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam )[0]

  Local $tStruct  = DllStructCreate( _
    'struct;hwnd hWndFrom;uint_ptr IDFrom;INT Code;endstruct;' & _
    'uint Action;struct;uint OldMask;handle OldhItem;uint OldState;uint OldStateMask;' & _
    'ptr OldText;int OldTextMax;int OldImage;int OldSelectedImage;int OldChildren;lparam OldParam;endstruct;' & _
    'struct;uint NewMask;handle NewhItem;uint NewState;uint NewStateMask;' & _
    'ptr NewText;int NewTextMax;int NewImage;int NewSelectedImage;int NewChildren;lparam NewParam;endstruct;' & _
    'struct;long PointX;long PointY;endstruct', $lParam )

  If DllStructGetData( $tStruct, 'hWndFrom' ) <> HWnd( $hTreeView ) Then _
    Return DllCall( "comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam )[0]

  Switch DllStructGetData( $tStruct, 'Code' )
      Local $tNMTVCUSTOMDRAW = DllStructCreate($tagNMTVCUSTOMDRAW, $lParam)
      Local $dwDrawStage = DllStructGetData($tNMTVCUSTOMDRAW, "DrawStage")
      Switch $dwDrawStage             ; Holds a value that specifies the drawing stage
        Case $CDDS_PREPAINT           ; Before the paint cycle begins
          Return $CDRF_NOTIFYITEMDRAW ; Notify the parent window of any item-related drawing operations
        Case $CDDS_ITEMPREPAINT       ; Before painting an item
          Local $iLevel = 0, $hItem = DllStructGetData($tNMTVCUSTOMDRAW, "ItemSpec")
          Local $iState = DllStructGetData($tNMTVCUSTOMDRAW, "ItemState")
          If Not $hItem Or BitAnd( $iState, $CDIS_FOCUS ) Then Return $CDRF_NEWFONT
          While $hItem And $iLevel < 3
            $hItem = _SendMessage(HWnd( $hTreeView ), $TVM_GETNEXTITEM, $TVGN_PARENT, $hItem, 0, "wparam", "handle", "handle")
            $iLevel += 1
          Switch $iLevel
            Case 1
              DllStructSetData( $tNMTVCUSTOMDRAW, "ClrText", ColorConvert(0xFFFFFF) )   ; Forecolor of item text
              DllStructSetData( $tNMTVCUSTOMDRAW, "clrTextBk", ColorConvert(0x006400) )  ; Backcolor of item text
            Case 2
              DllStructSetData( $tNMTVCUSTOMDRAW, "ClrText", ColorConvert(0xFFFFFF) )   ; Forecolor of item text
              DllStructSetData( $tNMTVCUSTOMDRAW, "clrTextBk", ColorConvert(0x008B8B) )  ; Backcolor of item text
          Return $CDRF_NEWFONT        ; $CDRF_NEWFONT must be returned after changing font or colors

  Return DllCall( "comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam )[0]
  #forceref $iSubclassId

;RGB to BGR or BGR to RGB
Func ColorConvert($iColor)
  Return BitOR(BitAND($iColor, 0x00FF00), BitShift(BitAND($iColor, 0x0000FF), -16), BitShift(BitAND($iColor, 0xFF0000), 16))


Share this post

Link to post
Share on other sites

Hi @LarsJ,

that's amazing. Honestly I couldn't do that way on my own. It's a bit too much of DLLStructs, which is a complex topic for me.
But I'm really grateful for your help and great solution.

Thanks for your help - I'm grateful!

Edited by Sven-Seyfert

// Innovation creates curiosity - curiosity innovation //

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By MesterPerfect
      good morning
      this is the first post here in the autoit forums
      i hope that you can help me in my problem
      i have a JSON encoded
      it a map of my forums
      where i want to make a treeview that have the same type of map
      a system (as category)
      windows (as sub category)
      software (as an child item in the windows category)
      i don't know how to do that
      so, i know that i can do that using the json functions
      but i need your help about how we can do it as the type that i told you
      by the way i need to put the sub info for each item in an array that give me the ability to manage my items
      can post thread
      can reply
      message cound ...
      you just give me a small example and i can continue.
      am sorry if this against the rules of the forum.
      but i realy searched a lot but i couldn't
      i hope some one give me the way.
      thank you very much in advance
      here is the link of json forum
      and here is my encoded json file
      { "tree_map": { "0": [ 1, 5, 6, 7 ], "1": [ 2 ], "2": [ 4 ], "5": [ 3 ], "6": [ 8 ], "8": [ 9, 10 ] }, "nodes": [ { "breadcrumbs": [], "description": "", "display_in_list": true, "display_order": 1, "node_id": 1, "node_name": null, "node_type_id": "Category", "parent_node_id": 0, "title": "Main category", "type_data": {} }, { "breadcrumbs": [ { "node_id": 1, "title": "Main category", "node_type_id": "Category" } ], "description": "", "display_in_list": true, "display_order": 1, "node_id": 2, "node_name": null, "node_type_id": "Forum", "parent_node_id": 1, "title": "Main forum", "type_data": { "allow_poll": true, "allow_posting": true, "can_create_thread": true, "can_upload_attachment": true, "discussion_count": 0, "last_post_date": 0, "last_post_id": 0, "last_post_username": "", "last_thread_id": 0, "last_thread_prefix_id": 0, "last_thread_title": "", "message_count": 0, "min_tags": 0, "require_prefix": false } }, { "breadcrumbs": [ { "node_id": 1, "title": "Main category", "node_type_id": "Category" }, { "node_id": 2, "title": "Main forum", "node_type_id": "Forum" } ], "description": "", "display_in_list": true, "display_order": 1, "node_id": 4, "node_name": null, "node_type_id": "Forum", "parent_node_id": 2, "title": "my forums1", "type_data": { "allow_poll": true, "allow_posting": true, "can_create_thread": true, "can_upload_attachment": true, "discussion_count": 0, "last_post_date": 0, "last_post_id": 0, "last_post_username": "", "last_thread_id": 0, "last_thread_prefix_id": 0, "last_thread_title": "", "message_count": 0, "min_tags": 0, "require_prefix": false } }, { "breadcrumbs": [], "description": "", "display_in_list": true, "display_order": 2, "node_id": 5, "node_name": null, "node_type_id": "Category", "parent_node_id": 0, "title": "Perfect", "type_data": {} }, { "breadcrumbs": [ { "node_id": 5, "title": "Perfect", "node_type_id": "Category" } ], "description": "", "display_in_list": true, "display_order": 2, "node_id": 3, "node_name": null, "node_type_id": "Forum", "parent_node_id": 5, "title": "ahmed", "type_data": { "allow_poll": true, "allow_posting": true, "can_create_thread": true, "can_upload_attachment": true, "discussion_count": 0, "last_post_date": 0, "last_post_id": 0, "last_post_username": "", "last_thread_id": 0, "last_thread_prefix_id": 0, "last_thread_title": "", "message_count": 0, "min_tags": 0, "require_prefix": false } }, { "breadcrumbs": [], "description": "", "display_in_list": true, "display_order": 3, "node_id": 6, "node_name": null, "node_type_id": "Forum", "parent_node_id": 0, "title": "autoit", "type_data": { "allow_poll": true, "allow_posting": true, "can_create_thread": true, "can_upload_attachment": true, "discussion_count": 0, "last_post_date": 0, "last_post_id": 0, "last_post_username": "", "last_thread_id": 0, "last_thread_prefix_id": 0, "last_thread_title": "", "message_count": 0, "min_tags": 0, "require_prefix": false } }, { "breadcrumbs": [ { "node_id": 6, "title": "autoit", "node_type_id": "Forum" } ], "description": "", "display_in_list": true, "display_order": 3, "node_id": 8, "node_name": null, "node_type_id": "Forum", "parent_node_id": 6, "title": "examples", "type_data": { "allow_poll": true, "allow_posting": true, "can_create_thread": true, "can_upload_attachment": true, "discussion_count": 0, "last_post_date": 0, "last_post_id": 0, "last_post_username": "", "last_thread_id": 0, "last_thread_prefix_id": 0, "last_thread_title": "", "message_count": 0, "min_tags": 0, "require_prefix": false } }, { "breadcrumbs": [ { "node_id": 6, "title": "autoit", "node_type_id": "Forum" }, { "node_id": 8, "title": "examples", "node_type_id": "Forum" } ], "description": "", "display_in_list": true, "display_order": 3, "node_id": 9, "node_name": null, "node_type_id": "Forum", "parent_node_id": 8, "title": "GUI", "type_data": { "allow_poll": true, "allow_posting": true, "can_create_thread": true, "can_upload_attachment": true, "discussion_count": 0, "last_post_date": 0, "last_post_id": 0, "last_post_username": "", "last_thread_id": 0, "last_thread_prefix_id": 0, "last_thread_title": "", "message_count": 0, "min_tags": 0, "require_prefix": false } }, { "breadcrumbs": [ { "node_id": 6, "title": "autoit", "node_type_id": "Forum" }, { "node_id": 8, "title": "examples", "node_type_id": "Forum" } ], "description": "", "display_in_list": true, "display_order": 31, "node_id": 10, "node_name": null, "node_type_id": "Forum", "parent_node_id": 8, "title": "windowEX", "type_data": { "allow_poll": true, "allow_posting": true, "can_create_thread": true, "can_upload_attachment": true, "discussion_count": 0, "last_post_date": 0, "last_post_id": 0, "last_post_username": "", "last_thread_id": 0, "last_thread_prefix_id": 0, "last_thread_title": "", "message_count": 0, "min_tags": 0, "require_prefix": false } }, { "breadcrumbs": [], "description": "", "display_in_list": true, "display_order": 4, "node_id": 7, "node_name": null, "node_type_id": "Category", "parent_node_id": 0, "title": "vbs", "type_data": {} } ] }  
    • By Burgs
        I am having great difficulty with something I would have thought to be fairly easy.  I have an array containing (military) organization strings, similar to this:
      42nd Battalion
       Company A
        1st Platoon
         1st Squad
         2nd Squad
         3rd Squad
        2nd Platoon
         ...1st, 2nd, 3rd Squad
        3rd Platoon
        ...1st, 2nd, 3rd Squad
       Company B
      I also have an associated array that contains the 'hierarchy' information associated with each string..."0", "1","2", etc   ...therefore using example above the "0" would associate with "42nd Battalion", while "1" would be "Company A", "2" is "1st Platoon", etc.  Each sequential number is a 'child' of the preceding number.  Therefore the information above would appear in the array as "0", "1", "2", "3", "3", "3", "2", "3", "3", "3", "2", "3", "3", "3", "1", etc...
        My issue is that I'm having great difficulty creating a 'Treeview' control using this information.  Mainly due to the fact that entries can, and will...repeat (for example multiple entries for "Company A", "Company B", "1st Platoon", "1st Squad", etc, etc).  The following code is operative, however it does not create the treeview items as 'child' entries of one another...it simply lists each item as a separate entity.
      For $_populate = 0 to Ubound($_HIERARCHY) - 1 _GUICtrlTreeView_BeginUpdate($idTreeView) _GUICtrlTreeView_Add($idTreeView, $_HIERARCHY[$_populate], String($_STRUCTURES[$_populate])) _GUICtrlTreeView_EndUpdate($idTreeView) Next ;Next $_populate, cycle thru '$_HIERARCHY' array to build 'TREEVIEW' Controls As I mentioned earlier I thought I could manage this...however i'm pulling out quite a bit of my hair trying to get this working properly...any help would be appreciated.  I thank you in advance. 
    • By xtcislove
      i stuck again,
      Im using this function to create a treeview from root dir.
      ;https://autoit.de/index.php?thread/86082-treeview-root-verbergen/&postID=691139#post691139 #include <File.au3> #include <WindowsConstants.au3> Global $sPath = @ScriptDir Global $hGui = GUICreate('TreeView-Example', 400, 600) Global $idTreeView = GUICtrlCreateTreeView(10, 10, 380, 580, Default, $WS_EX_CLIENTEDGE) GUISetState() _CreatePath($sPath, $idTreeView) Do Until GUIGetMsg() = -3 Func _CreatePath($sPath, $idParent) Local $aFolder, $aFiles, $idItem If StringRight($sPath, 1) <> '\' Then $sPath &= '\' $aFolder = _FileListToArray($sPath, '*', $FLTA_FOLDERS) If Not @error Then For $i = 1 To $aFolder[0] $idItem = GUICtrlCreateTreeViewItem($aFolder[$i], $idParent) _CreatePath($sPath & $aFolder[$i], $idItem) Next EndIf $aFiles = _FileListToArray($sPath, '*', $FLTA_FILES) If @error Then Return For $i = 1 To $aFiles[0] $idItem = GUICtrlCreateTreeViewItem($aFiles[$i], $idParent) Next EndFunc Folder Structure:

      If a file exists in multiple folders, i like to color it red, if not green. 

      I know how to do this for files, but nut for the folders.

      Because if there is only 1 file in Folder2 that is also in Folder1 that it should only color this single file red, inlcuding its whole tree.

      The Folder1 and Folder2 should be red in this case, too. Other files and trees should stay green.
      Basically i like to color a file and its belonging tree red if the file exists more than 1 time.
    • By xtcislove

      im searching like 6 hours and i didnt found the right solution.

      Im trying to build a treeview from a directory and its subfolders etc.

      This function give me right treeview, but i cant color each item seperated.

      #include <GuiTreeView.au3> $hGui = GUICreate("Demo1", 600, 400) $hTreeView = _GUICtrlTreeView_Create($hGui, 10, 10, 580, 380) GUISetState() _GUICtrlTreeView_BeginUpdate($hTreeView) ListFiles_ToTreeView(@ScriptDir, 0) _GUICtrlTreeView_EndUpdate($hTreeView) Do Until GUIGetMsg() = -3 Func ListFiles_ToTreeView($sSourceFolder, $hItem) Local $sFile ; Force a trailing \ If StringRight($sSourceFolder, 1) <> "\" Then $sSourceFolder &= "\" ; Start the search Local $hSearch = FileFindFirstFile($sSourceFolder & "*.*") ; If no files found then return If $hSearch = -1 Then Return ; This is where we break the recursive loop <<<<<<<<<<<<<<<<<<<<<<<<<< ; Now run through the contents of the folder While 1 ; Get next match $sFile = FileFindNextFile($hSearch) ; If no more files then close search handle and return If @error Then ExitLoop ; This is where we break the recursive loop <<<<<<<<<<<<<<<<<<<<<<<<<< ; Check if a folder If @extended Then ; If so then call the function recursively ListFiles_ToTreeView($sSourceFolder & $sFile, _GUICtrlTreeView_AddChild($hTreeView, $hItem, $sFile)) Else ; If a file than write path and name _GUICtrlTreeView_AddChild($hTreeView, $hItem, $sFile) EndIf WEnd ; Close search handle FileClose($hSearch) EndFunc ;==>ListFiles_ToTreeView
      So i am searching for the exact same function just with
      instead of 
      Ps: i have a folder structure where i like to color each item green if a file only exist once and red if it exist more than once.

      Could someone help?

    • By gillesg
      I am struggling in merging GUITreeViewEx, Shelltristate and enhancing to handle a third state that means : some items under are selected.
      I have difficulties handling expand order and key Space (especially when node is collapsed).
      Here the zip with UDF and and example.
      The problem I might need some advice to handle : 
      1- When load Treeview, have a correct settings of the checkbox for a tristate tree
      2 - Handle keyboard used for walking in tree
           Chicken is checked and  Steak is unchecked
          When walking with arrow to Meat, it gets unchecked
      3 - When node is collapsed and checked thru keyboard (space)
         the middle state is possible which should not
      Here is joined an animated gif showing the 3 problems
      Thanks for your advices

  • Create New...