Jul 27, 2012

Create Drive combo box in C#

While browsing at some places on internet we may seen the Drive combo box as shown below,

How to create/populate combo box like this in WinForms using C#.Net?

The drive information can be retrieved using DriveInfo.GetDrives() method.  And for getting the corresponding icons for drive letters, I am using the SHGetFileInfo WIN32 API call.

Implementation details are as follows,

private void btnGetDrives_Click(object sender, EventArgs e)
            cboDrives.DrawMode = DrawMode.OwnerDrawFixed;
            cboDrives.DropDownStyle = ComboBoxStyle.DropDownList;
            cboDrives.DrawItem += new DrawItemEventHandler(CboDrives_DrawItem);

            DriveInfo[] drives = DriveInfo.GetDrives();

Draw the combobox items with drive icon using DrawItem() event.

private void CboDrives_DrawItem(object sender, DrawItemEventArgs e)
            if (e.Index == -1)

            Icon icon = GetIcon(cboDrives.Items[e.Index].ToString());
            e.Graphics.DrawIcon(icon, 3, e.Bounds.Top);
                cboDrives.Font, Brushes.Black, icon.Width + 2, e.Bounds.Top);

here is the GetIcon method and API declaration

        private const uint SHGFI_ICON = 0x100;
        private const uint SHGFI_LARGEICON = 0x0;
        private const uint SHGFI_SMALLICON = 0x1;

        private const int HWND_TOPMOST = -1;
        private const int SWP_NOMOVE = 0x0002;
        private const int SWP_NOSIZE = 0x0001; 

        private static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags);
        private Icon GetIcon(string fileName)
            SHFILEINFO shinfo = new SHFILEINFO();
            IntPtr hImgSmall = SHGetFileInfo(fileName, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), SHGFI_ICON | SHGFI_SMALLICON);
            return Icon.FromHandle(shinfo.hIcon);

        private struct SHFILEINFO
            public IntPtr hIcon; public IntPtr iIcon; public uint dwAttributes;

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
            public string szDisplayName;

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
            public string szTypeName;


If you feel this is helpful or you like it, Please share this using share buttons available on page.