VERSION 2.00
Begin Form Child 
   Caption         =   "Form2"
   ClientHeight    =   3405
   ClientLeft      =   1935
   ClientTop       =   2565
   ClientWidth     =   4665
   Height          =   4335
   HelpContextID   =   17
   Icon            =   DISKPCHD.FRX:0000
   KeyPreview      =   -1  'True
   Left            =   1875
   LinkTopic       =   "Form2"
   MDIChild        =   -1  'True
   ScaleHeight     =   3405
   ScaleWidth      =   4665
   Top             =   1695
   Width           =   4785
   Begin CommonDialog CMDialog1 
      Left            =   4080
      Top             =   2160
   End
   Begin ListBox List2 
      Height          =   225
      Left            =   2640
      Sorted          =   -1  'True
      TabIndex        =   6
      Top             =   2520
      Visible         =   0   'False
      Width           =   1335
   End
   Begin ListBox List1 
      Height          =   225
      Left            =   2640
      Sorted          =   -1  'True
      TabIndex        =   5
      Top             =   2160
      Visible         =   0   'False
      Width           =   1335
   End
   Begin PictureBox Picture1 
      Height          =   375
      Left            =   120
      ScaleHeight     =   345
      ScaleWidth      =   2385
      TabIndex        =   3
      Top             =   120
      Visible         =   0   'False
      Width           =   2415
   End
   Begin GRAPH Graph1 
      AsciiFFamily    =   "1~1~1~1"
      AsciiFSize      =   "200~150~100~500"
      AsciiFStyle     =   "0~0~0~2"
      AutoInc         =   0  'Off
      DragIcon        =   DISKPCHD.FRX:0302
      GraphStyle      =   4
      GraphType       =   2  '3D Pie
      Height          =   2655
      Left            =   120
      NumPoints       =   2
      TabIndex        =   4
      Top             =   600
      Visible         =   0   'False
      Width           =   2415
   End
   Begin FileListBox File1 
      Height          =   420
      Left            =   2640
      TabIndex        =   2
      Top             =   2880
      Visible         =   0   'False
      Width           =   1935
   End
   Begin DirListBox Dir2 
      Height          =   480
      Left            =   2640
      TabIndex        =   1
      Top             =   1560
      Visible         =   0   'False
      Width           =   1935
   End
   Begin DirListBox Dir1 
      Height          =   480
      Left            =   2640
      TabIndex        =   0
      Top             =   960
      Visible         =   0   'False
      Width           =   1935
   End
   Begin Label Label1 
      BorderStyle     =   1  'Fixed Single
      Caption         =   "This control and the six controls below it are INVISIBLE."
      Height          =   735
      Left            =   2640
      TabIndex        =   7
      Top             =   120
      Visible         =   0   'False
      Width           =   1935
   End
   Begin Menu mnu_Main 
      Caption         =   "&File"
      HelpContextID   =   2
      Index           =   0
      Begin Menu mnu_File 
         Caption         =   "&Get Colors"
         HelpContextID   =   3
         Index           =   0
      End
      Begin Menu mnu_File 
         Caption         =   "-"
         Index           =   1
      End
      Begin Menu mnu_File 
         Caption         =   "&Print..."
         HelpContextID   =   4
         Index           =   2
      End
      Begin Menu mnu_File 
         Caption         =   "P&rint Setup..."
         HelpContextID   =   5
         Index           =   3
      End
      Begin Menu mnu_File 
         Caption         =   "-"
         Index           =   4
      End
      Begin Menu mnu_File 
         Caption         =   "E&xit"
         HelpContextID   =   21
         Index           =   5
      End
   End
   Begin Menu mnu_Main 
      Caption         =   "&Options"
      HelpContextID   =   6
      Index           =   1
      Begin Menu mnu_Options 
         Caption         =   "&Save Layout on Exit"
         HelpContextID   =   7
         Index           =   0
      End
      Begin Menu mnu_Options 
         Caption         =   "&Maximum Slices"
         HelpContextID   =   8
         Index           =   102
         Begin Menu mnu_Slice 
            Caption         =   "&5"
            HelpContextID   =   8
            Index           =   5
         End
         Begin Menu mnu_Slice 
            Caption         =   "&6"
            HelpContextID   =   8
            Index           =   6
         End
         Begin Menu mnu_Slice 
            Caption         =   "&7"
            HelpContextID   =   8
            Index           =   7
         End
         Begin Menu mnu_Slice 
            Caption         =   "&8"
            HelpContextID   =   8
            Index           =   8
         End
         Begin Menu mnu_Slice 
            Caption         =   "&9"
            HelpContextID   =   8
            Index           =   9
         End
         Begin Menu mnu_Slice 
            Caption         =   "1&0"
            HelpContextID   =   8
            Index           =   10
         End
         Begin Menu mnu_Slice 
            Caption         =   "1&1"
            HelpContextID   =   8
            Index           =   11
         End
         Begin Menu mnu_Slice 
            Caption         =   "1&2"
            HelpContextID   =   8
            Index           =   12
         End
         Begin Menu mnu_Slice 
            Caption         =   "1&3"
            HelpContextID   =   8
            Index           =   13
         End
         Begin Menu mnu_Slice 
            Caption         =   "1&4"
            HelpContextID   =   8
            Index           =   14
         End
      End
   End
   Begin Menu mnu_Main 
      Caption         =   "&Window"
      HelpContextID   =   9
      Index           =   2
      WindowList      =   -1  'True
      Begin Menu mnu_Window 
         Caption         =   "&Cascade"
         HelpContextID   =   10
         Index           =   0
      End
      Begin Menu mnu_Window 
         Caption         =   "&Tile"
         HelpContextID   =   11
         Index           =   1
      End
      Begin Menu mnu_Window 
         Caption         =   "&Arrange Icons"
         HelpContextID   =   12
         Index           =   2
      End
      Begin Menu mnu_Window 
         Caption         =   "-"
         Index           =   3
      End
      Begin Menu mnu_Window 
         Caption         =   "New &Dir Window"
         HelpContextID   =   13
         Index           =   4
      End
      Begin Menu mnu_Window 
         Caption         =   "New &Ext Window"
         HelpContextID   =   14
         Index           =   5
      End
      Begin Menu mnu_Window 
         Caption         =   "&Refresh Active Window"
         HelpContextID   =   15
         Index           =   6
      End
      Begin Menu mnu_Window 
         Caption         =   "&Balance Slices"
         HelpContextID   =   22
         Index           =   7
      End
   End
   Begin Menu mnu_Main 
      Caption         =   "&Help"
      HelpContextID   =   16
      Index           =   3
      Begin Menu mnu_Help 
         Caption         =   "&Contents"
         HelpContextID   =   16
         Index           =   0
      End
      Begin Menu mnu_Help 
         Caption         =   "&Search for Help On..."
         HelpContextID   =   16
         Index           =   1
      End
      Begin Menu mnu_Help 
         Caption         =   "&How to Use Help"
         HelpContextID   =   16
         Index           =   2
      End
      Begin Menu mnu_Help 
         Caption         =   "-"
         Index           =   3
      End
      Begin Menu mnu_Help 
         Caption         =   "&About Disk Pie..."
         HelpContextID   =   16
         Index           =   4
      End
   End
End
Option Explicit
' The variables defined below exist separately for EACH instance of the
' child window form.

' Typ is "T" for Tree pie, "E" for Extension pie
Dim Typ As String * 1

' SliceShown is initially -1.  After a pie slice has been clicked or
' space bar has been pressed, it identifies the slice whose detailed
' data is shown on the status bar.
Dim SliceShown%

' GraphReady helps the program avoid trying to USE the graph before
' it has been completely created.
Dim GraphReady%

' Breakout is true when the user breaks out of the scan process
Dim Breakout%

' GrandTotal is the total size of all slices
Dim GrandTotal!

' Balanced is true if slice size is balanced for best viewing,
' false if slices are sorted largest to smallest
Dim Balanced%

' Each instance of the Child form makes its own copy of the global
' variable Dir2Use.
Dim LocalDir2Use$

Sub BalanceGraph ()
  ' Purpose - to "balance" the graph so the smallest slices are on the
  ' right and left, rather than piled up at the top where their labels
  ' overlap.
  Balanced = True
  SliceShown = -1
  MdiForm1.Shape1.FillColor = &HFFFFFF
  MdiForm1.Label1.Caption = ""
  If Graph1.NumPoints < 3 Then Exit Sub
  Dim N%, Max%
  Max = Graph1.NumPoints
  Graph1.ThisPoint = 1
  ' If the biggest slice is more than half the pie, simply move the
  ' next-biggest slice to the last position.  This will push the
  ' smallest slices toward the 3-o'clock position.
  If Graph1.GraphData / GrandTotal > .5 Then
    Dim DataMax!, LgndMax$, Data2!, Lgnd2$
    ' Store data and legend for slice Max
    Graph1.ThisPoint = Max
    DataMax = Graph1.GraphData
    LgndMax = Graph1.LegendText
    ' Store data and legend for slice N
    Graph1.ThisPoint = 2
    Data2 = Graph1.GraphData
    Lgnd2 = Graph1.LegendText
    ' Set data and legend for slice N to values stored for M
    Graph1.GraphData = DataMax
    Graph1.LegendText = LgndMax
    ' Set data and legend for slice M to values stored for N
    Graph1.ThisPoint = Max
    Graph1.GraphData = Data2
    Graph1.LegendText = Lgnd2
    For N = 1 To Max
      Graph1.ThisPoint = N
      Graph1.ColorData = N
    Next N
    Exit Sub
  End If
  ' If the biggest slice is less than half the pie, attempt to balance
  ' the pie.  Start with the next-biggest slice and add slices to the
  ' right or left of 12-o'clock, always adding to the side that
  ' currently has less.  Put the biggest slice in the remaining space.
  ' With luck, the biggest slice will cross 6-o'clock, and the
  ' smallest will cluster around 3-o'clock and 9-o'clock.
  ReDim NewData(1 To Graph1.NumPoints) As Single
  ReDim NewLgnd(1 To Graph1.NumPoints) As String
  Dim LIndex%, RIndex%, LTotal!, RTotal!, LeftLast%
  LIndex = 1
  RIndex = Max
  LTotal = 0
  RTotal = 0
  LeftLast = False
  For N = 2 To Max
    Graph1.ThisPoint = N
    If LTotal < RTotal Then
      NewData(LIndex) = Graph1.GraphData
      LTotal = LTotal + Graph1.GraphData
      NewLgnd(LIndex) = Graph1.LegendText
      LIndex = LIndex + 1
      LeftLast = True
    Else
      NewData(RIndex) = Graph1.GraphData
      RTotal = RTotal + Graph1.GraphData
      NewLgnd(RIndex) = Graph1.LegendText
      RIndex = RIndex - 1
      LeftLast = False
    End If
  Next N
  Graph1.ThisPoint = 1
  Dim M%
  M = RIndex
  If LeftLast Then M = LIndex
  NewData(M) = Graph1.GraphData
  NewLgnd(M) = Graph1.LegendText
  For N = 1 To Max
    Graph1.ThisPoint = N
    Graph1.GraphData = NewData(N)
    Graph1.LegendText = NewLgnd(N)
    Graph1.ColorData = N
  Next N
End Sub

Sub EliminateZeros ()
  ' Slices of zero size are pointless, so we strip 'em off.  This
  ' routine is always called while the graph is SORTED, so any zero
  ' size slices will be at the end.  Thus all we need do is decrement
  ' Graph1.NumPoints to get rid of a zero size slice.
  Dim N%
  For N = Graph1.NumPoints To 1 Step -1
    Graph1.ThisPoint = N
    If (Graph1.GraphData = 0) And (Graph1.NumPoints > 2) Then
      Graph1.NumPoints = Graph1.NumPoints - 1
    End If
  Next N
End Sub

Sub Form_Activate ()
  ' When a child form is activated, if it was previously displaying
  ' slice info in the status bar, redisplay that data now.
  If Not GraphReady Then Exit Sub
  If WindowState = MINIMIZED Then Exit Sub
  If SliceShown = -1 Then
    MdiForm1.Shape1.FillColor = &HFFFFFF
    MdiForm1.Label1.Caption = ""
  Else
    Graph1.ThisPoint = SliceShown + 1
    MdiForm1.Shape1.FillColor = SliceColors(Graph1.ColorData)
    MdiForm1.Label1.Caption = ReportString()
  End If
End Sub

Sub Form_KeyPress (KeyAscii As Integer)
  ' If the user presses space bar, select each slice in turn to show
  ' in the status bar.  If the user presses Enter in a Directory pie
  ' generate a new pie from the selected slice.
  If Not GraphReady Then Exit Sub
  If KeyAscii = KEY_SPACE Then
    SliceShown = (SliceShown + 1) Mod Graph1.NumPoints
    Graph1.ThisPoint = SliceShown + 1
    ' Handle one-slice pies
    If Graph1.LegendText = "" Then
      SliceShown = SliceShown - 1
    Else
      MdiForm1.Label1.Caption = ReportString()
      MdiForm1.Shape1.FillColor = SliceColors(Graph1.ColorData)
    End If
  ElseIf KeyAscii = KEY_RETURN Then
    If SliceShown = -1 Then Exit Sub
    If Typ = "E" Then Exit Sub
    Graph1.ThisPoint = SliceShown + 1
    If Graph1.LegendText = "OTHER" Then Exit Sub
    If Left$(Graph1.LegendText, 1) = "[" Then Exit Sub
    Dir2Use = "T" + Graph1.LegendText
    NewPie
  End If
End Sub

Sub Form_Load ()
  LocalDir2Use = Dir2Use
  Screen.MousePointer = HOURGLASS
  ' In case this is the first child form, synch the child form menu
  ' with the main menu.
  mnu_Slice(NumSlices).Checked = True
  mnu_Options(0).Checked = SaveSettings
  SliceShown = -1
  NumOpenWindows = NumOpenWindows + 1
  MdiForm1.Shape1.FillColor = &HFFFFFF
  GraphReady = False
  Breakout = False
  ' Initialize the child form in one of four ways.
  If LocalDir2Use = "GETCOLORS" Then
    LoadGetColors
  Else
    If InStr("012345678", LocalDir2Use) > 0 Then
      LoadFromINI
    Else
      Typ = Left$(LocalDir2Use, 1)
      LocalDir2Use = Mid$(LocalDir2Use, 2)
      If Typ = "T" Then
        LoadDirData
      Else
        Icon = Graph1.DragIcon
        HelpContextID = 18
        LoadExtData
      End If
    End If
  End If
  MdiForm1.Label1.Caption = ""
  DoEvents
  Screen.MousePointer = DEFAULT
  LocalDir2Use = ""
  If Breakout Then Exit Sub

  GraphReady = True
  ' If the window was created correctly, have the Graph draw itself,
  ' then copy the resulting picture to the picture box
  If (Caption <> "ERROR") And (Caption <> "Get Colors") Then
    Picture1.Visible = True
    Refresh
  End If
End Sub

Sub Form_Paint ()
  ' Redraw the graph, and copy the graph to the picture.
  If GraphReady Then
    Graph1.DrawMode = G_DRAW
    Picture1 = Graph1.Picture
  End If
End Sub

Sub Form_QueryUnload (Cancel As Integer, UnloadMode As Integer)
  NumOpenWindows = NumOpenWindows - 1
  ' Don't try to unload the child if it's not even done getting loaded
  If Not GraphReady Then
    'Cancel = True
    Breakout = True
    Exit Sub
  End If
  ' If this is simply one child window closing, clear the status bar.
  ' The child window that gets activated next will put its own info
  ' into the status bar.  If this was the last child window, the
  ' status bar will remain empty.
  If UnloadMode = FORM_CONTROLMENU Then
    MdiForm1.Label1.Caption = ""
    MdiForm1.Shape1.FillColor = &HFFFFFF
  End If
  If UnloadMode <> FORM_MDIFORM Then Exit Sub
  ' The QueryUnload method of each child is called *after* the
  ' QueryUnload of the main MDI form.  The main form's QueryUnload
  ' method erases any [Window n] sections from the INI file.
  If SaveSettings Then
    Dim Sec$, Success%, N%
    Sec = "Window" + Str$(NextWindow)
    NextWindow = NextWindow + 1
    Success = WPPS(Sec, "Type", Typ)
    Success = WPPS(Sec, "Dir", Mid$(Caption, InStr(Caption, ":") + 2))
    GraphReady = False ' Don't bother re-drawing the graph NOW!
    If WindowState = MAXIMIZED Then WindowState = NORMAL
    Success = WPPS(Sec, "State", WindowState)
    WindowState = NORMAL
    Success = WPPS(Sec, "Left", Format$(Left))
    Success = WPPS(Sec, "Top", Format$(Top))
    Success = WPPS(Sec, "Width", Format$(Width))
    Success = WPPS(Sec, "Height", Format$(Height))
    Success = WPPS(Sec, "Slices", Graph1.NumPoints)
    Success = WPPS(Sec, "Balanced", Format$(Balanced))
    For N = 1 To Graph1.NumPoints
      Graph1.ThisPoint = N
      Success = WPPS(Sec, "Data" + Str$(N), Format$(Graph1.GraphData))
      Success = WPPS(Sec, "Legend" + Str$(N), Graph1.LegendText)
    Next N
  End If
End Sub

Sub Form_Resize ()
  ' If the form is becoming iconized, clear the status bar
  If WindowState = MINIMIZED Then
    MdiForm1.Shape1.FillColor = &HFFFFFF
    MdiForm1.Label1.Caption = ""
  Else
    ' Otherwise, fit the graph and the picture to the new size.
    Graph1.Move 0, 0, ScaleWidth, ScaleHeight
    Picture1.Move 0, 0, ScaleWidth, ScaleHeight
  End If
End Sub

Sub GetExtensionData (ByVal DirName$)
  ' Recursive function, sums the sizes for the various file extensions
  ' in the current directory, then calls itself for each subdir.
  Dim TotalSize!, OneSize!, N%, DirCombine$, Temp$
  DoEvents
  If Breakout Then Exit Sub
  Temp = "Scanning " + DirName + ". "
  Temp = Temp + Str$(List1.ListCount) + " extensions found."
  MdiForm1.Label1.Caption = Temp
  DoEvents
  TotalSize = 0
  If Right$(DirName, 1) = "\" Then
    DirCombine = DirName
  Else
    DirCombine = DirName + "\"
  End If
  File1.Path = DirName
  File1.Pattern = "*.*"
  File1.Refresh
  ' File List box File1 contains a list of all files in current dir
  Dim Posn%, Locn%, Ext$, OneSiz!, TotalSiz!
  If File1.ListCount > 0 Then
    For N = 0 To File1.ListCount - 1
      Posn = InStr(File1.List(N), ".")
      If Posn = 0 Then
        Ext = "   ."
      Else
        Ext = Left$(Mid$(File1.List(N), Posn + 1) + "   ", 3) + "."
      End If
      OneSiz = FileLen(DirCombine + File1.List(N))
      Locn = LocationOf(Ext, List1)
      If Locn = -1 Then
        List1.AddItem Ext + Format$(OneSiz, "0000000000")
      Else
        TotalSiz = Val(Right$(List1.List(Locn), 10))
        TotalSiz = TotalSiz + OneSiz
        List1.RemoveItem (Locn)
        List1.AddItem Ext + Format$(TotalSiz, "0000000000")
      End If
    Next N
  End If
  Dir2.Path = DirName
  Dir2.Refresh
  ' Directory list box Dir2 now contains a list of subdirectories.
  If Dir2.ListCount > 0 Then
    ' Copy the subdirectory list to a local array, because other
    ' instances of this recursive procedure will re-use Dir2
    Dim Dirs$()
    ReDim Dirs$(Dir2.ListCount - 1)
    For N = 0 To Dir2.ListCount - 1
      Dirs(N) = Dir2.List(N)
    Next N
    For N = 0 To UBound(Dirs)
      GetExtensionData (Dirs(N))
    Next N
  End If
End Sub

Sub LoadDirData ()
  ' This function is called to initialize a new child window with
  ' Directory pie information.
  Dim N%, M%, Slices%
  Caption = "TREE: " + LocalDir2Use
  Show
  On Error GoTo BadPathDir
  Dir1.Path = LocalDir2Use
  On Error GoTo 0
  ' Add 1 to slices for "base" directory
  Slices = Dir1.ListCount + 1
  If Slices < 2 Then
    ' If there would be < 2 slices, switch to an extension pie
    Typ = "E"
    Icon = Graph1.DragIcon
    LoadExtData
    Exit Sub
  Else
    GrandTotal = 0
    Graph1.ThisSet = 1
    Graph1.NumPoints = Slices
    ' Store data for each subdirectory right in Graph1.  Note that
    ' Graph1 may well come to hold many more slices than specified
    ' by the NumSlices variable.
    Dim Siz&
    For N = 0 To Dir1.ListCount - 1
      Graph1.ThisPoint = N + 1
      Siz = SizeOfFiles(Dir1.List(N), True)
      DoEvents
      If Breakout Then Exit Sub
      Graph1.GraphData = Siz
      GrandTotal = GrandTotal + Siz
      Graph1.LegendText = Dir1.List(N)
    Next N
    ' Insert a slice for the base directory
    Graph1.ThisPoint = Slices
    Siz = SizeOfFiles(LocalDir2Use, False)
    Graph1.GraphData = Siz
    GrandTotal = GrandTotal + Siz
    Graph1.LegendText = "[" + LocalDir2Use + "]"
  End If
  If GrandTotal = 0 Then
    Msg = "There are no files in or below " + LocalDir2Use
    MsgType = MB_ICONSTOP
    MsgBox Msg, MsgType, MsgTitle
    Caption = "ERROR"
    Exit Sub
  End If
  MdiForm1.Label1.Caption = "Sorting..."
  SortDirData
  EliminateZeros
  ' If there are too many slices, merge smallest ones into "OTHER"
  If Graph1.NumPoints > NumSlices Then
    Dim OtherSiz!
    OtherSiz = 0
    For N = NumSlices To Graph1.NumPoints
      Graph1.ThisPoint = N
      OtherSiz = OtherSiz + Graph1.GraphData
    Next N
    Graph1.NumPoints = NumSlices
    Graph1.ThisPoint = NumSlices
    Graph1.GraphData = OtherSiz
    Graph1.LegendText = "OTHER"
  End If

  ' Give each slice the color of its slice number, so DiskPie can
  ' identify slices by grabbing the color of a pixel.
  For N = 1 To Graph1.NumPoints
    Graph1.ThisPoint = N
    Graph1.ColorData = N
  Next N
  Exit Sub
  ' Error handling code follows, in case this subroutine received an
  ' invalid directory.
BadPathDir:
  Caption = "ERROR"
  Msg = LocalDir2Use + " is not a valid path."
  MsgType = MB_ICONSTOP
  MsgBox Msg, MsgType, MsgTitle
  Exit Sub
End Sub

Sub LoadExtData ()
  ' This function is called to initialize a new child window with
  ' Extension pie information.
  Dim N%, M%, Slices%, Temp$
  Caption = "EXT: " + LocalDir2Use
  Show
  Temp = "Scanning " + LocalDir2Use + ".  0 extensions found."
  MdiForm1.Label1.Caption = Temp
  List1.Clear
  On Error GoTo BadPathExt
  File1.Path = LocalDir2Use
  File1.Refresh
  On Error GoTo 0
  GetExtensionData (LocalDir2Use)
  DoEvents
  If Breakout Then Exit Sub
  Slices = List1.ListCount
  If Slices > NumSlices Then Slices = NumSlices
  If Slices < 2 Then Slices = 2
  GrandTotal = 0
  Graph1.ThisSet = 1
  Graph1.NumPoints = Slices
  MdiForm1.Label1.Caption = "Sorting..."
  ' Sort the data simply by copying it to List2 with the size FIRST
  List2.Clear
  Dim TheLine$
  For N = 0 To List1.ListCount - 1
    TheLine = List1.List(N)
    List2.AddItem Right$(TheLine, 10) + Left$(TheLine, 4)
  Next N
  ' Put the biggest items into the graph
  For N = 1 To Slices
    Graph1.ThisPoint = N
    Graph1.ColorData = N
    TheLine = List2.List(List2.ListCount - N)
    Graph1.GraphData = Val(Left$(TheLine, 10))
    GrandTotal = GrandTotal + Graph1.GraphData
    Graph1.LegendText = Mid$(TheLine, 11, 3)
  Next N
  ' Add the remaining items to the "OTHER" slice
  Dim OneData!
  If List2.ListCount > NumSlices Then
    Graph1.LegendText = "OTHER"
    For N = 0 To List2.ListCount - (Slices + 1)
      TheLine = List2.List(N)
      OneData = Val(Left$(TheLine, 10))
      Graph1.GraphData = Graph1.GraphData + OneData
      GrandTotal = GrandTotal + OneData
    Next N
  End If
  If GrandTotal = 0 Then
    Msg = "There are no files in or below " + LocalDir2Use
    MsgType = MB_ICONSTOP
    MsgBox Msg, MsgType, MsgTitle
    Caption = "ERROR"
    Exit Sub
  End If
  EliminateZeros
  Exit Sub
  ' Error handling code follows, in case this subroutine received an
  ' invalid directory.
BadPathExt:
  Caption = "ERROR"
  Msg = LocalDir2Use + " is not a valid path."
  MsgType = MB_ICONSTOP
  MsgBox Msg, MsgType, MsgTitle
  Exit Sub
End Sub

Sub LoadFromINI ()
  ' Load a pie window from information saved in DISKPIE.INI
  Dim Sec$, N%, Success%, Temp$, Slices%
  Sec$ = "Window " + LocalDir2Use
  Success = GPPS(Sec$, "Type", "T", Typ, 1)
  Success = GPPS(Sec$, "Dir", "ERROR", Temp, 144)
  If Typ = "T" Then
    Caption = "TREE: " + Temp
  Else
    Caption = "EXT: " + Temp
    Icon = Graph1.DragIcon
    HelpContextID = 18
  End If
  DoEvents
  Temp = "Loading " + Caption + " from INI file ..."
  MdiForm1.Label1.Caption = Temp
  DoEvents
  ' Start with the window in a normal state, to set the coords
  WindowState = NORMAL
  Dim xLeft%, xTop%, xWid%, xHig%
  xLeft = GPPI(Sec$, "Left", 0)
  xTop = GPPI(Sec$, "Top", 0)
  xWid = GPPI(Sec$, "Width", 1000) 'MdiForm1.ScaleWidth)
  xHig = GPPI(Sec$, "Height", 1000) 'MdiForm1.ScaleHeight)
  Move xLeft, xTop, xWid, xHig
  WindowState = GPPI(Sec$, "State", NORMAL)
  GrandTotal = 0
  Graph1.NumPoints = GPPI(Sec$, "Slices", NumSlices)
  Balanced = GPPI(Sec, "Balanced", False)
  If Balanced Then
    mnu_Window(7).Caption = "&Sort Slices"
  End If
  Dim Key$
  For N = 1 To Graph1.NumPoints
    Graph1.ThisPoint = N
    Graph1.ColorData = N
    Key = "Data" + Str$(N)
    ' Can't use GetPrivateProfileInt, because the stored values may
    ' well be too LARGE for an Integer.
    Success = GPPS(Sec, Key, "-1", Temp, 12)
    Graph1.GraphData = Val(Temp)
    GrandTotal = GrandTotal + Graph1.GraphData
    Key = "Legend" + Str$(N)
    Success = GPPS(Sec, Key, "ERROR", Temp, 144)
    Graph1.LegendText = Temp
  Next N
End Sub

Sub LoadGetColors ()
  ' Load a child form that will be used just to get the colors of the
  ' pie slices.
  Dim N%, WasState
  MdiForm1!Label1.Caption = "GETTING COLOR VALUES..."
  Caption = "Get Colors"
  ' Draw a graph with 14 slices, each colors with the graph color of
  ' its number.  Do not use 0 (black) or 15 (white).  Make it a 2D
  ' pie chart, so the center of the pie will be IN the center of
  ' the graph.
  Graph1.NumPoints = 14
  Graph1.GraphType = 1
  Graph1.GraphStyle = 0
  For N = 1 To 14
    Graph1.ThisPoint = N
    Graph1.GraphData = 1
    Graph1.ColorData = N
    Graph1.LabelText = "Slice #" + Format$(N)
  Next N
  Show
  Graph1.DrawMode = G_DRAW
  Picture1.Visible = True
  Picture1 = Graph1.Picture
  Dim X!, Y!, Angle!, Radius!
  ' (X,Y) is the center of the graph.
  X = Picture1.ScaleWidth / 2
  Y = Picture1.ScaleHeight / 2
  Radius = X / 3
  If Radius > Y / 3 Then Radius = Y / 3
  ' Find a point in each of the equal-size sectors and get its color.
  ' Start at straight up, which is -(pi/2).  For the Nth slice go
  ' counter clockwise N 14ths of the distance.  Then go halfway into
  ' the slice (pi / 14).  Use a radius 1/6 the height of the graph
  ' or 1/6 the width, whichever is smaller.
  Dim TotalSuccess%, vX%, vY%, Key$, Valu$
  TotalSuccess = True
  For N = 0 To 13
    Angle = -(pi / 2) - ((((2 * pi) * N) / 14) + (pi / 14))
    vX = X + Cos(Angle) * Radius
    vY = Y + Sin(Angle) * Radius
    SliceColors(N + 1) = Picture1.Point(vX, vY)
    If SliceColors(N + 1) = -1 Then
      TotalSuccess = False
    Else
      Key = "Color" + Str$(N + 1)
      Valu = Right$("00000000" + Hex$(SliceColors(N + 1)), 6)
      If WPPS("Settings", Key, Valu) = 0 Then TotalSuccess = False
    End If
  Next N
  If Not TotalSuccess Then
    Msg = "Failed to record the values of all graph colors 1-14. "
    Msg = Msg + "Examine the 'Color n=' keys in the [Settings] "
    Msg = Msg + "section of DISKPIE.INI."
    MsgType = MB_ICONSTOP
    MsgBox Msg, MsgType, MsgTitle
  End If
End Sub

Function LocationOf% (ByVal Ext$, L As ListBox)
  ' This is a binary search routine for locating a particular extension
  ' in the sorted list box List1.  It returns -1 if the extension
  ' is not found, or the position within the list if found.
  Dim Top%, Bot%, Midl%, Found%
  If L.ListCount = 0 Then
    LocationOf = -1
  Else
    Top = L.ListCount - 1
    Bot = 0
    Midl = (Top + Bot) \ 2
    Found = False
    Do While (Not Found) And (Top >= Bot)
      Select Case StrComp(Ext, Left$(List1.List(Midl), 4), 1)
        Case Is < 0
          ' Desired location is in bottom half of range.  Set top to
          ' one less than current middle.
          Top = Midl - 1
        Case 0
          Found = True
        Case Is > 0
          ' Desired location is in top half of range.  Set bottom to
          ' one more than current middle.
          Bot = Midl + 1
      End Select
      Midl = (Top + Bot) \ 2
    Loop
    If Not Found Then
      LocationOf = -1
    Else
      LocationOf = Midl
    End If
  End If
End Function

Sub mnu_File_Click (Index As Integer)
  If Not GraphReady Then Exit Sub
  Select Case Index
    Case 0
      Dir2Use = "GETCOLORS"
      NewPie
    Case 2
      PrepareAndPrint
    Case 3
      CmDialog1.Flags = PD_PRINTSETUP
      CmDialog1.Action = DLG_PRINT
    Case 5
      Unload MdiForm1
  End Select
End Sub

Sub mnu_Help_Click (Index As Integer)
  ' The Mdi form and the child form have nearly identical menus.  Both
  ' rely on functions in DISKPIE.BAS to process many of them.
  Share_Help_Click (Index)
End Sub

Sub mnu_Options_Click (Index As Integer)
  Select Case Index
    Case 0
      mnu_Options(0).Checked = Not mnu_Options(0).Checked
      SaveSettings = mnu_Options(0).Checked
      ' Synchronize the main form's menu with this change
      MdiForm1.mnu_Options(0).Checked = SaveSettings
  End Select
End Sub

Sub mnu_Slice_Click (Index As Integer)
  ' Keep the main form menu and the child form menu in synch
  If Index <> NumSlices Then
    mnu_Slice(NumSlices).Checked = False
    MdiForm1.mnu_Slice(NumSlices).Checked = False
    NumSlices = Index
    mnu_Slice(NumSlices).Checked = True
    MdiForm1.mnu_Slice(NumSlices).Checked = True
  End If
End Sub

Sub mnu_Window_Click (Index As Integer)
  If Not GraphReady Then Exit Sub
  Select Case Index
    Case 0
      MdiForm1.Arrange CASCADE
    Case 1
      MdiForm1.Arrange TILE_HORIZONTAL
    Case 2
      MdiForm1.Arrange ARRANGE_ICONS
    Case 4, 5
      ' These two options are available even when no child window open.
      Share_Window_Click (Index)
    Case 6
      Dir2Use = MdiForm1.ActiveForm.Caption
      Dim Posn%
      Posn = InStr(Dir2Use, ":")
      If Posn > 0 Then
        Dir2Use = Left$(Dir2Use, 1) + Mid$(Dir2Use, Posn + 2)
        Unload MdiForm1.ActiveForm
        NewPie
      End If
    Case 7
      If Balanced Then
        SortDirData
        mnu_Window(7).Caption = "&Balance Slices"
      Else
        BalanceGraph
        mnu_Window(7).Caption = "&Sort Slices"
      End If
      Refresh
  End Select
End Sub

Sub Picture1_DblClick ()
  If Not GraphReady Then Exit Sub
  ' If this isn't a directory pie, exit immediately.
  If Typ = "E" Then Exit Sub
  If SliceShown > -1 Then
    Graph1.ThisPoint = SliceShown + 1
    If Graph1.LegendText = "OTHER" Then Exit Sub
    If Left$(Graph1.LegendText, 1) = "[" Then Exit Sub
    Dir2Use = "T" + Graph1.LegendText
    NewPie
  End If
End Sub

Sub Picture1_MouseUp (Button As Integer, Shift As Integer, X As Single, Y As Single)
  ' If the user clicks the mouse, get the color of the pixel at the
  ' mouse pointer.  If it matches one of the recorded slice colors,
  ' select that slice and display its data in the status bar.  If it
  ' does not match and is not either white or black, warn the user
  ' to re-calibrate the colors.
  If Not GraphReady Then Exit Sub
  Dim Color&, N%, Found%
  Color = Picture1.Point(X, Y)
  Found = False
  SliceShown = -1
  For N = 1 To 14
    If Color = SliceColors(N) Then
      Graph1.ThisPoint = N
      SliceShown = N - 1
      Found = True
    End If
  Next N
  If Found Then
    MdiForm1.Label1.Caption = ReportString()
    MdiForm1.Shape1.FillColor = Color
  End If
End Sub

Sub PrepareAndPrint ()
  ' Before printing, change the graph for better printed output
  Dim N%, Temp$, G As Graph, GT!
  Set G = Graph1
  GT = GrandTotal
  ' Change labels to index numbers.  Prefix legend text with index
  ' number and add total size and percent data to it.
  For N = 1 To G.NumPoints
    G.ThisPoint = N
    G.LabelText = Format$(N, "#0\. ")
    Temp = G.LabelText + G.LegendText + " ["
    Temp = Temp + Format$(G.GraphData, "#,###,###,##0") + " bytes, "
    Temp = Temp + Format$(G.GraphData / GT, "#0.0%]")
    G.LegendText = Temp
  Next N
  ' Create titles for the output report
  G.GraphTitle = "DISKPIE Disk Space Usage Report"
  G.BottomTitle = MdiForm1.ActiveForm.Caption
  ' Switch to a 2D pie, because it prints better
  G.GraphType = G_PIE2D
  ' Make the labels bigger and bolder
  G.FontUse = 2 ' labels
  G.FontSize = 200
  G.FontStyle = 2 ' bold
  ' Save the child and main window states and maximize both
  Dim CS%, MS%
  CS = WindowState
  MS = MdiForm1.WindowState
  ' Don't SHOW the changes
  GraphReady = False
  Picture1.Visible = False
  WindowState = MAXIMIZED
  MdiForm1.WindowState = MAXIMIZED
  ' PRINT IT!
  G.DrawMode = G_PRINT

  ' Now UNDO all the changes
  G.FontUse = 2 ' labels
  G.FontSize = 100
  G.FontStyle = 0 ' default
  G.BottomTitle = ""
  G.GraphTitle = ""
  G.GraphType = G_PIE3D
  G.DataReset = G_LABEL_TEXT
  For N = 1 To G.NumPoints
    G.ThisPoint = N
    Temp = G.LegendText
    Temp = Left$(Temp, InStr(7, Temp, "[") - 2)
    Temp = Mid$(Temp, InStr(Temp, ".") + 2)
    G.LegendText = Temp
  Next N
  MdiForm1.WindowState = MS
  WindowState = CS
  GraphReady = True
  Picture1.Visible = True
  Refresh
End Sub

Function ReportString$ ()
  ' Returns the string used on the status line to report the size
  ' of the selected slice.
  If Typ = "T" Then
    Msg = Graph1.LegendText + " - "
  Else
    Msg = "*." + UCase$(Graph1.LegendText) + " - "
  End If
  Msg = Msg + Format$(Graph1.GraphData, "#,###,###,##0")
  Msg = Msg + " bytes.  ("
  Msg = Msg + Format$(Graph1.GraphData / GrandTotal, "#0.0%)")
  ReportString = Msg
End Function

Function SizeOfFiles! (ByVal DirName$, ByVal Recurse%)
  ' Function to get size of files in directory DirName.  If the
  ' parameter Recurse is TRUE, the function recursively sums files in
  ' directories below DirName.
  Dim TotalSize!, OneSize!, N%, DirCombine$
  MdiForm1.Label1.Caption = "Scanning " + DirName + "..."
  DoEvents
  If Breakout Then Exit Function
  TotalSize = 0
  If Right$(DirName, 1) = "\" Then
    DirCombine = DirName
  Else
    DirCombine = DirName + "\"
  End If
  File1.Path = DirName
  File1.Pattern = "*.*"
  File1.Refresh
  ' Add the size of each file in the current directory
  If File1.ListCount > 0 Then
    For N = 0 To File1.ListCount - 1
      TotalSize = TotalSize + FileLen(DirCombine + File1.List(N))
    Next N
  End If
  If Recurse Then
    ' Use Dir2 to get a list of subdirectories
    Dir2.Path = DirName
    Dir2.Refresh
    If Dir2.ListCount > 0 Then
      ' Copy the list of subdirectories to a LOCAL variable
      Dim Dirs$()
      ReDim Dirs$(Dir2.ListCount - 1)
      For N = 0 To Dir2.ListCount - 1
        Dirs(N) = Dir2.List(N)
      Next N
      ' For each subdirectory, call SizeOfFiles
      For N = 0 To UBound(Dirs)
        TotalSize = TotalSize + SizeOfFiles(Dirs(N), True)
        If Breakout Then Exit Function
      Next N
    End If
  End If
  SizeOfFiles = TotalSize
End Function

Sub SortDirData ()
' Sort into descending size order using sorted list box
  Dim M%, N%, SizM!, SizN!
  Balanced = False
  SliceShown = -1
  MdiForm1.Shape1.FillColor = &HFFFFFF
  MdiForm1.Label1.Caption = ""
  List1.Clear
  Dim Siz!
  For N = 1 To Graph1.NumPoints
    Graph1.ThisPoint = N
    Siz = Graph1.GraphData
    List1.AddItem Format$(Siz, "0000000000") + Graph1.LegendText
  Next N
  Dim TheLine$
  For N = 1 To List1.ListCount
    Graph1.ThisPoint = N
    TheLine = List1.List(List1.ListCount - N)
    Graph1.LegendText = Mid$(TheLine, 11)
    Graph1.GraphData = Val(Left$(TheLine, 10))
  Next N
  List1.Clear
  Exit Sub
End Sub

