Click here to Skip to main content
15,867,453 members
Articles / Programming Languages / C#

Fast Drive ComboBox

Rate me:
Please Sign up or sign in to vote.
4.82/5 (20 votes)
22 May 2007CPOL3 min read 90.2K   2.5K   51   20
A fast combobox that correctly displays all the logical drives with the appropriate icons, volume names, and drive letters.
<o>Screenshot - DriveComboBox.jpg

Introduction

Recently, I needed some way of displaying the logical drives on the computer and only the logical drives. I didn't think it would be any problem through the use of either OpenFileDialog or FolderBrowserDialog, but I quickly realized that these didn't do what I wanted them to do.

I, therefore, turned to CodeProject to see if a control existed here that could do the job. I found several (An "Explorer-Style" TreeView Control, DriveComboBox, Drive Box) - but none of them solved my problem to my satisfaction, and therefore I chose to hack my own control.

Using the code

To use the control, include the code and add a standard ComboBox to your form/dialog/control. Next, change the type of the control from "System.Windows.Forms.ComboBox" to "ZinoLib.Windows.Controls.DriveComboBox".

C#
...
private ZinoLib.Windows.Controls.DriveComboBox _cbDrives = 
        new ZinoLib.Windows.Controls.DriveComboBox();
...

If you don't want to use the Designer to add the combo box to the parent control, the following code describes how to create and add the DriveComboBox to a parent control:

C#
public class Form1 : System.Windows.Forms.Form
{
   private ZinoLib.Windows.Controls.DriveComboBox _cbDrives;

   ...

   private void CreateDriveComboBox()
   {
      _cbDrives = new ZinoLib.Windows.Controls.DriveComboBox();
      _cbDrives.Location = new System.Drawing.Point(8, 24);
      _cbDrives.Name = "_cbDrives";
      _cbDrives.Size = new System.Drawing.Size(320, 21);
      _cbDrives.TabIndex = 0;
      this.Controls.Add(this._cbDrives);
   }

   ...

}

The code presented in this article has support for both .NET framework 1.1 and .NET framework 2.0.

Points of interest

The .NET framework has built-in support for retrieving the logical drive letters via calls to System.IO.Directory.GetLogicalDrives() - however, it does not provide an interface to retrieve the volume name or the appropriate icon. By browsing through the source code of MrPJ's "Explorer-Style" TreeView Control and Microsoft article 319350, I figured out how to retrieve these information through the use of SHGetFileInfo located in shell32.dll. By parsing the appropriate flags, SHGetFileInfo can return the display name, icon index, icon handle, and more. I then needed a way to display this information - and thought it would be easy to extend Niels Penneman's excellent ImageCombo control. 10 minutes later, DriveComboBox was finished - and ready to be used.

The retrieval of the drive information is done in the function "BuildDriveList()" which is initially called by the constructor of DriveComboBox. Before SHGetFileInfo can be used to retrieve the actual drive information, we have to tell what information is needed. In the case of DriveComboBox, the following information is needed:

  • Icon
  • Small icon
  • Icon index
  • Display name

The actual retrieval is quite trivial, as we only have to iterate over the drives returned by System.IO.Directory.GetLogicalDrives() and call SHGetFileInfo for each drive. The information retrieved can then be used to build an ImageList of drive icons and add them to the combobox.

C#
public void BuildDriveList()
{
   base.Items.Clear();

   ShellAPI.SHFILEINFO shInfo = new ShellAPI.SHFILEINFO();
   ShellAPI.SHGFI dwAttribs = 
     ShellAPI.SHGFI.SHGFI_ICON |
     ShellAPI.SHGFI.SHGFI_SMALLICON |
     ShellAPI.SHGFI.SHGFI_SYSICONINDEX |
     ShellAPI.SHGFI.SHGFI_DISPLAYNAME;

   ListDictionary _iconDict = new ListDictionary();            
   foreach( string drive in System.IO.Directory.GetLogicalDrives() )
   {
      IntPtr m_pHandle = ShellAPI.SHGetFileInfo(drive, 
                            ShellAPI.FILE_ATTRIBUTE_NORMAL,
                            ref shInfo,
                            (uint)System.Runtime.InteropServices.Marshal.SizeOf(shInfo),
                            dwAttribs);

      if( m_pHandle.Equals(IntPtr.Zero)==false )                    
      {
         int idxIcon = 0;
         if( _iconDict.Contains(shInfo.iIcon)==false )
         {
            base.ImageList.Images.Add( 
              System.Drawing.Icon.FromHandle(shInfo.hIcon).Clone() 
              as System.Drawing.Icon );

            User32API.DestroyIcon(shInfo.hIcon);

            _iconDict.Add( shInfo.iIcon, _iconDict.Count );
            idxIcon = _iconDict.Count-1;
         }
         else
            idxIcon = Convert.ToInt32( _iconDict[shInfo.iIcon] );


         ImageComboItem item = 
           new ImageComboItem(shInfo.szDisplayName, idxIcon, false);
         item.ItemValue = drive;
         base.Items.Add( item );
      }
   }

   if( base.Items.Count!=0 )
      base.SelectedIndex = 0;
}

License

You are free to use this code in any way you wish - both in freeware and commercial programs - free of charge. A small link in an About box etc. will be appreciated - but it is not required.

Acknowledgement

Most of the credit must go to Niels Penneman for his ImageCombo control which does most of the magic in the DriveComboBox control, and MrPJ for his "Explorer-Style" TreeView Control which gave me the idea to use SHGetFileInfo.

History

  • 2007-05-08: Initial release.
  • 2007-05-15: Moved drive enumeration to a separate function "BuildDriveList" and removed the Items property from the designer.
  • 2007-05-23: Minor ajustments to the article text.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Founder CWAIN
Denmark Denmark
I have a MCPD .NET 3.5 EAD and a Bsc in computer science, organizational theory and economics.
After more than 24 years working as professional system engineer, I founded the independent consultant agency CWAIN.

Comments and Discussions

 
QuestionCircles for the drive icons Pin
Brian C Hart12-Aug-14 20:26
professionalBrian C Hart12-Aug-14 20:26 
QuestionThanks! Pin
MillerME16-Nov-13 10:48
MillerME16-Nov-13 10:48 
GeneralMy vote of 5 Pin
Kanasz Robert27-Sep-12 11:00
professionalKanasz Robert27-Sep-12 11:00 
GeneralLogical drives not. Pin
Vercas17-Aug-10 1:28
Vercas17-Aug-10 1:28 
GeneralUpdating Icons when Drive Changes Pin
Member 309384422-Mar-10 6:13
Member 309384422-Mar-10 6:13 
I'm building a program to change drive icons and when I call the cmbDriveList.BuildDriveList() & Refresh the labels and drives update but the new icons for the drive are not reloaded? How can I fix this? Thanks
GeneralRe: Updating Icons when Drive Changes Pin
Michael B. Hansen22-Mar-10 7:35
Michael B. Hansen22-Mar-10 7:35 
GeneralRe: Updating Icons when Drive Changes Pin
Member 309384422-Mar-10 8:33
Member 309384422-Mar-10 8:33 
Generalnice Pin
xtcradio10-Mar-10 17:42
xtcradio10-Mar-10 17:42 
GeneralInteresting, but I wonder... Pin
Johnny J.14-May-07 21:28
professionalJohnny J.14-May-07 21:28 
GeneralRe: Interesting, but I wonder... Pin
eisernWolf14-May-07 22:06
eisernWolf14-May-07 22:06 
GeneralRe: Interesting, but I wonder... Pin
Johnny J.14-May-07 22:11
professionalJohnny J.14-May-07 22:11 
AnswerRe: Interesting, but I wonder... Pin
Michael B. Hansen14-May-07 22:46
Michael B. Hansen14-May-07 22:46 
GeneralRe: Interesting, but I wonder... Pin
vodzurk30-Aug-07 13:14
vodzurk30-Aug-07 13:14 
GeneralBUG - Identical items - Design-time Pin
eisernWolf14-May-07 21:02
eisernWolf14-May-07 21:02 
GeneralRe: BUG - Identical items - Design-time Pin
Michael B. Hansen14-May-07 22:48
Michael B. Hansen14-May-07 22:48 
AnswerRe: BUG - Identical items - Design-time Pin
Michael B. Hansen14-May-07 23:07
Michael B. Hansen14-May-07 23:07 
GeneralNice But ... Pin
Hamed J.I13-May-07 0:56
Hamed J.I13-May-07 0:56 
GeneralRe: Nice But ... Pin
Michael B. Hansen14-May-07 7:02
Michael B. Hansen14-May-07 7:02 
GeneralNice.. Pin
merlin9818-May-07 11:11
professionalmerlin9818-May-07 11:11 
AnswerRe: Nice.. Pin
Michael B. Hansen8-May-07 11:18
Michael B. Hansen8-May-07 11:18 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.