In principle it's quite easy: You scan the directories of all hard drives, put them in a sorted list and then display it. But there is a snag: The scanning of a big drive can last more than a minute, and if you want to scan them all you can go and drink a cup of coffee while the program is working.
So it makes sense to scan only the part of the directory you want to display. And to make the sorting easier *cough* I used a chained list instead of an array. There are still some features to implement, but in general it works now:
Code: Select all
' Original code by BasicCoder2
'------------------------------------------------------------------------- '
' Modifications by MrSwiss, bcohio2001, grindstone ... Date: 2017-11-05 Time: 01:25 PM
' ======================================================================== '
'
'Mouse support added by grindstone
'********* BEGIN MOUSEMENU ***********************************
'by grindstone *** the mousemenu section can be copied into a
' seperate file (eg. "mousemenu.bi") to be included in any
' other program to provide mouse functionality
'
#Define MM_FRAME 2
#Define MM_SHIFT 4
#Define MM_BUTTONUP 8
#Define MM_CONTINUE 16
Type tMMcolors 'mouse menu colors
foreground As ULong
background As ULong
frame As ULong
foregroundhi As ULong
backgroundhi As ULong
framehi As ULong
normalFont As UByte Ptr 'user defined font
highlightFont As UByte Ptr
Declare Property text(col As ULong)
Declare Property bgnd(col As ULong)
End Type
Property tMMcolors.text(col As ULong)
this.foreground = col
this.backgroundhi = col
this.frame = col
this.framehi = col
End Property
Property tMMcolors.bgnd(col As ULong)
this.foregroundhi = col
this.background = col
End Property
#Macro PrintMenuItem(fg, bg, fr, fp)
If graphic Then
If userDefinedFont Then
Line buffer, (xPos,yPos - 1)-(xPos + Len(text) * ch_width, yPos + ch_height), bg, bf
Draw String buffer, (xPos + IIf(Bit(mode, 2),ch_width / 2, 0), yPos), text,, fp
If Bit(mode, 1) Then 'draw frame around text
Line buffer, (xPos - 1, yPos - 1)-(xPos + textWidth, yPos + ch_height), fr, b
EndIf
Else
Line buffer, (xPos,yPos - 1)-(xPos + textWidth, yPos + ch_height), bg, bf
Draw String buffer, (xPos + IIf(Bit(mode, 2),ch_width / 2, 0), yPos), text, fg
If Bit(mode, 1) Then 'draw frame around text
Line buffer, (xPos - 1, yPos - 2)-(xPos + 1 + textWidth, yPos + ch_height + 1), fr, b
EndIf
EndIf
Else 'console window
colorrem = Color
cursorrem = Locate
Color fg, bg
Locate lin, col, 0
Print text
Locate HiByte(cursorrem),LoByte(cursorrem),HiWord(cursorrem) 'replace cursor
Color LoWord(colorrem),HiWord(colorrem) 'restore colours
EndIf
#EndMacro
Function mouseMenu(text As String, _
separator As String = "", _
xPos As Integer = 0, _
yPos As Integer = 0, _
colors As tMMcolors, _
mode As UByte = 0, _
buffer As Any Ptr = 0) As Integer
'mode bit 0 set (1) -> omitted for downward compatibility
'mode bit 1 set (2, MM_FRAME) -> draw a frame around the text
'mode bit 2 set (4, MM_SHIFT) -> shift the text right half a character
'mode bit 3 set (8, MM_BUTTONUP) -> action at button up (default: action at button down)
'mode bit 4 set (16, MM_CONTINUE) -> continued action at button down (default: single shot)
#Define lin xpos
#Define col ypos
Dim As String sc_driver
Dim As Integer mx, my, wheel, buttons
Dim As Integer sc_width, sc_height, ch_width, ch_height, graphic
Dim As Integer colorrem, cursorrem, x, returnValue = 0
Dim As Integer textWidth, ch_width_n(255), ch_width_h(255)
Dim As UByte Ptr p
Dim As Integer Ptr hp
Dim As boolean userDefinedFont = FALSE
Static As Integer xrem, yrem, returnrem
ScreenInfo sc_width, sc_height,,,,,sc_driver
graphic = Len(sc_driver) '= 0 --> console window / <> 0 --> graphic screen
If graphic Then
With colors
'get character size(s)
If (.normalFont <> 0) And (.highlightFont <> 0) Then 'user defined font
userDefinedFont = TRUE
p = .normalFont + IIf(.normalFont[0] = 7, 32, 4) 'points to font header
For x = p[1] To p[2] '1st character to last character
ch_width_n(x) = p[x + 3 - p[1]] 'write widths to array
Next
p = .highlightFont + IIf(.highlightFont[0] = 7, 32, 4)
For x = p[1] To p[2]
ch_width_h(x) = p[x + 3 - p[1]]
Next
hp = Cast(Integer Ptr, .normalFont)
ch_height = hp[3] - 1
Else
ch_width = sc_width / LoWord(Width)
ch_height = sc_height / HiWord(Width)
EndIf
End With
EndIf
If yPos = 0 Then
yPos = yrem
ElseIf yPos < 0 Then
yPos = yrem - yPos
yPos = IIf(yPos < 0, 0, yPos)
EndIf
If xPos = 0 Then
xPos = xrem
ElseIf xPos < 0 Then
xPos = xrem - xPos
xPos = IIf(xPos < 0, 0, xPos)
EndIf
xrem = xPos
yrem = yPos
If Len(separator) Then 'justify text at separator
If graphic Then
If userDefinedFont Then
For x = 1 To InStr(text, separator) - 1
xpos -= ch_width_n(text[x - 1]) 'shift xpos left
Next
Else
xPos = xPos - ((InStr(text, separator) - 1) * ch_width)
EndIf
Else 'console window
col = col - (InStr(text, separator))
EndIf
EndIf
GetMouse (mx, my, wheel, buttons)
If graphic Then
If userDefinedFont Then
For x = 0 To Len(text) - 1
textWidth += ch_width_n(text[x])
Next
Else
textWidth = Len(text) * ch_width
EndIf
If (mx >= xpos) AndAlso (mx <= xpos + textWidth) AndAlso _
(my >= yPos) AndAlso (my <= ypos + ch_height) Then 'mouse cursor touches the text
returnValue Or= 8
EndIf
Else 'console window
If (my + 1 = lin) AndAlso (mx >= col - 1) AndAlso (mx <= col - 2 + Len(text)) Then
returnValue Or= 8
EndIf
EndIf
If returnValue Then 'cursor touches the item
PrintMenuItem(colors.foregroundhi, colors.backgroundhi, colors.framehi, colors.highlightFont) 'highlight menu item
If Bit(mode, 4) Then 'MM_CONTINUE -> continuous action at button down
returnValue Or= buttons
returnrem = returnValue
Return returnValue
ElseIf Bit(mode, 3) Then 'MM_BUTTONUP -> single action at button up
If buttons Then 'mouse button pressed
returnrem = returnValue Or buttons
Else
If returnrem And &b00000111 Then 'button was pressed at the last call
returnValue = returnrem
returnrem And= &b11111000 'clear button flags
EndIf
EndIf
Return returnValue
Else 'single action at button down (default)
If buttons Then
If (returnrem And &b00000111) = 0 Then 'no button pressed at the last call
returnValue Or= buttons
returnrem = returnValue
Return returnValue
Else 'ignore button
Return returnValue
EndIf
Else 'no button
returnrem = returnValue
Return returnValue
EndIf 'buttons
EndIf 'mode
EndIf 'cursor touching item
PrintMenuItem(colors.foreground, colors.background, colors.frame, colors.normalFont)
Return 0
End Function
'******* END MOUSEMENU ********************************************
'************************************************************************************
#Include Once "dir.bi"
'#Define fbReadOnly &h01
'#Define fbHidden &h02
'#Define fbSystem &h04
'#Define fbDirectory &h10
'#Define fbArchive &h20
'#Define fbNormal (fbReadOnly Or fbArchive)
#Define black RGB(0,0,0)
#Define white RGB(255,255,255)
#Define red RGB(255,0,0)
#Define green RGB(100,255,100)
#Define dkgreen RGB(80,180,80)
ScreenRes 800, 800, 32, 2
ScreenSet 1, 0 'double buffering to prevent flicker
Color black, white : Cls
Dim Shared As tMMcolors mmcblack, mmcred
Dim Shared As Any Ptr wndImg
Dim Shared As String message
mmcblack.text = black
mmcblack.bgnd = white
mmcred.text = red
mmcred.bgnd = white
'----------------------------------------------
Enum 'listbox view methods
treeview
listview
imageview
End Enum
Type tTreeNode
As String fName 'name of the current subfolder
As UInteger attr 'attributes
As Integer depth 'folder depth
As boolean deflate = TRUE 'deflation flag (for folder)
As tTreeNode Ptr parent 'pointer to parent node
As tTreeNode Ptr child(Any) 'array of child nodes (sorted by fname)
Declare Property total() As Integer
Declare Function doTotal(p As tTreeNode Ptr) As Integer
Declare Property path() As String
End Type
Property tTreeNode.total() As Integer
Dim As Integer ret
Dim As tTreeNode Ptr p = @This
Do While p->parent <> 0 'get parent node
p = p->parent
Loop
For x As Integer = 0 To UBound(p->child) 'all drives
ret += this.doTotal(p->child(x))
Next
Return ret
End Property
Function tTreeNode.doTotal(p As tTreeNode Ptr) As Integer
Dim As Integer ret = 1
If UBound(p->child) = -1 Then 'no subnodes --> don't traverse
Return ret
EndIf
For x As Integer = 0 To UBound(p->child) 'all subnodes
If p->child(x) <> 0 Then
ret += this.doTotal(p->child(x)) 'traverse subnode (recursive)
EndIf
Next
Return ret
End Function
Property tTreeNode.path() As String
Dim As String ret
Dim As tTreeNode Ptr p = @This
ret = p->fName
Do While p->parent <> 0
p = p->parent
ret = p->fName + "\" + ret
Loop
Return LTrim(ret, "\")
End Property
Declare Sub getFolderEntryList(p As tTreeNode Ptr)
Type tLISTBOX
As Integer x ' x position on screen
As Integer y ' y position on screen
As Integer w ' width in pixels
As Integer h ' height in pixels
As Integer start ' item to start printing from
As Integer index ' current item selected
As Integer itemcount ' current item number at traversing the tree list
As Integer totalitems ' current number of exposed items
As Integer mmkey ' key substitute for mouse menu
As Integer wheelrem ' reference value for mousewheel query
As boolean mouserem ' help variable for mouse use
As ULong bgcolor ' background color
As ULong framecolor ' frame color
As ULong focuscolor ' title bar color
As ULong nofocuscolor ' title bar color
As UByte display ' current view method (tree / list / image)
As String title ' title of list box
As String key ' pressed key
'static --> global to the tLISTBOX class
Static As tTreeNode Ptr rootNode 'pointer to root node of chained dirtree list
Static As tTreeNode Ptr selected 'pointer to the selected node
Static As tLISTBOX Ptr focus 'pointer of the listbox which has the keyboard focus
Static As String selfile 'selected file
Declare Property count As Integer ' number of shown items
Declare Property mouseInsideBox As boolean
Declare Sub show
Declare Sub printExposed(p As tTreeNode Ptr)
Declare Sub scrollBar
Declare Function alignLen(s As String) As String
End Type
Dim As tTreeNode Ptr tLISTBOX.rootNode
Dim As tTreeNode Ptr tLISTBOX.selected
Dim As tLISTBOX Ptr tLISTBOX.focus
Dim As String tLISTBOX.selfile
Sub tLISTBOX.show
Dim As Integer ret, x, ownChildIndex, childIndex, i, pline, ff, iw, ih, mmkey
Dim As Integer mx, my, wheel, buttons
Dim As tTreeNode Ptr pp, p(count) 'list of nodes to print
Dim As boolean subfolders
Dim As String deflateSign, attrString, g, itemName
Static As Double timerem
With This
'mousewheel stuff
GetMouse(mx, my, wheel, buttons)
If .mouseinsidebox Then
If .mouserem = FALSE Then 'mouse wasn't inside before --> actualize wheelrem
.wheelrem = wheel
.focus = @This 'set focus to the box
EndIf
If wheel > wheelrem Then 'scroll up (to the top of the list)
.key = Chr(255, 72)
wheelrem = wheel
ElseIf wheel < .wheelrem Then 'scroll down (to the bottom of the list)
.key = Chr(255, 80)
wheelrem = wheel
EndIf
EndIf
.mouserem = .mouseInsideBox
'clear list box area
Line (.x, .y - 24) - (.x + .w, .y + .h - 24), IIf(.focus = @This, .focuscolor, nofocuscolor), bf
Line (.x, .y - 24) - (.x + .w, .y + .h - 24), .framecolor, b
'print header details
Draw String (.x + 4, .y - 16), .title
Line (.x, .y) - (.x + .w, .y + .h), .bgcolor, bf
Line (.x, .y) - (.x + .w, .y + .h), .framecolor, b
Select Case display
Case treeview 'display the folder tree
.itemcount = 0
For x = 0 To UBound(.rootNode->child)
.printExposed(.rootNode->child(x))
Next
Select Case .key
Case Chr(255,72) 'scroll up (to the top of the list)
.index -= IIf(.index > 0, 1, 0)
If .index < .start Then 'reached the top of the displayed section --> shift list
.start -= 1
EndIf
Case Chr(255, 80) 'scroll down (to the bottom of the list)
.index += IIf(.index < (.totalitems - 1), 1, 0)
If .index >= .start + .count Then 'reached the bottom of the displayed section --> shift list
.start += 1
EndIf
End Select
.key = ""
.totalitems = .itemcount
.scrollbar
Case listview 'display files of the selected folder
If (.selected <> 0) AndAlso _
(UBound(.selected->child) >= 0) AndAlso _
(.selected->child(0) <> 0) Then 'at least one child
.itemcount = 0
.title = "FOLDERS OF " & .selfile
For x = 0 To UBound(.selected->child) 'all child nodes
Dim As tTreeNode Ptr sc = .selected->child(x) 'pointer to the actual child node
If (sc->attr And fbDirectory) = 0 Then 'child node represents a file
If (.itemcount >= .start) AndAlso (.itemcount < .start + .count) Then 'inside the window --> print file
If .index = .itemcount Then 'selected item --> try to write file contents to the image
selfile = sc->path
EndIf
pline = .y + (.itemcount - .start) * 16 + 4 'print line (in pixels)
Select Case mouseMenu(alignLen(sc->fName),"", _
.x + 65, pline, _
IIf(.index = .itemcount, mmcred, mmcblack))
Case 8 'cursor touching item
.index = .itemcount 'select current item
Case 9 'left click
If timerem < Timer Then
timerem = Timer + .4 'double click timer
Else
.key = Chr(13) 'open selected file
EndIf
End Select
EndIf
.itemcount += 1
EndIf
Next
.totalitems = .itemcount
.scrollbar
EndIf
Select Case .key
Case Chr(255,72) 'scroll up (to the top of the list)
.index -= IIf(.index > 0, 1, 0)
If .index < .start Then 'reached the top of the displayed section --> shift list
.start -= 1
EndIf
Case Chr(255, 80) 'scroll down (to the bottom of the list)
.index += IIf(.index < (.totalitems - 1), 1, 0)
If .index >= .start + .count Then 'reached the bottom of the displayed section --> shift list
.start += 1
EndIf
Case Chr(13)
Shell "start " & .selfile 'launch selected file
End Select
Case imageview 'display the contents image
ImageInfo wndImg, iw, ih 'get image size
Line wndImg, (0, 0) - (iw - 1, ih - 1), .bgcolor, bf 'clear image
Select Case LCase(Mid(.selfile, InStrRev(.selfile, "."))) 'file extension
Case ".bmp"
BLoad .selfile, wndImg
Case ".txt", ".bat", ".inf", ".lst", ".pif", ".hlp", ".bas", ".bi" 'text file
ff = FreeFile
Open .selfile For Input As #ff
For i As Integer = 1 To 30
Line Input #ff, g
Draw String wndImg, (0, 10 * i), g, black
If Eof(ff) Then
Exit For
EndIf
Next
Close ff
Case Else 'no display method
For x As Integer = 0 To 10 'draw cross
Dim As Integer clen = 50
Line wndImg, (iw/2 - clen + x, ih/2 - clen) - (iw/2 + clen + x, ih/2 + clen), black
Line wndImg, (iw/2 + clen + x, ih/2 - clen) - (iw/2 - clen + x, ih/2 + clen), black
Next
End Select
Line(.x, .y) - (.x + .w, .y + .h),white,
PUT (.x + 1, .y + 1), wndImg, PSet 'display image
End Select
.key = ""
End With
End Sub
Sub tLISTBOX.printExposed(p As tTreeNode Ptr)
Dim As tTreeNode Ptr pp = p->parent
Dim As Integer pline
Dim As String deflateSign
Dim As boolean noSubfolders = TRUE, toggledeflate
With This
If p = 0 Then
Return 'no node pointer --> error
EndIf
If (p->attr And fbDirectory) = 0 Then 'no folder
Return
EndIf
For x As Integer = 0 To UBound(p->child)
If (p->child(x) <> 0) AndAlso (p->child(x)->attr And fbDirectory) Then 'at least one subfolder
nosubfolders = FALSE
Exit For
EndIf
Next
If (.itemcount >= .start) And (.itemcount < .start + .count) Then 'print item
pline = .y + (.itemcount - .start) * 16 + 4 'print line (in pixels)
If noSubfolders Then
deflateSign = " "
Else
If p->deflate Then
deflateSign = "+ "
Else
deflateSign = "- "
EndIf
EndIf
Select Case mouseMenu(deflateSign + p->fName,"", _
.x + (p->depth * 16) , pline, _
IIf(.index = .itemcount, mmcred, mmcblack))
Case 0
If (.index = .itemcount) And (.key = Chr(13)) Then
toggledeflate = TRUE
.key = ""
EndIf
Case 8 'cursor touching item
If .mouseInsideBox Then
.index = .itemcount 'select the current item
.selected = p
EndIf
Case 9 'left click
toggledeflate = TRUE
End Select
If toggledeflate Then
p->deflate = IIf(p->deflate, FALSE, TRUE) 'toggle deflation flag
If p->deflate = FALSE Then
If nosubfolders = FALSE Then 'get entry list of all child nodes
For x As Integer = 0 To UBound(p->child)
getFolderEntryList(p->child(x))
Next
EndIf
EndIf
toggledeflate = FALSE
EndIf
EndIf
If .index = .itemcount Then
.selected = p
EndIf
.itemcount += 1
If (p->deflate) Then 'deflated --> don't continue, one level back
Return
EndIf
For x As Integer = 0 To UBound(p->child) 'traverse child nodes
If (p->child(x) <> 0) Then
.printExposed(p->child(x))
EndIf
Next
End With
End Sub
Property tLISTBOX.count As Integer
Return Int(this.h / 16)
End Property
Property tLISTBOX.mouseInsideBox As boolean
Dim As Integer mx, my, wheel, buttons
GetMouse(mx, my, wheel, buttons)
If (mx >= this.x) AndAlso (mx <= this.x + this.w) AndAlso _
(my >= this.y) AndAlso (my <= this.y + this.h) Then
Return TRUE
EndIf
Return FALSE
End Property
Sub tLISTBOX.scrollBar
Dim As boolean docount = TRUE
Dim As Integer x, item, begx, begy, endx, endy, lenframe, begbar, lenbar
With This
If .itemcount > .count Then 'draw scroll bar
begx = .x + .w - 20
begy = .y + 5
endx = .x + .w - 10
endy = .y + .h - 5
lenframe = endy - begy
lenbar = Int((lenframe /.totalitems) * (.count))
begbar = begy + Int((lenframe / .totalitems) * .start)
Line (begx, begy) - (endx, endy), black, b 'scroll frame
Line (begx, begbar) - (endx, begbar + lenbar), black, bf 'scroll bar
EndIf
End With
End Sub
Function tLISTBOX.alignLen(s As String) As String
Dim As String g = s
If Len(g) > Int(this.w / 8) - 5 Then
g = Left(s, Int(this.w / 8) - 25) & "..." & Right(s, 8)
EndIf
Return g
End Function
'##################################
Dim As tLISTBOX FOLDER_LIST, FILE_LIST, IMAGE_LIST
Dim As Integer x, i
Dim As String g, remselfile
Dim As tTreeNode Ptr tree = New tTreeNode 'create root node
'###################################
With FOLDER_LIST
.x = 8
.y = 64
.w = 8*48
.h = 16*20
.start = 0
.index = 0
.display = treeview
.title = "FOLDER VIEW"
.bgcolor = white
.framecolor = black
.focuscolor = green
.nofocuscolor = dkgreen
End With
With FILE_LIST
.x = 408
.y = 64
.w = 8*48
.h = 16*20
.start = 0
.index = 0
.display = listview
.title = "CONTENTS OF SELECTED FOLDER"
.bgcolor = white
.framecolor = black
.focuscolor = green
.nofocuscolor = dkgreen
End With
With IMAGE_LIST
.x = FOLDER_LIST.x
.y = FOLDER_LIST.y + FOLDER_LIST.h + 40
.w = 600
.h = 16*20
.start = 0
.index = 0
.display = imageview
.title = "CONTENTS OF SELECTED FOLDER"
.bgcolor = white
.framecolor = black
.focuscolor = green
.nofocuscolor = green
End With
wndImg = ImageCreate(IMAGE_LIST.w - 1, IMAGE_LIST.h - 1, white)
Sub getFolderEntryList(p As tTreeNode Ptr)
Dim As Integer i, x, y, out_attr, fileindex
Dim As String g, path
Dim As tTreeNode Ptr pp, ret '= Callocate(SizeOf(tTreeNode))
ReDim p->child(0) 'initialize child array
'get path
pp = p
Do
path = "\" + pp->fName + path
pp = pp->parent
Loop While Len(pp->fName)' <> 0
path = LTrim(path, "\")
g = Dir(path + "\*", -1, @out_attr) '1st dir entry
Do While Len(g) 'dir entry found
Select Case g
Case ".",".."
'ignore
Case Else
'message = "SCANNING " & g
ReDim Preserve p->child(x)
p->child(x) = New tTreeNode 'create new node
p->child(x)->parent = p
p->child(x)->depth = p->depth + 1
p->child(x)->fName = g 'subfolder name
p->child(x)->attr = out_attr
p->child(x)->deflate = TRUE
For y As Integer = x To 1 Step -1 'sort entries alphabetical
If LCase(p->child(y)->fName) < LCase(p->child(y - 1)->fName) Then
Swap p->child(y), p->child(y - 1)
Else
Exit For
EndIf
Next
x += 1
End Select
g = Dir("", -1, @out_attr) 'next entry
Loop
End Sub
'Open Cons For Output As #1
Sub deleteTree(p As tTreeNode Ptr)
If UBound(p->child) <> -1 Then 'no child nodes
For x As Integer = 0 To UBound(p->child) 'all child nodes
If p->child(x) <> 0 Then
deleteTree(p->child(x))
EndIf
Next
EndIf
Delete p
End Sub
'############################################################################################
'====== MAIN ================================================================================
Do
ChDir ".."
Loop While Len(CurDir) > 3
'create a list of all existing drives
'dirrem = CurDir 'save current directory
ReDim tree->child(0) 'initialize child array
For x = Asc("A") To Asc("Z") 'all possible drives
If ChDir(Chr(x) + ":") = 0 Then 'drive exists
ReDim Preserve tree->child(i)
tree->child(i) = New tTreeNode 'create new child node
tree->child(i)->parent = tree
tree->child(i)->depth = tree->child(i)->parent->depth + 1
tree->child(i)->fName = RTrim(CurDir, "\") 'write drive to list
tree->child(i)->attr = fbDirectory
tree->child(i)->deflate = TRUE
getFolderEntryList(tree->child(i))
i += 1
EndIf
Next
tLISTBOX.rootNode = tree
tLISTBOX.focus = @FOLDER_LIST
'ChDir dirrem 'restore current directory
With FOLDER_LIST
Do
Cls
If g = Chr(255, 75) Then 'cursor left
tLISTBOX.focus = @FOLDER_LIST
ElseIf g = Chr(255, 77) Then 'cursor right
tLISTBOX.focus = @FILE_LIST
Else 'send key to focused listbox
If tLISTBOX.focus = @FOLDER_LIST Then
FOLDER_LIST.key = g
ElseIf tLISTBOX.focus = @FILE_LIST Then
FILE_LIST.key = g
EndIf
EndIf
.show() 'display folder tree
FILE_LIST.show 'display file list (if any)
If tLISTBOX.selected <> 0 Then
IMAGE_LIST.title = "CONTENTS OF " & tLISTBOX.selfile
EndIf
IMAGE_LIST.show
If tLISTBOX.selected->path <> remselfile Then
FILE_LIST.index = 0
EndIf
remselfile = tLISTBOX.selected->path
ScreenCopy
Sleep 1
g = InKey
Loop Until g = Chr(27) Or g = Chr(255, 107)
End With
deleteTree(tree)
ImageDestroy wndImg
Mouse: Selecting an item by touching with the cursor, display/deflate folder with left click, open file with double click, scroll with mouse wheel.
Keyboard: cursor up/down to select item, cursor left/right to switch listbox, return to display/deflate respectively open the file.