Announcement

Collapse
No announcement yet.

Treeview, checkboxes, howto?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Treeview, checkboxes, howto?

    I started with a treeview to respresent a heirarchy with just two layers, and used the "selected" state of items to drive some processing. This works, but processing a single selection at a time is a trifle wearying for the user, so I aim to adapt the application to retreive any checked parent name and the names of any checked children, each preceded by the parent name, then process the whole batch together. I investigated multiple selections from the treeview. This looked hard, so I turned back towards using checkboxes.
    This requires a few pieces to be fitted together, including:
    1. How to turn off "selectability" - it's confusing having a selected item flashing away when you are checking boxes somewhere else.
    2. How to make the program check the parent if one of its children is checked, the parent can also be checked by the user.


    Any hints, tips, nudges or wrinkles will be welcome.

  • #2
    I am also working on a treeview currently, but without checkboxes. This one by Kev Peel gives a good start.
    http://www.powerbasic.com/support/pb...light=treeview
    regards, Ian
    :) IRC :)

    Comment


    • #3
      Here is an example of almost everything you can do with a treeview control

      Code:
      #COMPILE EXE
      #DIM ALL
      
      #INCLUDE "WIN32API.INC"
      #INCLUDE "InitCtrl.inc"
      #INCLUDE "COMMCTRL.INC"
      
      #RESOURCE "TView.pbr"
      
      %ID_TVIEW     = 1000
      %IDC_BUTTON1  = 1001
      %IDC_BUTTON2  = 1002
      %IDC_BUTTON3  = 1003
      %IDC_BUTTON4  = 1004
      %IDC_BUTTON5  = 1005
      %IDC_BUTTON6  = 1006
      %IDC_BUTTON7  = 1007
      %IDC_BUTTON8  = 1008
      %IDC_BUTTON9  = 1009
      %IDC_BUTTON10 = 1010
      %IDC_BUTTON11 = 1011
      %IDC_BUTTON12 = 1012
      %IDC_BUTTON13 = 1013
      %IDC_BUTTON14 = 1014
      %IDC_BUTTON15 = 1015
      %IDC_BUTTON16 = 1016
      %IDC_BUTTON17 = 1017
      %IDC_BUTTON18 = 1018
      %IDC_BUTTON19 = 1019
      %IDC_BUTTON20 = 1020
      %IDC_BUTTON21 = 1021
      %IDC_BUTTON22 = 1022
      %IDC_BUTTON23 = 1023
      %IDC_BUTTON24 = 1024
      %IDC_BUTTON25 = 1025
      %IDC_BUTTON26 = 1026
      %IDC_BUTTON27 = 1027
      %IDC_BUTTON28 = 1028
      %IDC_BUTTON29 = 1029
      %IDC_BUTTON30 = 1030
      %IDC_BUTTON31 = 1031
      %IDC_BUTTON32 = 1032
      %IDC_BUTTON33 = 1033
      %IDC_BUTTON34 = 1034
      %IDC_BUTTON35 = 1035
      %IDC_BUTTON36 = 1036
      %IDC_BUTTON37 = 1037
      %IDC_BUTTON38 = 1038
      %IDC_BUTTON39 = 1039
      %IDC_BUTTON40 = 1040
      %IDC_BUTTON41 = 1041
      %IDC_BUTTON42 = 1042
      %IDC_BUTTON43 = 1043
      %IDC_BUTTON44 = 1044
      %IDC_BUTTON45 = 1045
      
      %ID_HASBUTTONS       = 1006
      %ID_HASLINES         = 1004
      %ID_HASLINESATROOT   = 1005
      %ID_HASSHOWSELALWAYS = 1007
      %ID_HASEDITLABELS    = 1008
      %ID_HASCHECKBOXES    = 1009
      %IDC_FRAME1          = 1010
      %IDC_LABEL1          = 1011
      %IDOK                =    1
      %ID_HASFULLROWSELECT       = 1012
      %ID_HASINFOTIP             = 1013
      %ID_HASNONEVENHEIGHT       = 1014
      %ID_HASNOTOOLTIPS          = 1015
      %ID_HASRTLREADING          = 1016
      %ID_HASSINGLEEXPAND        = 1017
      %ID_HASTRACKSELECT         = 1018
      %ID_HASNOHSCROLL           = 1019
      %ID_HASNOSCROLL            = 1020
      %IDC_FRAME2                = 1026
      %ID_HASAUTOSCROLL          = 1021
      %ID_HASDIMMEDCHECKBOXES    = 1022
      %ID_HASDOUBLEBUFFER        = 1023
      %ID_HASDRAWIMAGESYNC       = 1024
      %ID_HASEXCLUSIONCHECKBOXES = 1025
      %ID_HASFADEINOUTEXPANDOS   = 1027
      %ID_HASNOINDENTSTATE       = 1028
      %ID_HASPARTIALCHECKBOXES   = 1029
      %ID_HASRICHTOOLTIP         = 1030
      
      GLOBAL TVStyles AS LONG
      GLOBAL TVExStyles AS LONG
      
      DECLARE FUNCTION BuildImagelist AS DWORD
      DECLARE SUB GetTVStyles
      
      FUNCTION PBMAIN () AS LONG
        LOCAL hdlg AS DWORD
      
        GetTVStyles
        TVStyles = TVStyles OR %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP
      
        ' Extended styles for the TreeView
        TVExStyles = TVExStyles OR %WS_EX_CONTROLPARENT OR %WS_EX_LEFT OR %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR
      
        'InitComCtl32
      
        DIALOG NEW PIXELS, 0, "TreeView Example", , , 880, 604, %WS_POPUP OR %WS_BORDER OR %WS_DLGFRAME OR %WS_SYSMENU OR %WS_CLIPSIBLINGS OR %WS_VISIBLE OR _
          %DS_MODALFRAME OR %DS_3DLOOK OR %DS_NOFAILCREATE OR %DS_SETFONT, %WS_EX_CONTROLPARENT OR %WS_EX_LEFT OR %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR, TO _
          hDlg
      
        CONTROL ADD "SysTreeView32", hDlg, %ID_TVIEW, "SysTreeView32_1", 2, 2, 245, 599, TVStyles, TVExStyles
      
         CONTROL ADD BUTTON, hDlg, %IDC_BUTTON1, "SET TEXT", 260, 8, 200, 33
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON2, "EDIT TEXT", 260, 73, 200, 33
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON3, "INSERT SIBLING AFTER", 465, 203, 201, 33
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON4, "DELETE", 260, 301, 200, 32
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON5, "SET IMAGE|SELIMAGE", 465, 73, 201, 33
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON6, "GET PARENT", 260, 138, 200, 33
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON7, "GET CHILD", 260, 171, 200, 32
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON8, "EXPAND|COLLAPSE", 465, 106, 201, 32
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON9, "GET COUNT", 260, 528, 200, 33
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON28, "INSERT SIBLING LAST", 465, 171, 201, 32
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON29, "INSERT CHILD LAST", 465, 301, 201, 32
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON10, "GET CHECK", 260, 366, 200, 32
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON11, "SET CHECK", 260, 398, 200, 33
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON12, "GET [FIRST|PREV|NEXT] VISIBLE", 260, 236, 200, 32
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON13, "GET INDENT", 260, 431, 200, 32
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON14, "SET INDENT", 260, 463, 200, 33
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON15, "INSERTMARK", 465, 8, 201, 33
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON16, "INSERTMARK COLOR", 465, 41, 201, 32
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON17, "GET TEXT", 260, 41, 200, 32
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON18, "GET SELECTED", 260, 496, 200, 32
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON19, "RESET", 260, 333, 200, 33
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON20, "ENDEDIT", 260, 106, 200, 32
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON21, "GET ROOT", 260, 268, 200, 33
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON22, "GET [PREV|NEXT] SIBLING", 260, 203, 200, 33
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON23, "INSERT SIBLING FIRST", 465, 138, 201, 33
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON24, "INSERT SIBLING SORTED", 465, 236, 201, 32
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON25, "GET VISIBLE COUNT", 260, 561, 200, 32
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON26, "INSERT CHILD FIRST", 465, 268, 201, 33
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON27, "INSERT CHILD AFTER", 465, 333, 201, 31
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON30, "SET BOLD [ON|OFF]", 465, 365, 201, 31
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON31, "GET BOLD", 465, 397, 201, 31
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON32, "ISEXPANDED", 465, 429, 201, 31
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON33, "SET LINECOLOR", 465, 461, 201, 31
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON34, "GET LINECOLOR", 465, 493, 201, 31
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON35, "SET TEXTCOLOR", 465, 525, 201, 31
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON36, "GET TEXTCOLOR", 465, 557, 201, 31
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON37, "SELECT", 670, 8, 201, 33
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON38, "SET VISIBLE", 670, 40, 201, 33
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON39, "SET ITEMHEIGHT", 670, 72, 201, 33
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON40, "GET ITEMHEIGHT", 670, 104, 201, 33
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON41, "SORT CHILDREN", 670, 136, 201, 33
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON42, "SORT CHILDREN [CALL SortingCallback]", 670, 168, 201, 33
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON43, "GET LPARAM", 670, 200, 201, 33
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON44, "SET LPARAM", 670, 232, 201, 33
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON45, "INSERT CHILD SORTED", 670, 264, 201, 33
      
      
        LOCAL hImageList AS DWORD
        LOCAL tTVInsert  AS TV_INSERTSTRUCT
        LOCAL hTree      AS DWORD
        LOCAL sItem      AS STRING
        LOCAL hNode      AS DWORD
        LOCAL hParentNode AS DWORD
      
        RANDOMIZE
      
        hTree = GetDlgItem(hdlg, %ID_TVIEW)
      '  local s as asciiz * 255
      '  s = "explorer"
      '  SetWindowTheme(hTree, byval varptr(s), byval 0)
      
        hImageList = BuildImageList
        TreeView_SetImageList(hTree, hImageList, %TVSIL_NORMAL)
      
        '************************************************************************************'
        ' Insert some items (parent and child nodes) into the treeview                      *'
        '************************************************************************************'
      
        sItem                          = "Root 1"        ' Text to be used for the Node
        tTVInsert.hParent              = 0               ' Parent Node, If TVI_ROOT or NULL, the item is inserted at the root
        tTVInsert.Item.Item.mask       = %TVIF_TEXT OR %TVIF_CHILDREN OR %TVIF_IMAGE OR %TVIF_SELECTEDIMAGE OR %TVIF_PARAM
        tTVInsert.Item.Item.pszText    = STRPTR(sItem)   ' Text used for the item
        tTVInsert.Item.Item.cchTextMax = LEN(sItem)      ' Length of text for the item
        tTVInsert.Item.Item.cchildren  = 1               ' Node as 1 or more child nodes
        tTVInsert.Item.Item.iImage     = 0
        tTVInsert.Item.Item.iSelectedImage = 1
        tTVInsert.Item.Item.lParam = RND(1, 10000)
        hParentNode = TreeView_InsertItem(hTree, tTVInsert)    ' Insert a new item and return its handle
        TreeView_SelectItem(htree, hParentNode)
      
        sItem                          = "Child 1 of Root 1 "
        tTVInsert.hParent              = hParentNode           ' Use the handle returned from inserted the root node
        tTVInsert.Item.Item.mask       = %TVIF_TEXT OR %TVIF_CHILDREN OR %TVIF_IMAGE OR %TVIF_SELECTEDIMAGE OR %TVIF_PARAM
        tTVInsert.Item.Item.pszText    = STRPTR(sItem)
        tTVInsert.Item.Item.cchTextMax = LEN(sItem)
        tTVInsert.Item.Item.cchildren  = 1
        tTVInsert.Item.Item.iImage     = 2
        tTVInsert.Item.Item.iSelectedImage = 3
        tTVInsert.Item.Item.lParam = RND(1, 10000)
        hNode = TreeView_InsertItem(hTree, tTVInsert)
      
        sItem                          = "Child 1 of (Root 1, Child 1)"
        tTVInsert.hParent              = hNode
        tTVInsert.Item.Item.mask       = %TVIF_TEXT OR %TVIF_IMAGE OR %TVIF_SELECTEDIMAGE OR %TVIF_PARAM
        tTVInsert.Item.Item.pszText    = STRPTR(sItem)
        tTVInsert.Item.Item.cchTextMax = LEN(sItem)
        tTVInsert.Item.Item.iImage     = 4
        tTVInsert.Item.Item.iSelectedImage = 5
        tTVInsert.Item.Item.lParam = RND(1, 10000)
        TreeView_InsertItem(hTree, tTVInsert)
      
        sItem                          = "Child 2 of Root 1 "
        tTVInsert.hParent              = hParentNode           ' Use the handle returned from inserted the root node
        tTVInsert.Item.Item.mask       = %TVIF_TEXT OR %TVIF_IMAGE OR %TVIF_SELECTEDIMAGE OR %TVIF_PARAM
        tTVInsert.Item.Item.pszText    = STRPTR(sItem)
        tTVInsert.Item.Item.cchTextMax = LEN(sItem)
        tTVInsert.Item.Item.iImage     = 2
        tTVInsert.Item.Item.iSelectedImage = 3
        tTVInsert.Item.Item.lParam = RND(1, 10000)
        hNode = TreeView_InsertItem(hTree, tTVInsert)
      
        sItem                          = "Root 2 "
        tTVInsert.hParent              = 0
        tTVInsert.Item.Item.mask       = %TVIF_TEXT OR %TVIF_CHILDREN OR %TVIF_IMAGE OR %TVIF_SELECTEDIMAGE OR %TVIF_PARAM
        tTVInsert.Item.Item.pszText    = STRPTR(sItem)
        tTVInsert.Item.Item.cchTextMax = LEN(sItem)
        tTVInsert.Item.Item.cchildren  = 1
        tTVInsert.Item.Item.iImage     = 2
        tTVInsert.Item.Item.iSelectedImage = 3
        tTVInsert.Item.Item.lParam = RND(1, 10000)
        hNode = TreeView_InsertItem(hTree, tTVInsert)
      
        sItem                          = "Child 1 of Root 2"
        tTVInsert.hParent              = hNode
        tTVInsert.Item.Item.mask       = %TVIF_TEXT OR %TVIF_IMAGE OR %TVIF_SELECTEDIMAGE OR %TVIF_PARAM
        tTVInsert.Item.Item.pszText    = STRPTR(sItem)
        tTVInsert.Item.Item.cchTextMax = LEN(sItem)
        tTVInsert.Item.Item.iImage     = 0
        tTVInsert.Item.Item.iSelectedImage = 1
        tTVInsert.Item.Item.lParam = RND(1, 10000)
        TreeView_InsertItem(hTree, tTVInsert)
      
        DIALOG SHOW MODAL hDlg, CALL DlgProc
      
        ImageList_Destroy(hImageList)
      END FUNCTION
      
      CALLBACK FUNCTION DlgProc
        LOCAL tTVItem     AS TV_ITEM
        LOCAL tTVInsert   AS TV_INSERTSTRUCT
        LOCAL hNode       AS DWORD
        LOCAL hChildNode  AS DWORD
        LOCAL hTree       AS DWORD
        LOCAL hParent     AS DWORD
        LOCAL TVnm        AS NM_TREEVIEW PTR
        LOCAL TVht        AS TV_HITTESTINFO
        STATIC OldText    AS STRING
        LOCAL NewText     AS STRING
        LOCAL hTVEdit     AS DWORD
        LOCAL s           AS STRING
        LOCAL s1          AS STRING
        LOCAL i           AS LONG
        LOCAL dwPos       AS DWORD
        LOCAL tTVSortCB   AS TV_SORTCB
      
        hTree =  GetDlgItem(CBHNDL, %ID_TVIEW)
      
        SELECT CASE AS LONG CBMSG
      
          CASE %WM_COMMAND
            SELECT CASE AS LONG CBCTL
      
              CASE %IDC_BUTTON1
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  ' Change the text of the selected node
      
                  ' Get the handle of the selected item(node)
                  hNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_CARET, 0)
      
                  NewText = "Set Text "+TIME$
      
                  tTVItem.Mask = %TVIF_TEXT
                  tTVItem.hItem = hNode
                  tTVItem.pszText = STRPTR(NewText)
                  tTVItem.cchTextMax = LEN(NewText)
      
                  'TreeView_SetItem(hTree, tTVItem)
                  SendMessage(hTree, %TVM_SETITEM, 0, BYVAL VARPTR(tTVItem))
      
                END IF
      
              CASE %IDC_BUTTON2
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  ' Edit the text of the first child of the first root
      
                  ' Get the handle of the selected item(node)
                  hNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_CARET, 0)
      
                  ' Cuases an edit box to be displayed at the node text
                  TreeView_EditLabel(hTree, hNode)
      
                  ' If you do not handle the TVN_ENDLABELEDIT message then the text
                  ' the user entered is discarded and the original text is set.
      
                  ' It is not necessary to handle the TVN_BEGINLABELEDIT notification but
                  ' it is a good idea to do so and limit the length of the text that the user may
                  ' enter into the edit control.
      
                END IF
      
              CASE %IDC_BUTTON3
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  ' Insert a new item after the selected item of the selected item
      
                  ' Get the handle of the selected item(node)
                  hNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_CARET, 0)
      
                  ' Get the parent of the selected node
                  hParent = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_PARENT, hNode)
      
                  tTVInsert.hParent      = hParent' It will have the same parent as the selected node
                  tTVInsert.hInsertAfter = hNode  ' Insert it after the first root node
      
                  NewText = "New After Node "+TIME$
      
                  tTVInsert.Item.Item.mask       = %TVIF_TEXT OR %TVIF_IMAGE OR %TVIF_SELECTEDIMAGE OR %TVIF_PARAM
                  tTVInsert.Item.Item.pszText    = STRPTR(NewText)
                  tTVInsert.Item.Item.cchTextMax = LEN(NewText)
                  tTVInsert.Item.Item.iImage     = 0
                  tTVInsert.Item.Item.iSelectedImage = 1
                  tTVInsert.Item.Item.lParam = RND(1, 10000)
      
                  SendMessage(hTree, %TVM_INSERTITEM, 0, BYVAL VARPTR(tTVInsert))
      
                END IF
      
              CASE %IDC_BUTTON4
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  ' Delete the selected node
      
                  hNode = TreeView_GetSelection(hTree)  ' Get the handle of the selected node
                  TreeView_DeleteItem(hTree, hNode)     ' Delete the node
      
                  ' If hNode above is TVI_ROOT then all nodes are deleted.
                  ' You could also call TreeView_DeleteAllItems to delete all items.
      
                END IF
      
              CASE %IDC_BUTTON5
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  ' Change the images associated with a node
      
                  hNode = TreeView_GetSelection(hTree)  ' Get the handle of the selected node
      
                  tTVItem.hItem = hNode
                  tTVItem.mask = %TVIF_IMAGE OR %TVIF_SELECTEDIMAGE ' Get the image information
                  tTVItem.iImage = 7
                  tTVItem.iSelectedImage = 6
                  TreeView_SetItem(hTree, tTVItem)
      
                END IF
      
              CASE %IDC_BUTTON6
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  ' Get the parent node of the selected node
      
                  hNode = TreeView_GetSelection(hTree)     ' Get the handle of the selected node
                  hNode = TreeView_GetParent(hTree, hNode) ' Get the handle of the parent of this node
      
                  ' Does this node have a parent?
                  IF hNode=%NULL THEN
                    ' The node does not have a parent
      
                    NewText = "This node does not have a parent"
      
                  ELSE
                    ' Get the text of the parent node
      
                    NewText = SPACE$(255)
      
                    tTVItem.hItem = hNode              ' Handle of node to get text of
                    tTVItem.mask  = %TVIF_TEXT         ' We only need the text
                    tTVItem.pszText = STRPTR(NewText)  ' String to put text in
                    tTVItem.cchTextMax = 255           ' Max string length
      
                    TreeView_GetItem(hTree, tTVItem)
                  END IF
      
                  ? "The parent is:"+$CRLF+NewText
      
                END IF
      
              CASE %IDC_BUTTON7
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  ' Enumerate children of the selected node
      
                  hNode = TreeView_GetSelection(hTree)     ' Get the handle of the selected node
      
                  s = ""
      
                  hNode = TreeView_GetChild(hTree, hNode)
      
                  WHILE (hNode<>%NULL)
                    ' Get the text of the child node found
      
                    NewText = SPACE$(255)
      
                    tTVItem.hItem = hNode              ' Handle of node to get text of
                    tTVItem.mask  = %TVIF_TEXT         ' We only need the text
                    tTVItem.pszText = STRPTR(NewText)  ' String to put text in
                    tTVItem.cchTextMax = 255           ' Max string length
      
                    TreeView_GetItem(hTree, tTVItem)
      
                    s = s + RTRIM$(REMOVE$(NewText, ANY CHR$(0))) + $CRLF
      
                    ' Get the next child node from the parent
                    ' Since hNode is a child of the parent node then
                    ' the easiest thing to do is to find this childs siblings
                    ' Otherwise we would have to have another variable for
                    ' the parent node
                    hNode = TreeView_GetNextSibling(hTree, hNode)
                  WEND
      
                  IF s = "" THEN s = "**This node has no children**"
                  s = "Found the following child nodes:"+$CRLF+s
                  ? s
      
                END IF
      
              CASE %IDC_BUTTON8
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  ' Expand an unexpanded node or collapse an expanded node
      
                  hNode= TreeView_GetSelection(hTree)     ' Get the handle of the selected node
      
                  ' Toggle the node : If expanded then collapse it or if collapsed expand it
                  TreeView_Expand(hTree, hNode, %TVE_TOGGLE)
      
                  ' You can also use TVE_EXPAND or TVE_COLLAPSE to explictly expand or
                  ' collapse a node. TVE_COLLAPSE OR TVE_COLLAPSERESET will collapse and
                  ' delete all child nodes.
      
                END IF
      
              CASE %IDC_BUTTON9
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  ' Get the count of all items in the treeview
      
                  ? "The count of items in the tree view is "+FORMAT$(TreeView_GetCount(hTree))
      
                END IF
      
              CASE %IDC_BUTTON10
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  ' Get the checked/unchecked/no checkbox state of the selected item
      
                  hNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_CARET, 0)
                  tTVItem.hItem = hNode
                  tTVItem.mask = %TVIF_STATE OR %TVIF_HANDLE
                  tTVItem.stateMask = %TVIS_STATEIMAGEMASK
      
                  SendMessage(hTree, %TVM_GETITEM, 0, BYVAL VARPTR(tTVItem))
                  i = tTVItem.state
      
                  ' Not really sure why this works but it does
                  ' MSDN says that that the return value is a unsigned int but then it says
                  ' it can return a -1.
                  ' I found the code below on several sites but no one explains why it works
                  '
                  ' Found this by accident in the Win32 SDK:
                  ' The INDEXTOSTATEIMAGEMASK macro prepares the index of a state image so that a tree-view
                  ' control or list-view control can use the index to retrieve the state image for an item.
                  '
                  ' This makes sense that it converts the imagemask to an imagelist index - the checkbox
                  ' as actuall two images one checked and one unchecked.
                  SHIFT RIGHT i, 12
      
                  SELECT CASE AS LONG i
                    CASE 0
                      s = "There is no checkbox for this item"
                    CASE 1
                      s = "Unchecked"
                    CASE 2
                      s = "Checked"
                    CASE ELSE
                      s = "Something went wrong and I got an incorrect value!"
                  END SELECT
                  ? s
      
                END IF
      
              CASE %IDC_BUTTON11
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  ' Set the checkbox to checked for the selected item
      
                  ' Get the handle of the selected item(node)
                  hNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_CARET, 0)
      
                  tTVItem.hItem = hNode
                  tTVItem.mask = %TVIF_STATE OR %TVIF_HANDLE
                  tTVItem.stateMask = %TVIS_STATEIMAGEMASK
      
                  ' 1 = Checkbox not checked
                  ' 2 = Checkbox is checked
                  ' See %IDC_BUTTON10 callback notes
                  i = 2
                  SHIFT LEFT i, 12
                  tTVItem.state = i
      
                  SendMessage(hTree, %TVM_SETITEM, 0, BYVAL VARPTR(tTVItem))
                END IF
      
      
              CASE %IDC_BUTTON12
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  ' Get the first visible node in the treeview
                  hNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_FIRSTVISIBLE, 0)
      
                  ' Get the text of (hNode) the first visible node item
                  NewText = SPACE$(255)
                  tTVItem.hItem = hNode
                  tTVItem.mask = %TVIF_HANDLE OR %TVIF_TEXT
                  tTVItem.pszText = STRPTR(NewText)
                  tTVItem.cchTextMax = 255
                  SendMessage(hTree, %TVM_GETITEM, BYVAL 0, BYVAL VARPTR(tTVItem))
      
                  s1 = "The text of the first visible node is:"+$CRLF+RTRIM$(REMOVE$(NewText, ANY CHR$(0)))+$CRLF
      
                  ' Get the handle of the selected item
                  hChildNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_CARET, 0)
      
                  ' Get the previous visible item
                  s = ""
                  hNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_PREVIOUSVISIBLE, hChildNode)
      
                  WHILE (hNode<>%NULL)
                    ' Get the text of the child node found
      
                    NewText = SPACE$(255)
      
                    tTVItem.hItem = hNode              ' Handle of node to get text of
                    tTVItem.mask  = %TVIF_TEXT         ' We only need the text
                    tTVItem.pszText = STRPTR(NewText)  ' String to put text in
                    tTVItem.cchTextMax = 255           ' Max string length
      
                    TreeView_GetItem(hTree, tTVItem)
      
                    s = s + RTRIM$(REMOVE$(NewText, ANY CHR$(0))) + $CRLF
      
                    ' Get the next sibling
                    hNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_PREVIOUSVISIBLE, hNode)
                  WEND
      
                  s1 = s1 + $CRLF + "The previous visible items are:"+$CRLF+s+$CRLF
      
                  ' Get the next siblings
                  s= ""
                  hNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_NEXTVISIBLE, hChildNode)
                  WHILE (hNode<>%NULL)
                    ' Get the text of the child node found
      
                    NewText = SPACE$(255)
      
                    tTVItem.hItem = hNode              ' Handle of node to get text of
                    tTVItem.mask  = %TVIF_TEXT         ' We only need the text
                    tTVItem.pszText = STRPTR(NewText)  ' String to put text in
                    tTVItem.cchTextMax = 255           ' Max string length
      
                    TreeView_GetItem(hTree, tTVItem)
      
                    s = s + RTRIM$(REMOVE$(NewText, ANY CHR$(0))) + $CRLF
      
                    ' Get the next sibling
                    hNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_NEXTVISIBLE, hNode)
                  WEND
      
                  s1 = s1 + $CRLF + "The next visible items are:"+$CRLF+s
                  ? s1
                END IF
      
      
              CASE %IDC_BUTTON13
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  ' Get the amount of indention of child nodes from parent nodes in pixels
      
                  i = SendMessage(hTree, %TVM_GETINDENT , 0, 0)
                  ? "The indention of child nodes from there parent is "+FORMAT$(i)+" pixels"
                END IF
      
              CASE %IDC_BUTTON14
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  ' Set the amount of idention in pixesl of child nodes from parent nodes
                  i = VAL(INPUTBOX$("Enter the amount of indention in pixels (THERE IS ERROR CHECKING!)"+_
                                    $CRLF+"SDK says any value less than the system minimum is ignored."+_
                                    $CRLF+"The system minimum can be found by enter -1 for the indention"+ _
                                    $CRLF+"and then getting the indention (There is a button for this)", _
                                    "Enter indention amount"))
      
                  SendMessage(hTree, %TVM_SETINDENT , i, 0)
                END IF
      
              CASE %IDC_BUTTON15
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  ' Set the Insert Mark. This is used to ask the user where
                  ' They would like a new node inserted. The wparam in SendMessage
                  ' says if the insert mark is show above or below the lparam hnode
      
                  ' Get the handle of the selected item(node)
                  hNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_CARET, 0)
      
                  ' Show the Insert Mark
                  SendMessage(hTree, %TVM_SETINSERTMARK, 0, hNode )
                END IF
      
              CASE %IDC_BUTTON16
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  ' Set the Insert Mark Color to %RED
                  SendMessage(hTree, %TVM_SETINSERTMARKCOLOR, 0, %RED)
                END IF
      
              CASE %IDC_BUTTON17
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  ' Get the text of the selected node
      
                  ' Get the handle of the selected node
                  hNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_CARET, 0)
      
                  ' Get the text of (hNode) the first visible node item
                  s = SPACE$(255)
                  tTVItem.hItem = hNode
                  tTVItem.mask = %TVIF_HANDLE OR %TVIF_TEXT
                  tTVItem.pszText = STRPTR(s)
                  tTVItem.cchTextMax = 255
                  SendMessage(hTree, %TVM_GETITEM, BYVAL 0, BYVAL VARPTR(tTVItem))
                  ? "The text of this node is "+s
                END IF
      
      
              CASE %IDC_BUTTON18
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  ' Get the handle of the selected node
                  hNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_CARET, 0)
      
                  ' Get the text of (hNode) the first visible node item
                  s = SPACE$(255)
                  tTVItem.hItem = hNode
                  tTVItem.mask = %TVIF_HANDLE OR %TVIF_TEXT
                  tTVItem.pszText = STRPTR(s)
                  tTVItem.cchTextMax = 255
                  SendMessage(hTree, %TVM_GETITEM, BYVAL 0, BYVAL VARPTR(tTVItem))
                  ? "The handle of this node is "+HEX$(hNode)+$CRLF+"The text of this node is "+s
                END IF
      
              CASE %IDC_BUTTON19
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  ' Delete all items from the treeview
                  SendMessage(hTree, %TVM_DELETEITEM, 0, %TVI_ROOT)
                END IF
      
              CASE %IDC_BUTTON20
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  ' End editing of a treeview node label/text
                  ? "See the notes for the %IDC_BUTTON2 and %TVN_ENDLABELEDIT message handlers"
                END IF
      
              CASE %IDC_BUTTON21
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  ' Get the handle of the root node
                  hNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_ROOT, 0)
      
                  ' Get the text of (hNode) the root node
                  s = SPACE$(255)
                  tTVItem.hItem = hNode
                  tTVItem.mask = %TVIF_HANDLE OR %TVIF_TEXT
                  tTVItem.pszText = STRPTR(s)
                  tTVItem.cchTextMax = 255
                  SendMessage(hTree, %TVM_GETITEM, BYVAL 0, BYVAL VARPTR(tTVItem))
                  ? "The handle of the root node is "+HEX$(hNode)+$CRLF+"The text of the root node is "+s
                END IF
      
              CASE %IDC_BUTTON22
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  ' Get the siblings of the selected node
      
                  ' Get the handle of the selected node
                  hChildNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_CARET, 0)
      
                  s = ""
                  s1= ""
      
                  ' Get the previous sibilings
                  hNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_PREVIOUS, hChildNode)
      
                  WHILE (hNode<>%NULL)
                    ' Get the text of the child node found
      
                    NewText = SPACE$(255)
      
                    tTVItem.hItem = hNode              ' Handle of node to get text of
                    tTVItem.mask  = %TVIF_TEXT         ' We only need the text
                    tTVItem.pszText = STRPTR(NewText)  ' String to put text in
                    tTVItem.cchTextMax = 255           ' Max string length
      
                    TreeView_GetItem(hTree, tTVItem)
      
                    s = s + RTRIM$(REMOVE$(NewText, ANY CHR$(0))) + $CRLF
      
                    ' Get the next sibling
                    hNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_PREVIOUS, hNode)
                  WEND
      
                  ' Get the next siblings
                  hNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_NEXT, hChildNode)
                  WHILE (hNode<>%NULL)
                    ' Get the text of the child node found
      
                    NewText = SPACE$(255)
      
                    tTVItem.hItem = hNode              ' Handle of node to get text of
                    tTVItem.mask  = %TVIF_TEXT         ' We only need the text
                    tTVItem.pszText = STRPTR(NewText)  ' String to put text in
                    tTVItem.cchTextMax = 255           ' Max string length
      
                    TreeView_GetItem(hTree, tTVItem)
      
                    s1 = s1 + RTRIM$(REMOVE$(NewText, ANY CHR$(0))) + $CRLF
      
                    ' Get the next sibling
                    hNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_NEXT, hNode)
                  WEND
      
                  IF (s = "" AND s1="") THEN s = "**This node has no siblings**":EXIT FUNCTION
      
                  s = "Previous Sibling Nodes:"+$CRLF+s+$CRLF+"Next Sibling Nodes:"+$CRLF+s1
                  ? s
                END IF
      
              CASE %IDC_BUTTON23
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  ' Insert a new item as the first sibling of the selected node
      
                  ' Get the handle of the selected item(node)
                  hNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_CARET, 0)
      
                  ' Get the parent of the selected node
                  hParent = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_PARENT, hNode)
      
                  tTVInsert.hParent      = hParent' It will have the same parent as the selected node
                  tTVInsert.hInsertAfter = %TVI_FIRST     ' Insert it as the first item
      
                  NewText = "New first item Node "+TIME$
      
                  tTVInsert.Item.Item.mask       = %TVIF_TEXT OR %TVIF_IMAGE OR %TVIF_SELECTEDIMAGE OR %TVIF_PARAM
                  tTVInsert.Item.Item.pszText    = STRPTR(NewText)
                  tTVInsert.Item.Item.cchTextMax = LEN(NewText)
                  tTVInsert.Item.Item.iImage     = 0
                  tTVInsert.Item.Item.iSelectedImage = 1
                  tTVInsert.Item.Item.lParam = RND(1, 10000)
      
                  SendMessage(hTree, %TVM_INSERTITEM, 0, BYVAL VARPTR(tTVInsert))
                END IF
      
              CASE %IDC_BUTTON24
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  ' Insert a new item as a sibling of the selected node in sorted order
      
                  ' Get the handle of the selected item(node)
                  hNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_CARET, 0)
      
                  ' Get the parent of the selected node
                  hParent = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_PARENT, hNode)
      
                  tTVInsert.hParent      = hParent' It will have the same parent as the selected node
                  tTVInsert.hInsertAfter = %TVI_SORT     ' Insert it in sorted order
      
                  NewText = "New sorted Node "+TIME$
      
                  tTVInsert.Item.Item.mask       = %TVIF_TEXT OR %TVIF_IMAGE OR %TVIF_SELECTEDIMAGE OR %TVIF_PARAM
                  tTVInsert.Item.Item.pszText    = STRPTR(NewText)
                  tTVInsert.Item.Item.cchTextMax = LEN(NewText)
                  tTVInsert.Item.Item.iImage     = 0
                  tTVInsert.Item.Item.iSelectedImage = 1
                  tTVInsert.Item.Item.lParam = RND(1, 10000)
      
                  SendMessage(hTree, %TVM_INSERTITEM, 0, BYVAL VARPTR(tTVInsert))
                END IF
      
              CASE %IDC_BUTTON25
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  ' Get the count of the number of items that be visible
                  i = SendMessage(hTree, %TVM_GETVISIBLECOUNT, 0, 0)
                  ? "The number of items that can be FULLY visible is "+FORMAT$(i)
                END IF
      
              CASE %IDC_BUTTON26
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  ' Insert a new child node as the first child of the selected node
      
                  ' Get the handle of the selected item(node)
                  hNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_CARET, 0)
      
                  ' Insert a new child node as the first child of the selected node
                  NewText = "Child First "+TIME$
                  tTVInsert.Item.Item.mask       = %TVIF_TEXT OR %TVIF_IMAGE OR %TVIF_SELECTEDIMAGE OR %TVIF_PARAM
                  tTVInsert.Item.Item.pszText    = STRPTR(NewText)
                  tTVInsert.Item.Item.cchTextMax = LEN(NewText)
                  tTVInsert.Item.Item.iImage     = 2
                  tTVInsert.Item.Item.iSelectedImage = 3
                  tTVInsert.Item.Item.lParam = RND(1, 10000)
                  tTVInsert.hParent = hNode
                  tTVInsert.hInsertAfter = %TVI_FIRST
      
                  SendMessage(hTree, %TVM_INSERTITEM, 0, BYVAL VARPTR(tTVInsert))
      
                  ' Make sure that the selected node (parent of the new child) has it's children member of it's TV_ITEM set
                  tTVItem.mask = %TVIF_CHILDREN OR %TVIF_HANDLE
                  tTVItem.hItem = hNode
                  tTVItem.cChildren = 1
      
                  SendMessage(hTree, %TVM_SETITEM, 0, BYVAL VARPTR(tTVItem))
                END IF
      
              CASE %IDC_BUTTON27
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  ' Insert a new child node of the selected parent after the specified node
                  ' In this case the specified node will be the first child of the selected node
      
                  ' Get the handle of the selected item(node)
                  hNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_CARET, 0)
      
                  ' Get the first child node of the selected node
                  hChildNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_CHILD, hNode)
      
                  ' Insert a new child node as the first child of the selected node
                  NewText = "Child First "+TIME$
                  tTVInsert.Item.Item.mask       = %TVIF_TEXT OR %TVIF_IMAGE OR %TVIF_SELECTEDIMAGE OR %TVIF_PARAM
                  tTVInsert.Item.Item.pszText    = STRPTR(NewText)
                  tTVInsert.Item.Item.cchTextMax = LEN(NewText)
                  tTVInsert.Item.Item.iImage     = 2
                  tTVInsert.Item.Item.iSelectedImage = 3
                  tTVInsert.Item.Item.lParam = RND(1, 10000)
      
                  ' If there is no child node to insert this new node after then
                  ' just make it the first item in the node
                  IF hChildNode<>0 THEN
                    tTVInsert.hInsertAfter = hChildNode
                  ELSE
                    tTVInsert.hInsertAfter = %TVI_FIRST
                  END IF
      
                  tTVInsert.hParent = hNode
      
                  SendMessage(hTree, %TVM_INSERTITEM, 0, BYVAL VARPTR(tTVInsert))
      
                  ' Make sure that the selected node (parent of the new child) has it's children member of it's TV_ITEM set
                  tTVItem.mask = %TVIF_CHILDREN OR %TVIF_HANDLE
                  tTVItem.hItem = hNode
                  tTVItem.cChildren = 1
      
                  SendMessage(hTree, %TVM_SETITEM, 0, BYVAL VARPTR(tTVItem))
                END IF
      
              CASE %IDC_BUTTON28
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  ' Insert a new item as the last sibling of the selected node
      
                  ' Get the handle of the selected item(node)
                  hNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_CARET, 0)
      
                  ' Get the parent of the selected node
                  hParent = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_PARENT, hNode)
      
                  tTVInsert.hParent      = hParent' It will have the same parent as the selected node
                  tTVInsert.hInsertAfter = %TVI_LAST     ' Insert it as the last item
      
                  NewText = "New last item Node "+TIME$
      
                  tTVInsert.Item.Item.mask       = %TVIF_TEXT OR %TVIF_IMAGE OR %TVIF_SELECTEDIMAGE OR %TVIF_PARAM
                  tTVInsert.Item.Item.pszText    = STRPTR(NewText)
                  tTVInsert.Item.Item.cchTextMax = LEN(NewText)
                  tTVInsert.Item.Item.iImage     = 0
                  tTVInsert.Item.Item.iSelectedImage = 1
                  tTVInsert.Item.Item.lParam = RND(1, 10000)
      
                  SendMessage(hTree, %TVM_INSERTITEM, 0, BYVAL VARPTR(tTVInsert))
                END IF
      
      
              CASE %IDC_BUTTON29
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  ' Insert a new child node of the selected parent after the specified as the last child node
      
                  ' Get the handle of the selected item(node)
                  hNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_CARET, 0)
      
                  ' Insert a new child node as the first child of the selected node
                  NewText = "Child Last "+TIME$
                  tTVInsert.Item.Item.mask       = %TVIF_TEXT OR %TVIF_IMAGE OR %TVIF_SELECTEDIMAGE OR %TVIF_PARAM
                  tTVInsert.Item.Item.pszText    = STRPTR(NewText)
                  tTVInsert.Item.Item.cchTextMax = LEN(NewText)
                  tTVInsert.Item.Item.iImage     = 2
                  tTVInsert.Item.Item.iSelectedImage = 3
                  tTVInsert.Item.Item.lParam = RND(1, 10000)
      
                  tTVInsert.hInsertAfter = %TVI_LAST
                  tTVInsert.hParent = hNode
      
                  SendMessage(hTree, %TVM_INSERTITEM, 0, BYVAL VARPTR(tTVInsert))
      
                  ' Make sure that the selected node (parent of the new child) has it's children member of it's TV_ITEM set
                  tTVItem.mask = %TVIF_CHILDREN OR %TVIF_HANDLE
                  tTVItem.hItem = hNode
                  tTVItem.cChildren = 1
      
                  SendMessage(hTree, %TVM_SETITEM, 0, BYVAL VARPTR(tTVItem))
                END IF
      
              CASE %IDC_BUTTON30
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  ' Set the current selected node to toggle bold text on and off
      
                  ' Get the handle of the selected item(node)
                  hNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_CARET, 0)
      
                  ' Get the current bold state of this item
                  tTVItem.mask = %TVIF_HANDLE OR %TVIF_STATE
                  tTVItem.statemask = %TVIS_BOLD
                  tTVItem.hItem = hNode
                  SendMessage(hTree, %TVM_GETITEM, 0 , BYVAL VARPTR(tTVItem))
      
                  IF (tTvItem.State AND %TVIS_BOLD) = %TVIS_BOLD THEN
                    ' Set the item text to not bold
                    tTVItem.mask = %TVIF_HANDLE OR %TVIF_STATE
                    tTVItem.statemask = %TVIS_BOLD
                    tTVItem.state = tTVItem.state AND NOT %TVIS_BOLD
                    tTVItem.hItem = hNode
                    sendMessage(hTree, %TVM_SETITEM, 0, BYVAL VARPTR(tTVItem))
                  ELSE
                    ' Set the item text to bold
                    tTVItem.mask = %TVIF_HANDLE OR %TVIF_STATE
                    tTVItem.statemask = %TVIS_BOLD
                    tTVItem.state = %TVIS_BOLD
                    tTVItem.hItem = hNode
                    sendMessage(hTree, %TVM_SETITEM, 0, BYVAL VARPTR(tTVItem))
                  END IF
                END IF
      
              CASE %IDC_BUTTON31
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  ' Get the bold state of the currently selected node
      
                  ' Get the handle of the selected item(node)
                  hNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_CARET, 0)
      
                  ' Get the current bold state of this item
                  tTVItem.mask = %TVIF_HANDLE OR %TVIF_STATE
                  tTVItem.statemask = %TVIS_BOLD
                  tTVItem.hItem = hNode
                  SendMessage(hTree, %TVM_GETITEM, 0 , BYVAL VARPTR(tTVItem))
      
                  IF (tTvItem.State AND %TVIS_BOLD) = %TVIS_BOLD THEN
                    ? "This node's text is bold"
                  ELSE
                    ? "This node's text is not bold"
                  END IF
      
                END IF
      
              CASE %IDC_BUTTON32
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  ' Is the selected node expanded
      
                  ' Get the handle of the selected item(node)
                  hNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_CARET, 0)
      
                  ' Get the current bold state of this item
                  tTVItem.mask = %TVIF_HANDLE OR %TVIF_STATE
                  tTVItem.statemask = %TVIS_EXPANDED
                  tTVItem.hItem = hNode
                  SendMessage(hTree, %TVM_GETITEM, 0 , BYVAL VARPTR(tTVItem))
      
                  IF (tTvItem.State AND %TVIS_EXPANDED) = %TVIS_EXPANDED THEN
                    ? "This node is expanded"
                  ELSE
                    ? "This node is not expanded"
                  END IF
                END IF
      
              CASE %IDC_BUTTON33
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  ' Set the current line color
                  SendMessage(hTree, %TVM_SETLINECOLOR, 0, %RED)
                END IF
      
              CASE %IDC_BUTTON34
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  ' Get the current line color
                  i = SendMessage(hTree, %TVM_GETLINECOLOR, 0, 0)
      
                  ? "The line color is "+HEX$(i)
                END IF
              CASE %IDC_BUTTON35
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  ' Set the current text color
                  SendMessage(hTree, %TVM_SETTEXTCOLOR, 0, %MAGENTA)
                END IF
      
              CASE %IDC_BUTTON36
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  ' Get the current text color
                  i = SendMessage(hTree, %TVM_GETTEXTCOLOR, 0, 0)
      
                  ? "The text color is "+HEX$(i)
                END IF
      
              CASE %IDC_BUTTON37
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  ' Select an node in the treeview
                  ' In this example we will select the child of the selected node
                  ' if there is no child then we will select the parent
                  ' If there is no parent then we will select the next sibling
                  ' If there is no sibling then just select the root
      
                  ' Get the Selected node
                  hNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_CARET, 0)
      
                  ' Get the child of the Selected node
                  hChildNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_CHILD, hNode)
      
                  ' If no child node then get the parent
                  IF hChildNode=0 THEN
                    hChildNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_PARENT, hNode)
                  END IF
      
                  ' If no parent node then get the sibling
                  IF hChildNode=0 THEN
                    hChildNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_NEXT, hNode)
                  END IF
      
                  ' If no siblings then get the root node
                  IF hChildNode=0 THEN
                    hChildNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_ROOT, 0)
                  END IF
      
                  SendMessage(hTree, %TVM_SELECTITEM, %TVGN_CARET, hChildNode)
                END IF
      
      
              CASE %IDC_BUTTON38
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  ' Ensure that a node in the treeview
                  ' In this example we will ensure the child of the selected node is visible
                  ' if there is no child then we will ensure the parent is visible
                  ' If there is no parent then we will ensure the next sibling is visible
                  ' If there is no sibling then just ensure the root is visible
      
                  ' Get the Selected node
                  hNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_CARET, 0)
      
                  ' Get the child of the Selected node
                  hChildNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_CHILD, hNode)
      
                  ' If no child node then get the parent
                  IF hChildNode=0 THEN
                    hChildNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_PARENT, hNode)
                  END IF
      
                  ' If no parent node then get the sibling
                  IF hChildNode=0 THEN
                    hChildNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_NEXT, hNode)
                  END IF
      
                  ' If no siblings then get the root node
                  IF hChildNode=0 THEN
                    hChildNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_ROOT, 0)
                  END IF
      
                  SendMessage(hTree, %TVM_ENSUREVISIBLE, 0, hChildNode)
                END IF
      
              CASE %IDC_BUTTON39
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  ' Set the item height for all items in the treeview
                  ' It is possible using the XP Look and Feel Resource fix that
                  ' uses common controls version 6.0 to set each items height idividually
      
                  i = VAL(INPUTBOX$("Enter the height of items in pixels"+$CRLF+_
                                    "There is NO error checking!"+$CRLF+_
                                    "-1 is the default height", _
                                    "Item Height"))
      
                  SendMessage(hTree, %TVM_SETITEMHEIGHT, i, 0)
                END IF
      
              CASE %IDC_BUTTON40
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  ' Retreive the item height
                  i = SendMessage(hTree, %TVM_GETITEMHEIGHT, 0, 0)
                  ? "The Item Height is "+FORMAT$(i)+" pixels"
                END IF
      
              CASE %IDC_BUTTON41
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  ' Sort the children of the selected node
      
                  ' Get the Selected node
                  hNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_CARET, 0)
      
                  SendMessage(hTree, %TVM_SORTCHILDREN, 0, hNode)
                END IF
      
              CASE %IDC_BUTTON42
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  ' Sort the children of the selected sub using a user defined sorting callback
      
                  ' Get the Selected node
                  hNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_CARET, 0)
      
                  tTVSortCB.hParent = hNode
                  tTVSortCB.lpfnCompare = CODEPTR(CompareFunc)
                  tTVSortCB.lParam = %null ' user defined data passed to the compare function
      
                  SendMessage(hTree, %TVM_SORTCHILDRENCB, 0, BYVAL VARPTR(tTVSortCB))
                END IF
      
      
              CASE %IDC_BUTTON43
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  ' Get the LParam of the selected node
      
                  ' Get the Selected node
                  hNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_CARET, 0)
      
                  tTVItem.mask = %TVIF_HANDLE OR %TVIF_PARAM
                  tTVItem.hItem = hNode
      
                  SendMessage(hTree, %TVM_GETITEM, 0, BYVAL VARPTR(tTVItem))
      
                  ? "The LParam for this item is"+STR$(tTVItem.lParam)
                END IF
      
              CASE %IDC_BUTTON44
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  i = VAL(INPUTBOX$("Please enter a lParam value", "Get lParam"))
      
                  ' Get the Selected node
                  hNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_CARET, 0)
      
                  tTVItem.mask = %TVIF_HANDLE OR %TVIF_PARAM
                  tTVItem.hItem = hNode
                  tTVItem.lParam = i
      
                  SendMessage(hTree, %TVM_SETITEM, 0, BYVAL VARPTR(tTVItem))
                END IF
      
              CASE %IDC_BUTTON45
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  ' Insert a new child node in alphabetical order based on the selected parent node
      
                  ' Get the handle of the selected item(node)
                  hNode = SendMessage(hTree, %TVM_GETNEXTITEM, %TVGN_CARET, 0)
      
                  ' Insert a new child node as the first child of the selected node
                  NewText = "Child Sort "+TIME$
                  tTVInsert.Item.Item.mask       = %TVIF_TEXT OR %TVIF_IMAGE OR %TVIF_SELECTEDIMAGE OR %TVIF_PARAM
                  tTVInsert.Item.Item.pszText    = STRPTR(NewText)
                  tTVInsert.Item.Item.cchTextMax = LEN(NewText)
                  tTVInsert.Item.Item.iImage     = 2
                  tTVInsert.Item.Item.iSelectedImage = 3
                  tTVInsert.Item.Item.lParam = RND(1, 10000)
                  tTVInsert.hParent = hNode
                  tTVInsert.hInsertAfter = %TVI_SORT
      
                  SendMessage(hTree, %TVM_INSERTITEM, 0, BYVAL VARPTR(tTVInsert))
      
                  ' Make sure that the selected node (parent of the new child) has it's children member of it's TV_ITEM set
                  tTVItem.mask = %TVIF_CHILDREN OR %TVIF_HANDLE
                  tTVItem.hItem = hNode
                  tTVItem.cChildren = 1
      
                  SendMessage(hTree, %TVM_SETITEM, 0, BYVAL VARPTR(tTVItem))
                END IF
      
            END SELECT
      
          CASE %WM_NOTIFY
            TVnm = CBLPARAM
      
            SELECT CASE @TVnm.hdr.code
      
              CASE %NM_CLICK
                IF @TVnm.hdr.idFrom = %ID_TVIEW THEN
                  ' This will ensure that when the user either clicks the checkbox or the
                  ' buttons (+/-) the item/node will be selected. You get a strange flashing
                  ' experience if you do not do this, comment out this code and then use a
                  ' checkbox or the buttons and see what occurs. (found this code on MSDN)
      
                  dwPos = GetMessagePos          ' Get the mouse position
                  TVht.pt.x = LO(WORD, dwPos)    ' Store the mouse x pos in the hittest udt
                  tvht.pt.y = HI(WORD, dwPos)    ' Store the mouse y pos in the hittest udt
                  MapWindowPoints(%HWND_DESKTOP, @TVnm.hdr.hwndFrom, TVht.pt, 1)
      
                  ' Get the TreeView item/node returned in the hittest udt member of hItem
                  SendMessage(hTree, %TVM_HITTEST, 0, BYVAL VARPTR(TVht))
      
                  ' Select the TreeView item/node that was clicked on (returned above)
                  'TreeView_SelectItem(hTree, TVHt.hItem)
                  SendMessage(hTree, %TVM_SELECTITEM, %TVGN_CARET, TVht.hItem)
                END IF
      
              CASE %TVN_BEGINLABELEDIT
                ' Get the handle of the TreeView edit control
                hTVEdit = Treeview_GetEditControl(hTree)
      
                ' Get the text in the edit control (original text)
                CONTROL GET TEXT hTree, GetDlgCtrlID(hTVEdit) TO oldtext
      
                ' Limit the edit control to 25 characters
                CONTROL SEND hTree, GetDlgCtrlID(hTVEdit), %EM_LIMITTEXT, 25, 0
      
              CASE %TVN_ENDLABELEDIT
                ' Return 1 to use the new text or 0 to use the original text
                ' This is useful when you subclass the TreeView edit box and
                ' catch the ESCape key to cancel the edit, you would then call
                ' TreeView_EndEditLabelNow which ends the editing and with a flag
                ' varaible set to 0 and then set FUNCTION = flagVariable or something
                ' like that.
      
                ' Get the handle of the TreeView edit control
                hTVEdit = Treeview_GetEditControl(hTree)
      
                ' Get the text in the edit control (original text)
                CONTROL GET TEXT hTree, GetDlgCtrlID(hTVEdit) TO NewText
      
                ? "You changed the text from "+OldText+" to "+NewText
      
                FUNCTION = 1
      
            END SELECT
        END SELECT
      
      END FUNCTION
      
      FUNCTION CompareFunc(BYVAL lParam1 AS LONG, BYVAL lParam2 AS LONG, BYVAL lParamSort AS LONG) AS LONG
        ' lParam1 and lParam2 are the lParam members of the TV_ITEM UDT
        ' I guess if you want a search based on the pszText member instead you have two choices
        ' One would be to store the handle to the node in the lParam then you could get the text this way
        ' Or you could iterate through each node until you find the node with this lParam
      
        IF lParam1>lParam2 THEN
          FUNCTION = 1
        ELSEIF lParam1<lParam2 THEN
          FUNCTION = -1
        ELSE
          FUNCTION = 0
        END IF
      
      END FUNCTION
      
      
      FUNCTION BuildImageList AS DWORD
        LOCAL hbmp AS DWORD
        LOCAL hIL  AS DWORD
      
        hIL = ImageList_Create(32, 32, %ILC_COLOR32, 2, 1)
      
        hBmp = LoadImage(GetModuleHandle(BYVAL %NULL), BYVAL 100, %IMAGE_ICON, 0, 0, _
                             %LR_DEFAULTSIZE OR %LR_COPYFROMRESOURCE OR %LR_LOADTRANSPARENT )
      
        ImageList_AddIcon(hIL, hBmp)
      
        hBmp = LoadImage(GetModuleHandle(BYVAL %NULL), BYVAL 101, %IMAGE_ICON, 0, 0, _
                             %LR_DEFAULTSIZE OR %LR_COPYFROMRESOURCE OR %LR_LOADTRANSPARENT OR %LR_LOADMAP3DCOLORS  )
      
        ImageList_AddIcon(hIL, hBmp)
      
        hBmp = LoadImage(GetModuleHandle(BYVAL %NULL), BYVAL 102, %IMAGE_ICON, 0, 0, _
                             %LR_DEFAULTSIZE OR %LR_COPYFROMRESOURCE OR %LR_LOADTRANSPARENT OR %LR_LOADMAP3DCOLORS  )
      
        ImageList_AddIcon(hIL, hBmp)
      
        hBmp = LoadImage(GetModuleHandle(BYVAL %NULL), BYVAL 103, %IMAGE_ICON, 0, 0, _
                             %LR_DEFAULTSIZE OR %LR_COPYFROMRESOURCE OR %LR_LOADTRANSPARENT OR %LR_LOADMAP3DCOLORS  )
      
        ImageList_AddIcon(hIL, hBmp)
      
        hBmp = LoadImage(GetModuleHandle(BYVAL %NULL), BYVAL 104, %IMAGE_ICON, 0, 0, _
                             %LR_DEFAULTSIZE OR %LR_COPYFROMRESOURCE OR %LR_LOADTRANSPARENT OR %LR_LOADMAP3DCOLORS  )
      
        ImageList_AddIcon(hIL, hBmp)
      
        hBmp = LoadImage(GetModuleHandle(BYVAL %NULL), BYVAL 105, %IMAGE_ICON, 0, 0, _
                             %LR_DEFAULTSIZE OR %LR_COPYFROMRESOURCE OR %LR_LOADTRANSPARENT OR %LR_LOADMAP3DCOLORS  )
      
        ImageList_AddIcon(hIL, hBmp)
      
        hBmp = LoadImage(GetModuleHandle(BYVAL %NULL), BYVAL 106, %IMAGE_ICON, 0, 0, _
                             %LR_DEFAULTSIZE OR %LR_COPYFROMRESOURCE OR %LR_LOADTRANSPARENT OR %LR_LOADMAP3DCOLORS  )
      
        ImageList_AddIcon(hIL, hBmp)
      
        hBmp = LoadImage(GetModuleHandle(BYVAL %NULL), BYVAL 107, %IMAGE_ICON, 0, 0, _
                             %LR_DEFAULTSIZE OR %LR_COPYFROMRESOURCE OR %LR_LOADTRANSPARENT OR %LR_LOADMAP3DCOLORS  )
      
        ImageList_AddIcon(hIL, hBmp)
      
        FUNCTION = hIL
      
      END FUNCTION
      
      SUB GetTVStyles
        LOCAL hDlg  AS DWORD
      
        DIALOG NEW 0, "Options", 64, 42, 494, 250, TO hDlg
        CONTROL ADD CHECKBOX, hDlg, %ID_HASLINES, "%TVS_HASLINES", 15, 30, 100, 10
        CONTROL ADD CHECKBOX, hDlg, %ID_HASLINESATROOT, "%TVS_LINESATROOT (%TVS_HASLINES MUST BE SELECTED)", 15, 40, 280, 10
        CONTROL ADD CHECKBOX, hDlg, %ID_HASBUTTONS, "%TVS_HASBUTTONS (%TVS_LINESATROOT MUST BE SELECTED)", 15, 50, 255, 10
        CONTROL ADD CHECKBOX, hDlg, %ID_HASSHOWSELALWAYS, "%TVS_SHOWSELALWAYS", 15, 60, 110, 10
        CONTROL ADD CHECKBOX, hDlg, %ID_HASEDITLABELS, "%TVS_EDITLABELS", 15, 70, 100, 10
        CONTROL ADD CHECKBOX, hDlg, %ID_HASCHECKBOXES, "%TVS_CHECKBOXES", 15, 80, 100, 10
        CONTROL ADD FRAME,    hDlg, %IDC_FRAME1, "Styles", 5, 15, 305, 170
        CONTROL ADD LABEL,    hDlg, %IDC_LABEL1, "Select the styles you want the TreeView created with", 5, 5, 175, 10
        CONTROL ADD BUTTON,   hDlg, %IDOK, "DONE", 439, 230, 50, 15
        DIALOG  SEND          hDlg, %DM_SETDEFID, %IDOK, 0
        CONTROL ADD CHECKBOX, hDlg, %ID_HASFULLROWSELECT, "%TVS_FULLROWSELECT (CANNOT BE USED WITH  %TVS_HASLINES)", 15, 90, 270, 10
        CONTROL ADD CHECKBOX, hDlg, %ID_HASINFOTIP, "%TVS_INFOTIP", 15, 100, 100, 10
        CONTROL ADD CHECKBOX, hDlg, %ID_HASNONEVENHEIGHT, "%TVS_NONEVENHEIGHT", 15, 110, 100, 10
        CONTROL ADD CHECKBOX, hDlg, %ID_HASNOTOOLTIPS, "%TVS_NOTOOLTIPS", 15, 120, 100, 10
        CONTROL ADD CHECKBOX, hDlg, %ID_HASRTLREADING, "%TVS_RTLREADING", 15, 130, 100, 10
        CONTROL ADD CHECKBOX, hDlg, %ID_HASSINGLEEXPAND, "%TVS_SINGLEEXPAND", 15, 140, 100, 10
        CONTROL ADD CHECKBOX, hDlg, %ID_HASTRACKSELECT, "%TVS_TRACKSELECT", 15, 150, 100, 10
        CONTROL ADD CHECKBOX, hDlg, %ID_HASNOHSCROLL, "%TVS_NOHSCROLL ", 15, 160, 100, 10
        CONTROL ADD CHECKBOX, hDlg, %ID_HASNOSCROLL, "%TVS_NOSCROLL ", 15, 170, 100, 10
        CONTROL ADD CHECKBOX, hDlg, %ID_HASAUTOSCROLL, "%TVS_EX_AUTOHSCROLL", 325, 30, 110, 10
        CONTROL ADD CHECKBOX, hDlg, %ID_HASDIMMEDCHECKBOXES, "%TVS_EX_DIMMEDCHECKBOXES", 325, 40, 130, 10
        CONTROL ADD CHECKBOX, hDlg, %ID_HASDOUBLEBUFFER, "%TVS_EX_DOUBLEBUFFER ", 325, 50, 110, 10
        CONTROL ADD CHECKBOX, hDlg, %ID_HASDRAWIMAGESYNC, "%TVS_EX_DRAWIMAGEASYNC ", 325, 60, 130, 10
        CONTROL ADD CHECKBOX, hDlg, %ID_HASEXCLUSIONCHECKBOXES, "%TVS_EX_EXCLUSIONCHECKBOXES", 325, 70, 150, 10
        CONTROL ADD FRAME,    hDlg, %IDC_FRAME2, "Extended Styles", 315, 16, 175, 170
        CONTROL ADD CHECKBOX, hDlg, %ID_HASFADEINOUTEXPANDOS, "%TVS_EX_FADEINOUTEXPANDOS ", 325, 80, 145, 10
        CONTROL ADD CHECKBOX, hDlg, %ID_HASNOINDENTSTATE, "%TVS_EX_NOINDENTSTATE", 325, 90, 145, 10
        CONTROL ADD CHECKBOX, hDlg, %ID_HASPARTIALCHECKBOXES, "%TVS_EX_PARTIALCHECKBOXES ", 325, 100, 155, 10
        CONTROL ADD CHECKBOX, hDlg, %ID_HASRICHTOOLTIP, "%TTVS_EX_RICHTOOLTIP ", 325, 110, 100, 10
        CONTROL ADD LABEL,    hDlg, -1, "The Extended TreeView Styles are for Windows Vista only. The older SDK Help files make no mention of " + _
          "these and testing shows they do not work on XP using version 6 of the common controls. I found several mentions for most of these Extended " + _
          "Styles that they are for Vista only. Also they must be set after the TreeView is created by sending a TVM_SETEXTENDEDSTYLE Message and MSDN " + _
          "says this message is for Vista only. ", 5, 190, 485, 35, %WS_CHILD OR %WS_VISIBLE OR %WS_BORDER OR %SS_LEFT, %WS_EX_STATICEDGE OR %WS_EX_LEFT _
          OR %WS_EX_LTRREADING
      
        CONTROL SET CHECK hdlg, %ID_HASLINES, 1
        CONTROL SET CHECK hdlg, %ID_HASLINESATROOT, 1
        CONTROL SET CHECK hdlg, %ID_HASSHOWSELALWAYS, 1
        CONTROL SET CHECK hdlg, %ID_HASEDITLABELS, 1
        CONTROL SET CHECK hdlg, %ID_HASCHECKBOXES, 1
        CONTROL SET CHECK hdlg, %ID_HASBUTTONS, 1
      
        DIALOG SHOW MODAL hDlg, CALL StylesDlgProc
      END SUB
      
      CALLBACK FUNCTION StylesDlgProc
        LOCAL i AS LONG
      
        SELECT CASE AS LONG CBMSG
      
          CASE %WM_COMMAND
            ' Process control notifications
            SELECT CASE AS LONG CBCTL
              CASE %IDOK
                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  CONTROL GET CHECK CBHNDL, %ID_HASLINES TO i
                  IF i THEN TVStyles = %TVS_HASLINES
      
                  CONTROL GET CHECK CBHNDL, %ID_HASLINESATROOT TO i
                  IF i THEN TVStyles = TVStyles OR %TVS_LINESATROOT
      
                  CONTROL GET CHECK CBHNDL, %ID_HASBUTTONS TO i
                  IF i THEN TVStyles = TVStyles OR %TVS_HASBUTTONS
      
                  CONTROL GET CHECK CBHNDL, %ID_HASSHOWSELALWAYS TO i
                  IF i THEN TVStyles = TVStyles OR %TVS_SHOWSELALWAYS
      
                  CONTROL GET CHECK CBHNDL, %ID_HASEDITLABELS TO i
                  IF i THEN TVStyles = TVStyles OR %TVS_EDITLABELS
      
                  CONTROL GET CHECK CBHNDL, %ID_HASCHECKBOXES TO i
                  IF i THEN TVStyles = TVStyles OR %TVS_CHECKBOXES
      
                  CONTROL GET CHECK CBHNDL, %ID_HASFULLROWSELECT TO i
                  IF i THEN TVStyles = TVStyles OR %TVS_FULLROWSELECT
                  DIALOG END CBHNDL, TVStyles
                END IF
      
            END SELECT
        END SELECT
      END FUNCTION
      Here is the RC file. Use your own icons...
      Code:
      #include "resource.h"
      
      #define IDI_DIR1CLOSED   100
      #define IDI_DIR1OPEN     101
      #define IDI_DIR2CLOSED   102
      #define IDI_DIR2OPEN   103
      #define IDI_CDDIS   104
      #define IDI_CDEND  105
      #define IDI_DIR3CLOSE  106
      #define IDI_DIR3OPEN   107
      
      
      
      IDI_DIR1CLOSED    ICON    DISCARDABLE   "Dirocty1.ico"
      IDI_DIR1OPEN      ICON    DISCARDABLE   "DirOpen.ico"
      IDI_DIR2CLOSED    ICON    DISCARDABLE   "RedDirocty.ico"
      IDI_DIR2OPEN      ICON    DISCARDABLE   "RedDirOpen.ico"
      IDI_CDDIS         ICON    DISCARDABLE   "CdDrive.ico"
      IDI_CDEND         ICON    DISCARDABLE   "CdBurn.ico"
      IDI_DIR3CLOSE     ICON    DISCARDABLE   "YellowDirOpen.ico"
      IDI_DIR3OPEN      ICON    DISCARDABLE   "YellowDirocty.ico"
      
      
      1 24 "xptheme.xml"
      Sincerely,

      Steve Rossell
      PowerBASIC Staff

      Comment


      • #4
        Thanks Ian & Steve for the above, which has been useful, though I have not yet solved my initial problems.



        Funny thing, what put me off looking at multiple selections was finding something very like the disclaimer in the eg which Steve posted above:

        ' Not really sure why this works but it does
        ' MSDN says that that the return value is a unsigned int but then it says
        ' it can return a -1.
        ' I found the code below on several sites but no one explains why it works
        '
        ' Found this by accident in the Win32 SDK:
        ' The INDEXTOSTATEIMAGEMASK macro prepares the index of a state image so that a tree-view
        ' control or list-view control can use the index to retrieve the state image for an item.
        '
        ' This makes sense that it converts the imagemask to an imagelist index - the checkbox
        ' as actuall two images one checked and one unchecked.
        Now if I had found that I would have said to myself "fools rush in..." but coming from Steve it looks more like leadership. Who wrote that code BTW Steve? no attribution or copyright/disclaimer.

        Slightly off my original message, but here's a scrap of code (as opposed to a compileable example) which will call a function for each checked item in a listview. The Walkies function is what does it, the Our_TV_itemProc is an example of a called function, and the last line is an example of how to call walkies. All my own work, so treat with caution!
        Code:
        '------------------------------------------------------------------------------
        ' function prototype for walkies "onHit" fn
        ' first param is treeview window handle
        ' second param is pointer to TV_ITEM
        DECLARE FUNCTION TVfnPrototype  ( hTVWnd AS DWORD, BYVAL pTV AS TV_ITEM PTR) AS LONG
        '------------------------------------------------------------------------------
        FUNCTION Our_TVITEM_proc ( hTVWnd AS DWORD, BYVAL pTV AS TV_ITEM PTR) AS LONG
            LOCAL sz AS ASCIIZ*256
            LOCAL TreeItem AS TV_ITEM
            LOCAL pTVITEM AS TV_ITEM PTR
        
            TreeItem = @pTV
            pTVITEM = VARPTR(TreeItem)
            TreeItem.mask = %TVIF_TEXT OR %TVIF_STATE OR %TVIF_HANDLE OR %TVIF_IMAGE
            TreeItem.stateMask = %TVIS_STATEIMAGEMASK
            TreeItem.cchTextMax = SIZEOF(sz)
            TreeItem.psztext    = VARPTR(sz)
            sendmessage hTVWnd, %TVM_GETITEM, 0, pTVITEM ' get item
            ' this line sends the TV item name to a listbox
            sendmessage geditWnd, %LB_ADDSTRING, 0, VARPTR(sz) ' send it on, prefixed by parent id
        END FUNCTION
        '------------------------------------------------------------------------------
        ' walk tree, execute OnHitfn when a checked item is encountered
        ' params are treeview control window handle,
        '            OnHitFn address
        '            TV item handle
        '            parent identifier (text of parent TV item)
        '
        FUNCTION walkies ( hTVWnd AS DWORD, OnHitfn AS DWORD, hTVItem AS DWORD, BYVAL pszParent AS ASCIZ PTR  ) AS LONG
            LOCAL sz AS ASCIZ * 256
            LOCAL hti AS tv_item PTR
            LOCAL treeItem AS TV_ITEM
            LOCAL pTVITEM AS tv_item PTR
        '    local lCountofItems as long
            LOCAL i AS LONG
            LOCAL dwOnHitFn AS DWORD
            
            TreeItem.HItem = hTVItem
            pTVITEM = VARPTR(TreeItem)
            WHILE TreeItem.HItem <> %NULL
                TreeItem.mask = %TVIF_STATE OR %TVIF_HANDLE '%TVIF_TEXT or %TVIF_STATE or %TVIF_HANDLE OR %TVIF_IMAGE
                TreeItem.stateMask = %TVIS_STATEIMAGEMASK
                sendmessage hTVWnd, %TVM_GETITEM, 0, pTVITEM ' get item
                ' is it checked?
                i = TreeItem.state
                SHIFT RIGHT i, 12
                IF i = 2 THEN
                    IF @pszParent <> "" THEN sz = @pszParent + "." + sz
                    CALL DWORD OnHitFn USING TVfnPrototype (hTVWnd, pTVITEM)
                    CALL walkies(hTVWnd, OnHitFn, TreeView_GetChild(hTVwnd, TreeItem.hitem), VARPTR(sz))
                END IF
                TreeItem.HItem = Treeview_GetNextSibling(hTVWnd, TreeItem.hItem)
            WEND
        END FUNCTION
        '-----------------------------------------------------------------------
        ' example of how walkies might be called, given the TV window and the name of the function to call when a checked item is found.
        
             walkies ( hTVWnd, CODEPTR(Our_TVITEM_proc), TreeView_GetRoot( hTVWnd), BYVAL %null)

        Comment


        • #5
          Now if I had found that I would have said to myself "fools rush in..." but coming from Steve it looks more like leadership. Who wrote that code BTW Steve? no attribution or copyright/disclaimer.
          I wrote this code above and I am not saying that it's right and was just trying to make and example of everything a treeview can do. As you can tell from my notes, I was not really sure about this when I wrote the code. I used this as a learning experience to understand better all the routines that exist for a treeview. Use this code as starting point - I am certainly not saying that everything I did in this code is correct.
          Sincerely,

          Steve Rossell
          PowerBASIC Staff

          Comment


          • #6
            Thanks for the work, Steve.

            regards, Ian
            :) IRC :)

            Comment


            • #7
              Originally posted by Steve Rossell View Post
              I wrote this code above...
              I'm very glad that you did, many thanks for posting it.

              Do you have any other topics lined up for this sort of treatment?

              BTW I put my tree walking code up on the Source Code Forum here
              Last edited by Chris Holbrook; 15 Feb 2008, 04:37 PM. Reason: link to source code added

              Comment


              • #8
                >Do you have any other topics lined up for this sort of treatment?

                One of the Petzold programs (which I know have been converted to PB and I'm pretty sure are here "somewhere") is called "gadgets" and uses one of just about every possible control.
                Michael Mattias
                Tal Systems (retired)
                Port Washington WI USA
                [email protected]
                http://www.talsystems.com

                Comment


                • #9
                  Just changed the code on the Source Code Forum to remove spurios #INCLUDE statements, no non-standard includes are required to run this code under PBWin 8.04. It's here

                  Comment


                  • #10
                    How to change the icon in a treeview node

                    <deleted>
                    Attached Files
                    Last edited by Gary Beene; 27 Apr 2009, 02:32 PM.

                    Comment

                    Working...
                    X