This program displays a tree view of the contents of drive C:, showing all the folders and the disk space they occupy (including sub-folders). Once the display is complete the contents of an individual folder can be listed and one or more files selected (the Ctrl and Shift keys can be used to allow multiple selections in the usual way). Pressing the Delete key causes the selected file(s) to be moved to the Recycle Bin or (if the Shift key is held down) permanently deleted.
Download DSKUSAGE.BBC | Run DSKUSAGE.EXE |
---|
REM. Disk usage display (Tree View) in BBC BASIC for Windows, RTR 17-Apr-2008
REM!Exefile C:\www\bbcwin\examples\dskusage.exe
*FLOAT 64
REM. Install libraries:
INSTALL @lib$+"WINLIB5"
REM. Program constants:
CX_BITMAP = 13
CY_BITMAP = 13
SPLIT = 2/3
ROOT$ = "C:"
REM. Windows constants:
TVM_INSERTITEM = &1100
TVM_SETIMAGELIST = &1109
TVM_GETNEXTITEM = &110A
TVM_GETITEM = &110C
TVM_SETITEM = &110D
TVS_HASBUTTONS = 1
TVS_HASLINES = 2
TVS_LINESATROOT = 4
TVS_SHOWSELALWAYS = &20
TVI_SORT = -&FFFD
TVIF_TEXT = 1
TVIF_IMAGE = 2
TVIF_PARAM = 4
TVIF_SELECTEDIMAGE = &20
TVIF_CHILDREN = &40
TVGN_PARENT = 3
TVGN_CARET = 9
LB_ADDSTRING = 384
LB_RESETCONTENT = 388
LB_GETSEL = 391
LB_GETTEXT = 393
LB_GETCOUNT = 395
LB_SETHORIZONTALEXTENT = 404
LB_GETITEMDATA = 409
LB_SETITEMDATA = 410
LBS_SORT = 2
LBS_NOINTEGRALHEIGHT = &100
LBS_EXTENDEDSEL = &800
WM_SETFONT = 48
WM_GETFONT = 49
WS_HSCROLL = &100000
WS_VSCROLL = &200000
WS_BORDER = &800000
FO_DELETE = 3
FOF_ALLOWUNDO = &40
REM. TV_INSERTSTRUCT
DIM tvi{hParent%, \
\ hInsertAfter%, \
\ mask%, \
\ hItem%, \
\ state%, \
\ stateMask%, \
\ pszText%, \
\ cchTextMax%, \
\ iImage%, \
\ iSelectedImage%,\
\ cChildren%, \
\ lParam% \
\ }
REM. SHFILEOPSTRUCT
DIM shfo{hwnd%, \
\ wFunc%, \
\ pFrom%, \
\ pTo%, \
\ fFlagl&, fFlagh&, \
\ fAnyOperationsAborted%, \
\ hNameMappings%, \
\ lpszProgressTitle% \
\ }
REM. WIN32_FIND_DATA
DIM wfd{dwFileAttributes%, \
\ ftCreationTime{l%,h%}, \
\ ftLastAccessTime{l%,h%}, \
\ ftLastWriteTime{l%,h%}, \
\ nFileSizeHigh%, \
\ nFileSizeLow%, \
\ dwReserved0%, \
\ dwReserved1%, \
\ cFileName&(259), \
\ cAlternate&(13) \
\ }
ON ERROR SYS "MessageBox", @hwnd%, REPORT$, 0, 48 : PROCcleanup : QUIT
ON CLOSE PROCcleanup : QUIT
REM. Get disk cluster size:
SYS "GetDiskFreeSpace", ROOT$+"\", ^spc%, ^bps%, ^nofc%, ^tnoc%
Cluster% = spc% * bps%
REM. Create tree view and list box controls:
SYS "InitCommonControls"
hTree% = FN_createwindow("SysTreeView32","",0,0,@vdu%!28*SPLIT,@vdu%!36,0,WS_BORDER OR TVS_HASLINES OR TVS_HASBUTTONS OR TVS_LINESATROOT OR TVS_SHOWSELALWAYS,0)
hList% = FN_listbox("",@vdu%!28*SPLIT,0,@vdu%!28*(1-SPLIT),@vdu%!36,1,WS_BORDER OR WS_HSCROLL OR WS_VSCROLL OR LBS_SORT OR LBS_NOINTEGRALHEIGHT OR LBS_EXTENDEDSEL)
REM. Use tree view font:
SYS "SendMessage", hTree%, WM_GETFONT, 0, 0 TO hfont%
SYS "SendMessage", hList%, WM_SETFONT, hfont%, 0
SYS "SelectObject", @memhdc%, hfont%
DIM Move%(2)
ON MOVE Move%() = @msg%, @wparam%, @lparam% : PROCmove(Move%()) : RETURN
REM. Set up image list:
SYS "ImageList_Create", CX_BITMAP, CY_BITMAP, 0, 1, 0 TO himl%
bmpfile$ = @dir$+"closed.bmp"
SYS "LoadImage", 0, bmpfile$, 0, CX_BITMAP, CY_BITMAP, &1010 TO hbmp%
IF hbmp% = 0 ERROR 100, "Cannot load file "+bmpfile$
SYS "ImageList_Add", himl%, hbmp%, 0
SYS "DeleteObject", hbmp%
SYS "SendMessage", hTree%, TVM_SETIMAGELIST, 0, himl%
REM. Display tree view:
SYS "SendMessage", hList%, LB_ADDSTRING, 0, "Working..."
totalsize = FNsize("",ROOT$,0)
REM. Display folder contents:
DIM text% 255, xy{x%,y%}
sel% = -1
REPEAT
SYS "SendMessage", hTree%, TVM_GETNEXTITEM, TVGN_CARET, 0 TO new%
IF new% <> sel% THEN
sel% = new%
SYS "SendMessage", hList%, LB_RESETCONTENT, 0, 0
path$ = ""
REPEAT
tvi.mask% = TVIF_TEXT OR TVIF_PARAM
tvi.hItem% = new%
tvi.pszText% = text%
tvi.cchTextMax% = 256
SYS "SendMessage", hTree%, TVM_GETITEM, 0, tvi{}+8
path$ = LEFT$($$text%, tvi.lParam%) + "\" + path$
SYS "SendMessage", hTree%, TVM_GETNEXTITEM, TVGN_PARENT, new% TO new%
UNTIL new% = 0
SYS "FindFirstFile", path$+"*", wfd{} TO sh%
IF sh% <> -1 THEN
hext% = 0
REPEAT
IF (wfd.dwFileAttributes% AND 16) = 0 THEN
size = 2^32*wfd.nFileSizeHigh% + 2*(wfd.nFileSizeLow% >>> 1) + \
\ (wfd.nFileSizeLow% AND 1)
name$ = wfd.cFileName&()
item$ = name$ + FNformat(size)
SYS "SendMessage", hList%, LB_ADDSTRING, 0, item$ TO index%
SYS "SendMessage", hList%, LB_SETITEMDATA, index%, LEN(name$)
SYS "GetTextExtentPoint32", @memhdc%, item$, LEN(item$), xy{}
IF xy.x% > hext% hext% = xy.x%
ENDIF
SYS "FindNextFile", sh%, wfd{} TO res%
UNTIL res% = 0
SYS "FindClose", sh%
SYS "SendMessage", hList%, LB_SETHORIZONTALEXTENT, hext%+4, 0
ENDIF
ENDIF
REM. If Del key pressed delete selected file(s):
SYS "GetForegroundWindow" TO hw%
IF (hw% = @hwnd%) IF INKEY(-90) THEN
name$ = ""
SYS "SendMessage", hList%, LB_GETCOUNT, 0, 0 TO index%
WHILE index%
index% -= 1
SYS "SendMessage", hList%, LB_GETSEL, index%, 0 TO res%
IF res% THEN
SYS "SendMessage", hList%, LB_GETITEMDATA, index%, 0 TO nlen%
SYS "SendMessage", hList%, LB_GETTEXT, index%, text%
name$ += path$ + LEFT$($$text%, nlen%) + CHR$0
ENDIF
ENDWHILE
IF name$ <> "" THEN
name$ += CHR$0
shfo.hwnd% = @hwnd%
shfo.wFunc% = FO_DELETE
shfo.pFrom% = !^name$
IF INKEY(-1) shfo.fFlagl& = 0 ELSE shfo.fFlagl& = FOF_ALLOWUNDO
SYS "SHFileOperation", shfo{}
IF shfo.fAnyOperationsAborted% = 0 sel% = -1
ENDIF
ENDIF
WAIT 1
UNTIL FALSE
REM. End of main
DEF PROCcleanup
hTree% += 0 : IF hTree% PROC_closewindow(hTree%)
hList% += 0 : IF hList% PROC_closewindow(hList%)
ENDPROC
DEF PROCmove(M%())
IF M%(0) = 5 SYS "MoveWindow", hTree%, 0, 0, (M%(2) AND &FFFF)*SPLIT, M%(2) >> 16, 1
IF M%(0) = 5 SYS "MoveWindow", hList%, (M%(2) AND &FFFF)*SPLIT, 0, (M%(2) AND &FFFF)*(1-SPLIT), M%(2) >> 16, 1
ENDPROC
REM. path$ = path to parent of folder
REM. name$ = name of folder whose size is wanted
REM. hparent% = handle to parent tree item
DEF FNsize(path$,name$,hparent%)
LOCAL sh%, res%, hnode%, size, temp$, children%, dir{}
DIM dir{} = wfd{}
temp$ = name$ + CHR$0
tvi.hParent% = hparent%
tvi.hInsertAfter% = TVI_SORT
tvi.mask% = TVIF_TEXT OR TVIF_IMAGE OR TVIF_SELECTEDIMAGE
tvi.pszText% = !^temp$
tvi.iImage% = 0
tvi.iSelectedImage% = 0
SYS "SendMessage", hTree%, TVM_INSERTITEM, 0, tvi{} TO hnode%
IF hnode% = 0 ERROR 100, "TVM_INSERTITEM failed"
SYS "InvalidateRect", hTree%, 0, 0
path$ += name$
IF RIGHT$(path$,1)<>"\" path$ += "\"
SYS "FindFirstFile", path$+"*", dir{} TO sh%
IF sh% <> -1 THEN
REPEAT
temp$ = dir.cFileName&()
IF (dir.dwFileAttributes% AND 16) IF temp$<>"." IF temp$<>".." THEN
size += FNsize(path$,temp$,hnode%)
children% OR= 1
ELSE
size += FNused(dir{})
ENDIF
SYS "FindNextFile", sh%, dir{} TO res%
UNTIL res% = 0
SYS "FindClose", sh%
ENDIF
temp$ = name$ + FNformat(size) + CHR$0
tvi.hItem% = hnode%
tvi.mask% = TVIF_TEXT OR TVIF_CHILDREN OR TVIF_PARAM
tvi.pszText% = !^temp$
tvi.cChildren% = children%
tvi.lParam% = LEN(name$)
SYS "SendMessage", hTree%, TVM_SETITEM, 0, tvi{}+8
= size
REM. Edit this routine to change size formatting
DEF FNformat(size)
LOCAL @%, I%, N$
@% = &1001010
N$ = STR$size
IF LEN(N$) >= 4 THEN
FOR I% = LEN(N$)-3 TO 1 STEP -3
N$ = LEFT$(N$,I%)+","+MID$(N$,I%+1)
NEXT
ENDIF
= " (" + N$ + ")"
DEF FNused(dir{})
LOCAL S
S = 2^32*dir.nFileSizeHigh% + 2*(dir.nFileSizeLow% >>> 1) + \
\ (dir.nFileSizeLow% AND 1)
= INT((S + Cluster% - 1) / Cluster%) * Cluster%