Client Write up and Programming
« File List/Select using Treeview »

Welcome Guest. Please Login or Register.
Dec 24, 2009, 11:12am




Client Write up and Programming :: PowerBasic Questions/Source Code :: PowerBasic :: File List/Select using Treeview
   [Search This Thread][Reply] [Send Topic To Friend] [Print]
 AuthorTopic: File List/Select using Treeview (Read 127 times)
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 »
[Quote]

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

« Last Edit: Dec 18, 2008, 6:32pm by buff1 »Link to Post - Back to Top  IP: Logged
   [Search This Thread][Reply] [Send Topic To Friend] [Print]

Google
Webbuffs.proboards.com
Click Here To Make This Board Ad-Free


This Board Hosted For FREE By ProBoards
Get Your Own Free Message Boards & Free Forums!