Home Page

R. T. RUSSELL

BBC BASIC for Windows

Disk usage display



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 PROC
cleanup : 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%


Home - Products - Contact us

Best viewed with Any Browser Valid HTML 3.2!
© Richard Russell 2008