If you are not a paid subscriber, you must have signed up for our free trial at http://www.codeoftheweek.com. Our ezine is not an unsolicited message (in other words a spam email). Keep in mind that if you signed up for our free trial you can still receive a total of four issues at no cost to you. After you receive the four issues you will be notified about continuing your subscription.
If you do not wish to continue to receive this ezine, please email us at cancel@codeoftheweek.com
The source code in this issue is designed for Visual Basic 5.0 and above. If you want to make this source code work under VB 4.0 32-bit, just change the Enum types to normal Const values.
If you have any questions about this issue, please email us at questions@codeoftheweek.com
This issue expands on the cVolumeInfo class introduced last week. This week we add the ability to gather the total disk space and the available disk space for a disk drive. It accomplishes this task by using an API call, GetDiskFreeSpace.
Last week we sent you the first version of the cVolumeInfo class. It had the ability to determine the label of a disk drive. This week we have included an updated cVolumeInfo class which has two new functions for getting the total disk space and the available free disk space. The first function, TotalDiskSpace will gather the total disk space information for the drive specified by the Drive property. The second function, FreeDiskSpace will gather the available free disk space information for the drive specified by the Drive property. The number returned from both functions are data type Double. This should handle the largest available drives currently on the market.
Inside the two functions you will notice some multiplication done with SectorsPerCluster and BytesPerSector. The GetDiskFreeSpace returns this information. For those of you not familiar with the way data storage is laid out, a quick lesson follows. On your hard drive, the smallest unit of data storage is called a sector. In order to handle data efficiently on larger hard drives, the operating system combines several sectors together to form a cluster. When you multiply the SectorsPerCluster by the BytesPerCluster you will get the total number of bytes stored in each cluster. This number multiplied by the available clusters or the total clusters on the drive will give you the free disk space or the total disk space. If you have any additional questions about this topic, drop us an email at questions@codeoftheweek.com
Public Function TotalDiskSpace() As Double Public Function FreeDiskSpace() As Double
On frmDriveType we created a ListView control called lvDrives. We also created a command button called cmdClose. This sample will scan all drives looking for volume labels, total disk size and available disk space.
Option Explicit Private Sub cmdClose_Click() Unload Me End Sub Private Sub Form_Load() SetupForm ShowDriveInfo End Subdata is Private Sub SetupForm() With lvDrives .ColumnHeaders.Add , "Drive", "Drive" .ColumnHeaders.Add , "Volume Label", "Volume Label" .ColumnHeaders.Add , "Total Size", "Total Size", , lvwColumnRight .ColumnHeaders.Add , "Free Space", "Free Space", , lvwColumnRight .Sorted = True .SortKey = 0 .View = lvwReport End With End Sub Private Sub ShowDriveInfo() Dim x As Integer Dim itm As ListItem Dim sDrive As String Dim lDriveType As Long Dim sDriveTypeDesc As String lvDrives.ListItems.Clear For x = 67 To 90 sDrive = Chr$(x) Dim vol As New cVolumeInfo vol.Drive = sDrive ' only add drives that have labels If vol.Label <> "" Then Set itm = lvDrives.ListItems.Add(, sDrive, sDrive) itm.SubItems(1) = vol.Label itm.SubItems(2) = Format$(vol.TotalDiskSpace, "###,###,###") itm.SubItems(3) = Format$(vol.FreeDiskSpace, "###,###,###") End If Next End Sub
Just paste this source code into a class module called cVolumeInfo and include it in your project.
'---------------------------------------------------------------------- ' ' Module Name: cVolumeInfo ' Written By: C&D Programming Corp. ' Create Date: 7/98, 8/98 ' Copyright: Copyright 1998 by C&D Programming Corp. Source ' code may not be reproduced except for use in a ' compiled executable. All rights reserved. If ' you would like to reprint any or all of this ' code please email us at info@codeoftheweek.com '---------------------------------------------------------------------- Option Explicit ' ' This API call allows us to gather volume information ' Private Declare Function GetVolumeInformation Lib "KERNEL32" _ Alias "GetVolumeInformationA" _ (ByVal lpRootPathName As String, _ ByVal lpVolumeNameBuffer As String, _ ByVal nVolumeNameSize As Long, _ lpVolumeSerialNumber As Long, _ lpMaximumComponentLength As Long, _ lpFileSystemFlags As Long, _ ByVal lpFileSystemNameBuffer As String, _ ByVal nFileSystemNameSize As Long) As Long ' ' This enumerator contains the possible values returned by ' GetDriveType ' Public Enum eDriveTypes drvtype_Unknown = 1 drvtype_Removable = 2 drvtype_Fixed = 3 ' Hard Drive or Local Drive drvtype_Remote = 4 drvtype_CDRom = 5 drvtype_Ramdisk = 6 End Enum ' ' This API call allows us determine what type of ' we are looking at and to gather disk drive stats ' Private Declare Function GetDriveType Lib "KERNEL32" _ Alias "GetDriveTypeA" _ (ByVal nDrive As String) As eDriveTypes Private Declare Function GetDiskFreeSpace Lib "KERNEL32" _ Alias "GetDiskFreeSpaceA" _ (ByVal lpRootPathName As String, _ lpSectorsPerCluster As Long, _ lpBytesPerSector As Long, _ lpFreeClusters As Long, _ lpTotalClusters As Long) As Long Dim msDrive As String Dim msLabel As String Dim mlSectorsPerCluster As Long Dim mlBytesPerSector As Long Dim mlFreeClusters As Long Dim mlTotalClusters As Long Public Property Get Drive() As String Drive = msDrive End Property Public Property Let Drive(sDrive As String) On Error GoTo Handler If Left(sDrive, 2) = "\\" Then Err.Raise 5, "cVolumeInfo.Drive", "Network drives are not supported in this version." Exit Property Else msDrive = Left(sDrive, 1) & ":\" End If ClearDriveInfo ' to make sure the data gets refreshed when a ' property used Exit Property Handler: Err.Raise Err.Number, Err.Source, Err.Description End Property Public Property Get Label() As String GetVolumeLabel Label = msLabel End Property Private Sub GetVolumeLabel() Dim lRet As Long Dim sLabel As String Dim lLabelSize As Long Dim lSerialNumber As Long Dim lMaxComponentLen As Long Dim lFileSysFlags As Long Dim sFileSysName As String Dim lFileSysNameSize As Long Dim elDriveType As eDriveTypes elDriveType = GetDriveType(Drive) ' ' don't include unknown drives and network drives ' If elDriveType <> drvtype_Unknown And elDriveType <> drvtype_Remote Then sLabel = String$(64, 0) lLabelSize = 63 lRet = GetVolumeInformation(Drive, sLabel, lLabelSize, lSerialNumber, _ lMaxComponentLen, lFileSysFlags, sFileSysName, lFileSysNameSize) Select Case Err.LastDllError Case 21 msLabel = "" ' device is not ready Case 111 ' buffer for label not large enough. Case 0 ' success msLabel = Left(sLabel, lLabelSize) Case Else msLabel = "" Err.Raise Err.LastDllError, "cVolumeInfo.GetVolumeLabel", "API Error " & Err.LastDllError End Select Else msLabel = "" End If End Sub ' ' This routine returns True if the GetDiskSpace function ' was called. This allows the cache to avoid making additional ' calls to the API to gather disk space information ' Private Property Get GotData() As Boolean GotData = False ' assume we haven't retrieved the data If mlSectorsPerCluster = 0 Then ' if SectorsPerCluster are we probably ' did not retrieve the data GetDiskSpace ' Get the data GotData = True ' Assume we retrieved it ok. Else GotData = True ' If SectorsPerCluster is non-zero, we ' already have the data, so don't get ' it again. If you set the Drive ' property it will reset the ' necessary flags for making sure ' the data is retrieved. End If End Property Public Property Get SectorsPerCluster() As Long If GotData Then SectorsPerCluster = mlSectorsPerCluster End If End Property Public Property Get BytesPerSector() As Long If GotData Then BytesPerSector = mlBytesPerSector End If End Property Public Property Get FreeClusters() As Long If GotData Then FreeClusters = mlFreeClusters End If End Property Public Property Get TotalClusters() As Long If GotData Then TotalClusters = mlTotalClusters End If End Property Private Function GetDiskSpace() As Boolean Dim lStatus As Long lStatus = GetDiskFreeSpace(Drive, mlSectorsPerCluster, _ mlBytesPerSector, mlFreeClusters, _ mlTotalClusters) If lStatus = 0 Then ' if failed, zero out counters ClearDriveInfo GetDiskSpace = True Else GetDiskSpace = False End If End Function Public Function TotalDiskSpace() As Double TotalDiskSpace = SectorsPerCluster * BytesPerSector * TotalClusters End Function Public Function FreeDiskSpace() As Double FreeDiskSpace = SectorsPerCluster * BytesPerSector * FreeClusters End Function Private Sub Class_Initialize() ClearDriveInfo End Sub Private Sub ClearDriveInfo() mlSectorsPerCluster = 0 mlBytesPerSector = 0 mlTotalClusters = 0 mlFreeClusters = 0 End Sub
That concludes this issue of COTW. We hope you find the source code useful in your development.
The below describes the ways you can supply us some feedback about COTW. We would like to see our members help mold COTW into the best Visual Basic source code resource available. But to do that we need your feedback about what you like and what you do not like about COTW.
If you are interested in advertising in COTW please email us at sponsor@codeoftheweek.com Our rates are VERY reasonable, actually they are almost FREE. We reach over five thousand Visual Basic developers each week.
If you have any suggestions for topics you would like to see covered or questions about this issue, please email them to info@codeoftheweek.com or use online feedback form at http://www.codeoftheweek.com/feedback.html.
If you have any source code you would like to submit for possible inclusion in COTW, please fill out our online submission form at http://www.codeoftheweek.com/submission.html.
Thank you for trying Code of the Week for Visual Basic.
Your free trial expires after you receive your fourth issue. If you want to continue to receive Code of the Week you can get 52 issues of COTW for only $19.95. This is a full year of Visual Basic source code and information to help with all your development. So don't wait, subscribe now! The quickest way to subscribe is to jump to our online order form at http://www.codeoftheweek.com/order.html