buff1 New Member
 member is offline
Joined: Mar 2006 Gender: Male  Posts: 23
|  | File List/Select using Treeview « Thread Started on Dec 18, 2008, 6:26pm » | |
A simple dialog using Treeview. Credit goes to Charles Dietz for the major part of the code. Some Gleaning from Tonny Bjorn for the Selchanging case. Files listbox and File textbox added by me.
'Basic Treeview of C: folders by Charles Dietz.2006 'with some gleaning of code from Tonny Bjorn.(CASE %TVN_SELCHANGING) 'modified slightly in 2008 done to expand in itemref_UDT 'Modified to add Subdirectory files and to select 'a file by Fred Buffington 12/2008 (the easy part) '======================================================================== 'Compile and Include statements '======================================================================== #COMPILE EXE #DIM ALL #INCLUDE "win32api.inc" #INCLUDE "Commctrl.inc" '#INCLUDE "debug.inc" '======================================================================== 'Declarations, UDTs, and Globals '======================================================================== %ID_TREE = 100 %ID_LISTBOX1 = 301
TYPE itemRef_UDT hItem AS LONG 'handle of item PARENT AS LONG 'item number of parent subDirs AS BYTE '1 = subdirectories exist, otherwise 0 expand AS BYTE '1 for expanded, 0 for collapsed END TYPE
GLOBAL hTree AS LONG GLOBAL numItems AS LONG GLOBAL maxDim AS LONG GLOBAL ITEM() AS STRING GLOBAL itemRef() AS itemRef_UDT GLOBAL UserSelected$ GLOBAL dirToSearch$
DECLARE FUNCTION TVInsertItem(LONG, LONG, STRING, BYTE) AS LONG DECLARE FUNCTION getItemNo(LONG) AS LONG DECLARE FUNCTION subDirsExist(STRING) AS BYTE DECLARE SUB getNextDirs(LONG) '======================================================================== 'Program start '======================================================================== FUNCTION PBMAIN() LOCAL hMain AS LONG LOCAL dummy$() DIM dummy$(0) 'title changed from "Mytreeview" DIALOG NEW PIXELS, 0, "Folder TreeView - Select File Dialog - C Drive", , , 500, 420,%WS_SYSMENU OR %WS_MINIMIZEBOX TO hMain 'add treeview common control CONTROL ADD "SysTreeView32", hMain, %ID_TREE, "", 0, 20, 300, 300, _ %WS_CHILD OR %WS_VISIBLE OR %TVS_HASBUTTONS OR %TVS_HASLINES OR _ %TVS_LINESATROOT OR %TVS_SHOWSELALWAYS, %WS_EX_CLIENTEDGE CONTROL ADD LABEL, hMain,101,"Folders",0,3,300,17,%SS_CENTER CONTROL ADD LABEL, hMain,102,"Files",310,3,170,17,%SS_CENTER CONTROL ADD LABEL, hMain,102,"File name",310,330,140,17,%SS_CENTER CONTROL ADD BUTTON, hMain,201,"&Close",100,380,80,30 CONTROL ADD BUTTON, hMain,202,"&Open",340,380,80,30 CONTROL ADD LISTBOX, hMain,%ID_ListBOX1,dummy$(),310,20,170,320,%WS_VSCROLL OR %WS_HSCROLL, %WS_EX_CLIENTEDGE 'OR %ES_MULTILINE CONTROL ADD TEXTBOX, hMain,302,"",310,350,140,22',%ES_MULTILINE OR %WS_VSCROLL DIALOG SHOW MODAL hMain CALL TreeViewProc
IF UserSelected$<>"" THEN 'if a file was selected, show the path in a message box MSGBOX "File is "+dirToSearch$+"\"+userSelected$ END IF END FUNCTION
CALLBACK FUNCTION TreeViewProc() LOCAL i, m, n, hTreeItem, hItem, hParent, hChild AS LONG LOCAL s AS STRING, szTxt AS ASCIIZ*64 LOCAL lpNmh AS NMHDR PTR LOCAL lpTV AS NM_TREEVIEW PTR LOCAL treeItem AS TV_ITEM LOCAL TVdi AS TV_DISPINFO LOCAL txt$,lResult$ 'LOCAL dirtosearch$ LOCAL dummy$() LOCAL PATH$,set_horiz&
DIM dummy$(0) SELECT CASE CBMSG CASE %WM_INITDIALOG maxDim = 2000 DIM ITEM(maxDim) DIM itemRef(maxDim)
'find the first level children of C:\ ITEM(0) = "C:": getNextDirs 0
'display the folders and files CONTROL HANDLE CBHNDL, %ID_TREE TO hTree itemRef(0).hItem = TVInsertItem(hTree, 0, "C:\", 1) FOR i = 1 TO numItems s = PARSE$(ITEM(i), "\", -1) hParent = itemRef(itemRef(i).PARENT).hItem hChild = TVInsertItem(hTree, hParent, s, itemRef(i).subDirs) itemRef(i).hItem = hChild NEXT i
'open with first level folders... the children of C:\ SendMessage hTree, %TVM_EXPAND, %TVE_EXPAND, itemRef(0).hItem CASE %WM_PAINT CASE %WM_COMMAND SELECT CASE CBCTL CASE 201 'close button UserSelected$="":DirtoSearch$="" DIALOG END CBHNDL,0 CASE 202 'open DIALOG END CBHNDL,1 CASE 301 'select a file from textbox LISTBOX GET TEXT CBHNDL,301 TO UserSelected$ CONTROL SET TEXT CBHNDL,302,UserSelected$ CASE 302 'file name text box CONTROL GET TEXT CBHNDL,302 TO UserSelected$ END SELECT CASE %WM_NOTIFY lpNmh = CBLPARAM SELECT CASE @lpNmh.CODE CASE %TVN_ITEMEXPANDING 'expand or collapse the treeview node hTreeItem lpTV = CBLPARAM hTreeItem = @lpTV.ItemNew.hItem m = numItems: n = getItemNo(hTreeItem) IF itemRef(n).expand = 0 THEN getNextDirs n
FOR i = m + 1 TO numItems s = PARSE$(ITEM(i), "\", -1) hParent = itemRef(itemRef(i).PARENT).hItem hChild = TVInsertItem(hTree, hParent, s, itemRef(i).subDirs) itemRef(i).hItem = hChild NEXT i
txt$="" LISTBOX RESET CBHNDL,301 dirtosearch$=ITEM(n) set_horiz&=0 lResult$=DIR$(dirtosearch$+"\*.*",0) WHILE lResult$<>"" txt$ =lResult$ LISTBOX ADD CBHNDL,301,txt$ IF LEN(txt$)>28 THEN set_horiz&=1 lResult$=DIR$ WEND IF set_horiz& THEN CONTROL SEND CBHNDL, %ID_ListBOX1, %LB_SETHORIZONTALEXTENT, 500, 0 ELSE CONTROL SEND CBHNDL, %ID_ListBOX1, %LB_SETHORIZONTALEXTENT, 0, 0 END IF CASE %TVN_SELCHANGING 'LAST 'FIRST 'KEYDOWN lpTV = CBLPARAM hTreeItem = @lpTV.ItemNew.hItem m = numItems: n = getItemNo(hTreeItem) txt$="" LISTBOX RESET CBHNDL,301 dirtosearch$=ITEM(n) set_horiz&=0 lResult$=DIR$(dirtosearch$+"\*.*",0) WHILE lresult$<>"" txt$ =lrEsult$ 'txt$+lResult$+$CRLF LISTBOX ADD CBHNDL,301,txt$ IF LEN(txt$)>28 THEN set_horiz&=1 'count&=count&+1 lResult$=DIR$ WEND IF set_horiz& THEN CONTROL SEND CBHNDL, %ID_ListBOX1, %LB_SETHORIZONTALEXTENT, 500, 0 ELSE CONTROL SEND CBHNDL, %ID_ListBOX1, %LB_SETHORIZONTALEXTENT, 0, 0 END IF
END SELECT
CASE %WM_SYSCOMMAND CASE %WM_DESTROY END SELECT END FUNCTION
FUNCTION getItemNo(hTreeItem AS LONG) AS LONG 'get itemNo corresponding to item's handle 'hTreeItem = item handle 'numItems = number of items defined (nodes of treeview) '=================================================================== LOCAL i, n AS LONG FOR i = 1 TO numItems IF itemRef(i).hItem = hTreeItem THEN n = i: EXIT FOR NEXT i FUNCTION = n END FUNCTION
FUNCTION TVInsertItem(hTree AS LONG, hParent AS LONG, sTxt AS STRING, b AS BYTE) AS LONG 'insert item into treeview control '-------------------------------------------------------------------------------- 'hTree = handle of treeview control 'hParent = handle of parent to item 'sTxt = string label identifying item 'b = set if children exist for this item '================================================================================ LOCAL tv_insert AS TV_INSERTSTRUCT tv_insert.hParent = hParent tv_insert.ITEM.ITEM.mask = %TVIF_TEXT OR %TVIF_CHILDREN tv_insert.ITEM.ITEM.pszText = STRPTR(sTxt) tv_insert.ITEM.ITEM.cchTextMax = LEN(sTxt) IF b THEN tv_insert.ITEM.ITEM.cChildren = 1 FUNCTION = TreeView_InsertItem(hTree, tv_insert) END FUNCTION
SUB getNextDirs(itemNo AS LONG) 'find next first level children of itemNo 'update global item(), itemRef(), and numItems '------------------------------------------------------------------- 'item() = array of folder names 'itemRef() = array of folder info UDTs 'numItems = number of nodes identified so far '=================================================================== LOCAL s, sParent AS STRING LOCAL attr, i, k, n, nDim AS LONG DIM sTemp(maxDim) AS STRING itemRef(itemNo).expand = 1 sParent = RTRIM$(ITEM(itemNo), "\") + "\" attr = %SUBDIR 'OR %READONLY OR %HIDDEN OR %SYSTEM s = DIR$(sParent, attr) IF LEN(s) THEN k = GETATTR(sParent + s) AND %SUBDIR IF k THEN INCR n: sTemp(n) = s DO s = DIR$: k = 0: IF LEN(s) = 0 THEN EXIT DO k = GETATTR(sParent + s) AND %SUBDIR IF k THEN INCR n: sTemp(n) = s LOOP END IF 'found n subdirectories of itemNo '... now update numItems, item(), and itemRef() IF n = 0 THEN EXIT SUB numItems = numItems + n nDim = UBOUND(ITEM) IF nDim < numItems THEN 'redim arrays if necessary nDim = numItems + 1000 REDIM PRESERVE ITEM(nDim) REDIM PRESERVE itemRef(nDim) END IF FOR i = 1 TO n s = sParent + sTemp(i) ITEM(numItems - n + i) = s itemRef(numItems - n + i).PARENT = itemNo itemRef(numItems - n + i).subDirs = subDirsExist(s) NEXT i END SUB
FUNCTION subDirsExist(sItem AS STRING) AS BYTE 'return 1 if any children exist for this node 'this function is needed to determine if node needs a [+] button '---------------------------------------------------------------- 'sItem = name of node '================================================================ LOCAL attr, k AS LONG LOCAL s, sParent AS STRING sParent = RTRIM$(sItem, "\") + "\" attr = %SUBDIR 'OR %READONLY OR %HIDDEN OR %SYSTEM s = DIR$(sParent, attr) IF LEN(s) THEN k = GETATTR(sParent + s) AND %SUBDIR DO WHILE LEN(s) AND k = 0 s = DIR$: IF LEN(s) = 0 THEN EXIT DO k = GETATTR(sParent + s) AND %SUBDIR LOOP END IF FUNCTION = SGN(k) END FUNCTION
| |
|