Announcement

Collapse

Forum Guidelines

This forum is for finished source code that is working properly. If you have questions about this or any other source code, please post it in one of the Discussion Forums, not here.
See more
See less

TreeView walking made easy

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

    TreeView walking made easy

    Code:
    ' TREEVIEW WALKER
    ' by Chris Holbrook 15-Feb-2008 public domain
    ' Program to demonstrate a reuseable approach to getting checked items
    ' from a TreeView with checkboxes. Actually it retrieves
    ' items whose parents, etc right back to the TreeView root
    ' are checked, in other words items with checked paths.
    '
    ' It uses a very simple generic recursive function to walk the tree
    ' This function should work with any TreeView. In turn it calls
    ' another, "user-written" function do do the actual processing of the
    ' selected TreeView item, passing to it a TV_ITEM pointer and the path
    ' of the checked item. In this case the function just adds the path to
    ' a listbox control.
    '
    ' There is also a sub to check the checked item's parent, grandparent, etc etc
    '
    ' when checking an item, the selection is moved to the current item to
    ' avoid "flashing" the selection.
    '
    ' Lots of help from Steve Rossell's highly recommended code at
    ' http://www.powerbasic.com/support/pbforums/showthread.php?p=276189&posted=1#post276189
    '
    #COMPILE EXE
    #DIM ALL
    #INCLUDE "commctrl.inc"
    #INCLUDE "comdlg32.inc"
    #INCLUDE "Encapsule.inc"
    #INCLUDE "SQLite.inc"
    
    %IDC_DBB_DONE_BN       = 1316
    %idc_DBB_lab1          = 1317
    %idc_DBB_lab2          = 1318
    %idc_DBB_lab3          = 1319
    %IDC_DBB_TREEVIEW      = 1320
    %IDC_main_bn           = 1321
    %idc_listbox           = 1322
    %OURMSG_EDITORHANDLE   = %WM_USER + 100
    
    DECLARE FUNCTION DBBrowser(BYVAL hParent AS DWORD) AS LONG
    DECLARE FUNCTION mainwindow  ( BYVAL hParent AS DWORD ) AS LONG
    
    GLOBAL gsDBPath AS STRING
    GLOBAL gEditWnd AS DWORD
    
    FUNCTION PBMAIN () AS LONG
    
        InitCommonControls
        DBBrowser(0)
        mainwindow(0)
    
    END FUNCTION
    '------------------------------------------------------------------------------
    FUNCTION SampleTreeViewInsertItem(BYVAL hTree AS DWORD, BYVAL hParent AS DWORD, sItem AS STRING) AS LONG
        LOCAL tTVItem   AS TV_ITEM
        LOCAL tTVInsert AS TV_INSERTSTRUCT
    
        IF hParent THEN
            tTVItem.mask      = %TVIF_CHILDREN OR %TVIF_HANDLE
            tTVItem.hItem     = hParent
            tTVItem.cchildren = 1
            TreeView_SetItem hTree, tTVItem
        END IF
    
        tTVInsert.hParent              = hParent
        tTVInsert.Item.Item.mask       = %TVIF_TEXT
        tTVInsert.Item.Item.pszText    = STRPTR(sItem)
        tTVInsert.Item.Item.cchTextMax = LEN(sItem)
    
        FUNCTION = TreeView_InsertItem(hTree, tTVInsert)
    END FUNCTION
    '------------------------------------------------------------------------------
    FUNCTION SampleTreeView(BYVAL hDlg AS DWORD, BYVAL lID AS LONG, BYVAL lCount AS LONG) AS LONG
        LOCAL i       AS LONG
        LOCAL j       AS LONG
        LOCAL k       AS LONG
        LOCAL hCtl    AS DWORD
        LOCAL hRoot   AS DWORD
        LOCAL hParent AS DWORD
    
        CONTROL HANDLE hDlg, lID TO hCtl
    
        FOR i = 1 TO lCount
            hRoot = SampleTreeViewInsertItem(hCtl, %NULL, USING$("Root#", i))
            FOR j = 1 TO lCount
                hParent = SampleTreeViewInsertItem(hCtl, hRoot, USING$("Item#", j))
                FOR k = 1 TO lCount
                    CALL SampleTreeViewInsertItem(hCtl, hParent, USING$("SubItem#_.#", j, k))
                NEXT k
            NEXT j
        NEXT i
    END FUNCTION
    '------------------------------------------------------------------------------
    ' this sub ascends the tree from the current item, setting the checked state to "checked"
    ' as it goes. Assumption: that the hItem part of the structure pointed to by 2nd param
    ' is valid. Note that the item pointed to does not have its checkstate changed by this code
    '
    SUB CheckParent ( hTVWnd AS DWORD, BYVAL pTV AS TV_ITEM PTR)
        LOCAL TreeItem AS TV_ITEM
        LOCAL i AS LONG
    
        TreeItem = @pTV
        TreeItem.mask = %TVIF_STATE OR %TVIF_HANDLE
        
        TreeItem.hItem = TreeView_GetParent ( hTVWnd, TreeItem.hitem)
        WHILE TreeItem.hItem <> %NULL
            TreeItem.mask = %TVIF_STATE OR %TVIF_HANDLE
            TreeItem.stateMask = %TVIS_STATEIMAGEMASK
            i = 2 ' 2 = checked, 1 = not
            SHIFT LEFT i, 12
            TreeItem.state = i
            SendMessage(hTVWnd, %TVM_SETITEM, 0, BYVAL VARPTR(TreeItem))
            TreeItem.hItem = TreeView_GetParent ( hTVWnd , TreeItem.hitem)
        WEND
    END SUB
    '------------------------------------------------------------------------------
    ' function prototype for walkies "onHit" fn
    ' first param is treeview window handle
    ' second param is pointer to TV_ITEM
    ' 3rd param is path
    DECLARE FUNCTION TVfnPrototype  ( hTVWnd AS DWORD, BYVAL pTV AS TV_ITEM PTR, BYVAL psz AS ASCIZ PTR) AS LONG
    '------------------------------------------------------------------------------
    FUNCTION Our_TVITEM_proc ( hTVWnd AS DWORD, BYVAL pTV AS TV_ITEM PTR, BYVAL psz AS ASCIZ PTR) AS LONG
        ' this line sends the TV item name to a listbox
        sendmessage geditWnd, %LB_ADDSTRING, 0, psz ' 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 * 1024
        LOCAL hti AS tv_item PTR
        LOCAL treeItem AS TV_ITEM
        LOCAL pTVITEM AS tv_item PTR
        LOCAL i AS LONG
    
        TreeItem.HItem = hTVItem
        pTVITEM = VARPTR(TreeItem)
        WHILE TreeItem.HItem <> %NULL
            TreeItem.mask       = %TVIF_TEXT OR %TVIF_STATE OR %TVIF_HANDLE
            TreeItem.stateMask  = %TVIS_STATEIMAGEMASK
            TreeItem.cchTextMax = SIZEOF(sz)
            TreeItem.pszText    = VARPTR(sz)
            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, VARPTR(sz))
                CALL walkies(hTVWnd, OnHitFn, TreeView_GetChild(hTVwnd, TreeItem.hitem), VARPTR(sz))
            END IF
            TreeItem.HItem = Treeview_GetNextSibling(hTVWnd, TreeItem.hItem)
        WEND
    END FUNCTION
    '------------------------------------------------------------------------------
    CALLBACK FUNCTION DBBrowser_dialogProc()
        STATIC hmenu, hparent, hTVWnd AS DWORD
        LOCAL r             AS rect
        LOCAL s, s1         AS STRING
        LOCAL hDB, l, lresult AS LONG
        LOCAL sz            AS ASCIIZ*64
        LOCAL psz           AS ASCIZ PTR
        LOCAL lpNmh         AS NMHDR PTR
        LOCAL lpTV          AS NM_TREEVIEW PTR
        LOCAL treeItem      AS TV_ITEM
        LOCAL pTVITEM       AS tv_item PTR
        LOCAL TVdi          AS TV_DISPINFO
        LOCAL TVht          AS TV_HITTESTINFO
        LOCAL DWPOS         AS DWORD
    
        SELECT CASE AS LONG CBMSG
            CASE %WM_INITDIALOG
                ' Initialization handler
                'dialog get user cbhndl, 1 to hEditWnd
    '            hParent = GetParent (CBHNDL)
                hTVWnd = getdlgitem(CBHNDL, %IDC_DBB_TREEVIEW)
    '            gsDBPath = selDB(CBHNDL)
    '            IF ISFALSE sqlOpen( gsDBPath, hDB) THEN
    '                ? "unable to open database"  , %mb_applmodal,"Warning"
    '                EXIT SELECT
    '            END IF
    '            s = "undefined"
    '            IF TRIM$(gsDBPath) <> "" THEN
    '                IF ASC(LEFT$(gsDBPath,1)) <> 0 THEN
    '                    s = gsDBPath
    '                END IF
    '            END IF
                CONTROL ADD LABEL, CBHNDL, %idc_DBB_lab1,"check boxes press button" & s ,5, 2, 175,12
                'tablelist ( CBHNDL, %IDC_DBB_TABLES_LB, hDB)
    
                SampleTreeView(CBHNDL, %IDC_DBB_TREEVIEW,20)
    '            DBTreeView( hDB, CBHNDL, %IDC_DBB_TREEVIEW,20)
             '
             CASE %WM_NOTIFY
                 lpNmh = CBLPARAM
                 SELECT CASE @lpNmh.Code
                    CASE %TVN_SELCHANGED
                       'get selected text
                       lpTV = CBLPARAM
                       'hTreeItem = @lpTV.ItemNew.hItem
                       TreeItem.hItem = @lpTV.ItemNew.hItem
                       TreeItem.mask = %TVIF_TEXT
                       TreeItem.cchTextMax = SIZEOF(sz)
                       TreeItem.psztext    = VARPTR(sz)
                       pTVITEM = VARPTR(TreeItem)
                       CONTROL SEND CBHNDL, %IDC_DBB_TREEVIEW, %TVM_GETITEM, 0, pTVITEM TO lresult
                       sendmessage hTVWnd, %LB_ADDSTRING, 0, VARPTR(sz)
    
                    CASE %NM_CLICK
                      IF @lpNmh.idFrom = %IDC_DBB_TREEVIEW 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, @LPnMH.hwndFrom, TVht.pt, 1)
    
                        ' Get the TreeView item/node returned in the hittest udt member of hItem
                        SendMessage(hTVWnd, %TVM_HITTEST, 0, BYVAL VARPTR(TVht))
                        ' get item
                        TreeItem.mask       = %TVIF_STATE OR %TVIF_HANDLE
                        TreeItem.hItem      = TVHT.Hitem
                        sendmessage hTVWnd, %TVM_GETITEM, 0, VARPTR(TreeItem)
                        CheckParent ( hTVWnd, TreeItem.hitem)
                        ' Select the TreeView item/node that was clicked on (returned above)
                        SendMessage(hTVWnd, %TVM_SELECTITEM, %TVGN_CARET, TVht.hItem)
                      END IF
                 END SELECT
    
            CASE %WM_NCACTIVATE
                STATIC hWndSaveFocus AS DWORD
                IF ISFALSE CBWPARAM THEN
                    ' Save control focus
                    hWndSaveFocus = GetFocus()
                ELSEIF hWndSaveFocus THEN
                    ' Restore control focus
                    SetFocus(hWndSaveFocus)
                    hWndSaveFocus = 0
                END IF
    
            CASE %WM_LBUTTONDOWN
                SendMessage CBHNDL, %WM_NCLBUTTONDOWN, %HTCAPTION, BYVAL %NULL  ' force drag
    
            CASE %WM_COMMAND
            SELECT CASE CBCTL  ' <- look at control's id
               CASE %IDC_DBB_DONE_BN
                  IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                      walkies ( hTVWnd, CODEPTR(Our_TVITEM_proc), TreeView_GetRoot( hTVWnd), BYVAL %null)
                  END IF
            END SELECT
        END SELECT
    END FUNCTION
    '------------------------------------------------------------------------------
    FUNCTION DBBrowser(BYVAL hParent AS DWORD) AS LONG
        LOCAL lRslt AS LONG
        LOCAL hDlg  AS DWORD
        LOCAL s AS STRING
    
        DIALOG NEW hParent, "", 10, 100, 140, 205, %WS_POPUP OR %WS_THICKFRAME OR _
            %WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_3DLOOK OR %DS_NOFAILCREATE OR _
            %DS_SETFONT, %WS_EX_CONTROLPARENT OR %WS_EX_TOOLWINDOW OR _
            %WS_EX_TOPMOST OR %WS_EX_LEFT OR %WS_EX_LTRREADING TO hdlg
        DIALOG  SET COLOR   hDlg, -1, RGB(255, 255, 155)
        CONTROL ADD BUTTON,  hDlg, %IDC_DBB_DONE_BN, "Send selection", 70, 190, 70, 15
        CONTROL ADD "SysTreeView32", hDlg,%IDC_DBB_TREEVIEW, "SysTreeView32_1", 5, 15, 135, 175, %WS_CHILD OR %WS_VISIBLE OR _
            %WS_TABSTOP OR %TVS_HASBUTTONS OR %TVS_HASLINES OR %TVS_CHECKBOXES OR %TVS_LINESATROOT OR %TVS_SHOWSELALWAYS, %WS_EX_CLIENTEDGE OR _
            %WS_EX_LEFT OR %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR
    
        DIALOG SHOW MODELESS hDlg, CALL DBBrowser_dialogProc TO lRslt
    
        FUNCTION = lRslt
    END FUNCTION
    '--------------------------------------------------------------------------------
    CALLBACK FUNCTION mainwindowproc()
        LOCAL sz AS ASCIZ * 64
    
        SELECT CASE AS LONG CBMSG
            CASE %WM_COMMAND
            SELECT CASE CBCTL  ' <- look at control's id
               CASE %IDC_MAIN_BN
                  IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                      DIALOG END CBHNDL, 0
                  END IF
            END SELECT
        END SELECT
    END FUNCTION
    
    '--------------------------------------------------------------------------------
    FUNCTION mainwindow  ( BYVAL hParent AS DWORD ) AS LONG
        LOCAL lRslt AS LONG
        LOCAL hDlg  AS DWORD
    
        DIALOG NEW hParent, "", 180, 100, 200, 210, %WS_POPUP OR %WS_THICKFRAME OR _
            %WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_3DLOOK OR %DS_NOFAILCREATE OR _
            %DS_SETFONT, %WS_EX_CONTROLPARENT OR _
            %WS_EX_TOPMOST OR %WS_EX_LEFT OR %WS_EX_LTRREADING TO hdlg
    
    
        CONTROL ADD LISTBOX, hdlg, %IDC_LISTBOX,, 0,0,200,200, _
        %WS_CHILD OR %WS_TABSTOP OR %WS_VISIBLE OR %WS_VSCROLL OR %LBS_NOTIFY, _
        %WS_EX_CLIENTEDGE OR %WS_EX_LEFT OR %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR
    
        gEditWnd = getdlgitem(hdlg, %IDC_LISTBOX)
    
        CONTROL ADD BUTTON,  hDlg, %IDC_main_bn, "exit", 170, 195, 30, 15
    
        DIALOG SHOW MODAL hdlg CALL mainwindowproc
    END FUNCTION
    Last edited by Chris Holbrook; 19 Feb 2008, 02:45 AM.

    #2
    more features

    This example passes the treeview "path" back, and also allows selection of all siblings at one level with a single click:
    Code:
    '
    #COMPILE EXE
    #DIM ALL
    #INCLUDE "commctrl.inc"
    #INCLUDE "comdlg32.inc"
    
    %IDC_DBB_DONE_BN       = 1316
    %idc_DBB_lab1          = 1317
    %idc_DBB_lab2          = 1318
    %idc_DBB_lab3          = 1319
    %IDC_DBB_TREEVIEW      = 1320
    %IDC_main_bn           = 1321
    %idc_listbox           = 1322
    %OURMSG_EDITORHANDLE   = %WM_USER + 100
    
    
    DECLARE FUNCTION DBBrowser(BYVAL hParent AS DWORD) AS LONG
    DECLARE FUNCTION mainwindow  ( BYVAL hParent AS DWORD ) AS LONG
    
    GLOBAL gsDBPath AS STRING
    GLOBAL gEditWnd AS DWORD
    GLOBAL gchecked, gunchecked      AS DWORD
    
    FUNCTION PBMAIN () AS LONG
    
        InitCommonControls
        gchecked   = 2: SHIFT LEFT gchecked,   12
        gunchecked = 1: SHIFT LEFT gunchecked, 12
        DBBrowser(0)
        mainwindow(0)
    
    END FUNCTION
    '------------------------------------------------------------------------------
    FUNCTION SampleTreeViewInsertItem(BYVAL hTree AS DWORD, BYVAL hParent AS DWORD, sItem AS STRING) AS LONG
        LOCAL tTVItem   AS TV_ITEM
        LOCAL tTVInsert AS TV_INSERTSTRUCT
    
        IF hParent THEN
            tTVItem.mask      = %TVIF_CHILDREN OR %TVIF_HANDLE
            tTVItem.hItem     = hParent
            tTVItem.cchildren = 1
            TreeView_SetItem hTree, tTVItem
        END IF
    
        tTVInsert.hParent              = hParent
        tTVInsert.Item.Item.mask       = %TVIF_TEXT
        tTVInsert.Item.Item.pszText    = STRPTR(sItem)
        tTVInsert.Item.Item.cchTextMax = LEN(sItem)
    
        FUNCTION = TreeView_InsertItem(hTree, tTVInsert)
    END FUNCTION
    '------------------------------------------------------------------------------
    FUNCTION SampleTreeView(BYVAL hDlg AS DWORD, BYVAL lID AS LONG, BYVAL lCount AS LONG) AS LONG
        LOCAL i       AS LONG
        LOCAL j       AS LONG
        LOCAL k       AS LONG
        LOCAL hCtl    AS DWORD
        LOCAL hRoot   AS DWORD
        LOCAL hParent AS DWORD
    
        CONTROL HANDLE hDlg, lID TO hCtl
    
        FOR i = 1 TO lCount
            hRoot = SampleTreeViewInsertItem(hCtl, %NULL, USING$("Root#", i))
            CALL SampleTreeViewInsertItem(hCtl, hRoot, "*")
            FOR j = 1 TO lCount
                hParent = SampleTreeViewInsertItem(hCtl, hRoot, USING$("Item#", j))
                CALL SampleTreeViewInsertItem(hCtl, hParent, "*")
                FOR k = 1 TO lCount
                    CALL SampleTreeViewInsertItem(hCtl, hParent, USING$("SubItem#_.#", j, k))
                NEXT k
            NEXT j
        NEXT i
    END FUNCTION
    '------------------------------------------------------------------------------
    ' this sub ascends the tree from the current item, setting the checked state to "checked"
    ' as it goes. Assumption: that the hItem part of the structure pointed to by 2nd param
    ' is valid. Note that the item pointed to does not have its checkstate changed by this code
    '
    SUB CheckParent ( hTVWnd AS DWORD, dwItem AS DWORD)
        LOCAL TreeItem AS TV_ITEM
        LOCAL i AS DWORD
    
        TreeItem.hItem = TreeView_GetParent ( hTVWnd, dwitem)
        WHILE TreeItem.hItem <> %NULL
            TreeItem.mask = %TVIF_STATE OR %TVIF_HANDLE
            TreeItem.stateMask = %TVIS_STATEIMAGEMASK
            TreeItem.state = gchecked
            Treeview_setItem (hTVWnd, BYVAL VARPTR(TreeItem))
            TreeItem.hItem = TreeView_GetParent ( hTVWnd , TreeItem.hitem)
        WEND
    END SUB
    '------------------------------------------------------------------------------
    ' Called when the text of the checked item is "*".
    ' check all its siblings
    SUB CheckAll ( hTVWnd AS DWORD, BYVAL pTV AS TV_ITEM PTR)
        LOCAL TreeItem AS TV_ITEM
        LOCAL i        AS LONG
        LOCAL checked  AS DWORD
        LOCAL sz AS ASCIZ * 256
    '    local psz as asciz ptr
    
        TreeItem = @pTV
        checked = TreeItem.state
        IF (checked AND gchecked) = gchecked THEN
            checked = gunchecked
        ELSE
            checked = gchecked
        END IF
        ' skip over the checkbox on the "*" item, let default processing
        ' set/unset its checkbox
        TreeItem.hItem = TreeView_GetNextSibling ( hTVWnd , TreeItem.hitem)
    
        WHILE TreeItem.hItem <> %NULL
            TreeItem.mask = %TVIF_STATE OR %TVIF_HANDLE
            TreeItem.stateMask = %TVIS_STATEIMAGEMASK
            TreeItem.state     = checked
            IF Treeview_setItem(hTVWnd, BYVAL VARPTR(TreeItem)) <> %TRUE THEN
                ? "failed to update treeview"
            END IF
            TreeItem.hItem = TreeView_GetNextSibling ( hTVWnd , TreeItem.hitem)
        WEND
    
    END SUB
    '------------------------------------------------------------------------------
    ' function prototype for walkies "onHit" fn
    ' first param is treeview window handle
    ' second param is pointer to TV_ITEM
    ' 3rd param is path
    DECLARE FUNCTION TVfnPrototype  ( hTVWnd AS DWORD, BYVAL pTV AS TV_ITEM PTR, BYVAL psz AS ASCIZ PTR) AS LONG
    '------------------------------------------------------------------------------
    FUNCTION Our_TVITEM_proc ( hTVWnd AS DWORD, BYVAL pTV AS TV_ITEM PTR, BYVAL psz AS ASCIZ PTR) AS LONG
        ' this line sends the TV item name to a listbox
        IF RIGHT$(TRIM$(@psz),1) <> "*" THEN
            sendmessage geditWnd, %LB_ADDSTRING, 0, psz ' send it on, prefixed by parent id
        END IF
    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 * 1024
        LOCAL hti AS tv_item PTR
        LOCAL treeItem AS TV_ITEM
        LOCAL pTVITEM AS tv_item PTR
        LOCAL i AS LONG
    
        TreeItem.HItem = hTVItem
        pTVITEM = VARPTR(TreeItem)
        WHILE TreeItem.HItem <> %NULL
            TreeItem.mask       = %TVIF_TEXT OR %TVIF_STATE OR %TVIF_HANDLE
            TreeItem.stateMask  = %TVIS_STATEIMAGEMASK
            TreeItem.cchTextMax = SIZEOF(sz)
            TreeItem.pszText    = VARPTR(sz)
            TReeView_getItem( hTVWnd, BYVAL pTVITEM) ' get item
            ' is it checked?
    '        ? str$(gchecked)+ ":" + str$(TreeItem.state)
            IF (TreeItem.state AND gchecked) = gchecked THEN
                IF @pszParent <> "" THEN sz = @pszParent + "." + sz
                CALL DWORD OnHitFn USING TVfnPrototype (hTVWnd, BYVAL pTVITEM, BYVAL VARPTR(sz))
                CALL walkies(hTVWnd, OnHitFn, TreeView_GetChild(hTVwnd, TreeItem.hitem), BYVAL VARPTR(sz))
            END IF
            TreeItem.HItem = Treeview_GetNextSibling(hTVWnd, TreeItem.hItem)
        WEND
    END FUNCTION
    
    '------------------------------------------------------------------------------
    CALLBACK FUNCTION DBBrowser_dialogProc()
        STATIC hmenu, hparent, hTVWnd AS DWORD
        LOCAL r             AS rect
        LOCAL s, s1         AS STRING
        LOCAL hDB, l, lresult AS LONG
        LOCAL sz            AS ASCIIZ*256
        LOCAL psz           AS ASCIZ PTR
        LOCAL lpNmh         AS NMHDR PTR
        LOCAL lpTV          AS NM_TREEVIEW PTR
        LOCAL treeItem      AS TV_ITEM
        LOCAL pTVITEM       AS tv_item PTR
        LOCAL TVdi          AS TV_DISPINFO
        LOCAL TVht          AS TV_HITTESTINFO
        LOCAL DWPOS         AS DWORD
    
        SELECT CASE AS LONG CBMSG
            CASE %WM_INITDIALOG
                hTVWnd = getdlgitem(CBHNDL, %IDC_DBB_TREEVIEW)
                CONTROL ADD LABEL, CBHNDL, %idc_DBB_lab1,"check boxes press button" & s ,5, 2, 175,12
    
                SampleTreeView(CBHNDL, %IDC_DBB_TREEVIEW,20)
             '
             CASE %WM_NOTIFY
                 lpNmh = CBLPARAM
                 SELECT CASE @lpNmh.Code
                    CASE %TVN_SELCHANGED
                       'get selected text
                       lpTV = CBLPARAM
                       TreeItem.hItem = @lpTV.ItemNew.hItem
                       TreeItem.mask = %TVIF_TEXT
                       TreeItem.cchTextMax = SIZEOF(sz)
                       TreeItem.psztext    = VARPTR(sz)
                       pTVITEM = VARPTR(TreeItem)
                       TreeView_GetItem( hTVWnd, BYVAL pTVITEM)
    
                    CASE %NM_CLICK
                      IF @lpNmh.idFrom = %IDC_DBB_TREEVIEW 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, @LPnMH.hwndFrom, TVht.pt, 1)
                        ' clicked on the checkbox?
                        ' Get the TreeView item/node returned in the hittest udt member of hItem
                        TreeView_HitTest( hTVWnd, BYVAL VARPTR(TVht))
                        ' examine the flags to see if the checkbox was hit
                        IF (tvht.flags AND %TVHT_ONITEMSTATEICON) = %TVHT_ONITEMSTATEICON THEN
                            ' get item
                            TreeItem.mask       = %TVIF_STATE OR %TVIF_HANDLE OR %TVIF_TEXT
                            TreeItem.stateMask  = %TVIS_STATEIMAGEMASK
                            TreeItem.cchTextMax = SIZEOF(sz)
                            TreeItem.psztext    = VARPTR(sz)
                            TreeItem.hItem      = TVHT.Hitem
                            TreeView_GetItem (hTVWnd, BYVAL VARPTR(TreeItem))
                            IF TRIM$(sz) = "*" THEN
                                CheckAll (hTVWnd, BYVAL VARPTR(TreeItem))
                            END IF
                            CheckParent (hTVWnd, TreeItem.Hitem)
                            ' Select the TreeView item/node that was clicked on (returned above)
                            TreeView_SelectItem(hTVWnd, TreeItem.hItem)
                        END IF
                      END IF
                 END SELECT
    
            CASE %WM_NCACTIVATE
                STATIC hWndSaveFocus AS DWORD
                IF ISFALSE CBWPARAM THEN
                    ' Save control focus
                    hWndSaveFocus = GetFocus()
                ELSEIF hWndSaveFocus THEN
                    ' Restore control focus
                    SetFocus(hWndSaveFocus)
                    hWndSaveFocus = 0
                END IF
    
            CASE %WM_LBUTTONDOWN
                SendMessage CBHNDL, %WM_NCLBUTTONDOWN, %HTCAPTION, BYVAL %NULL  ' force drag
    
            CASE %WM_COMMAND
            SELECT CASE CBCTL  ' <- look at control's id
               CASE %IDC_DBB_DONE_BN
                  IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                      walkies ( hTVWnd, CODEPTR(Our_TVITEM_proc), TreeView_GetRoot( hTVWnd), BYVAL %null)
                  END IF
            END SELECT
        END SELECT
    END FUNCTION
    '------------------------------------------------------------------------------
    FUNCTION DBBrowser(BYVAL hParent AS DWORD) AS LONG
        LOCAL lRslt AS LONG
        LOCAL hDlg  AS DWORD
        LOCAL s AS STRING
    
        DIALOG NEW hParent, "", 10, 100, 140, 205, %WS_POPUP OR %WS_THICKFRAME OR _
            %WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_3DLOOK OR %DS_NOFAILCREATE OR _
            %DS_SETFONT, %WS_EX_CONTROLPARENT OR %WS_EX_TOOLWINDOW OR _
            %WS_EX_TOPMOST OR %WS_EX_LEFT OR %WS_EX_LTRREADING TO hdlg
        DIALOG  SET COLOR   hDlg, -1, RGB(255, 255, 155)
        CONTROL ADD BUTTON,  hDlg, %IDC_DBB_DONE_BN, "Send selection", 70, 190, 70, 15
        CONTROL ADD "SysTreeView32", hDlg,%IDC_DBB_TREEVIEW, "SysTreeView32_1", 5, 15, 135, 175, %WS_CHILD OR %WS_VISIBLE OR _
            %WS_TABSTOP OR %TVS_HASBUTTONS OR %TVS_HASLINES OR %TVS_CHECKBOXES OR %TVS_LINESATROOT OR %TVS_SHOWSELALWAYS, %WS_EX_CLIENTEDGE OR _
            %WS_EX_LEFT OR %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR
    
        DIALOG SHOW MODELESS hDlg, CALL DBBrowser_dialogProc TO lRslt
    
        FUNCTION = lRslt
    END FUNCTION
    '--------------------------------------------------------------------------------
    CALLBACK FUNCTION mainwindowproc()
        LOCAL sz AS ASCIZ * 64
    
        SELECT CASE AS LONG CBMSG
            CASE %WM_COMMAND
            SELECT CASE CBCTL  ' <- look at control's id
               CASE %IDC_MAIN_BN
                  IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                      DIALOG END CBHNDL, 0
                  END IF
            END SELECT
        END SELECT
    END FUNCTION
    
    '--------------------------------------------------------------------------------
    FUNCTION mainwindow  ( BYVAL hParent AS DWORD ) AS LONG
        LOCAL lRslt AS LONG
        LOCAL hDlg  AS DWORD
    
        DIALOG NEW hParent, "", 180, 100, 200, 210, %WS_POPUP OR %WS_THICKFRAME OR _
            %WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_3DLOOK OR %DS_NOFAILCREATE OR _
            %DS_SETFONT, %WS_EX_CONTROLPARENT OR _
            %WS_EX_TOPMOST OR %WS_EX_LEFT OR %WS_EX_LTRREADING TO hdlg
    
    
        CONTROL ADD LISTBOX, hdlg, %IDC_LISTBOX,, 0,0,200,200, _
        %WS_CHILD OR %WS_TABSTOP OR %WS_VISIBLE OR %WS_VSCROLL OR %LBS_NOTIFY, _
        %WS_EX_CLIENTEDGE OR %WS_EX_LEFT OR %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR
    
        gEditWnd = getdlgitem(hdlg, %IDC_LISTBOX)
    
        CONTROL ADD BUTTON,  hDlg, %IDC_main_bn, "exit", 170, 195, 30, 15
    
        DIALOG SHOW MODAL hdlg CALL mainwindowproc
    END FUNCTION

    Comment


      #3
      correction to 1st post

      the following spurious includes should be deleted:

      #INCLUDE "comdlg32.inc"
      #INCLUDE "Encapsule.inc"
      #INCLUDE "SQLite.inc

      This is not a SQLite application.

      Comment

      Working...
      X
      😀
      🥰
      🤢
      😎
      😡
      👍
      👎