Drive combo box in C#

As most of the .Net developers, I am also started my development career with VB6. :) VB6 comes with few file system controls, like DriveListbox, DirectoryListbox, FileListbox etc. But in .Net framework didn’t support these controls. Here is a solution for creating a drive listbox(it is not a listbox, it is dropdown list).

Drive Combo box in C#

Drive Combo box in C#

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.

Here is the implementation.

private void Form1_Load(object sender, EventArgs e)
{
    comboBox1.DrawMode = DrawMode.OwnerDrawFixed;
    comboBox1.DropDownStyle = ComboBoxStyle.DropDownList;
    comboBox1.DrawItem += new DrawItemEventHandler(comboBox1_DrawItem);

    var drives = DriveInfo.GetDrives()
        .Where(drive => drive.Name != string.Empty).ToArray();
    comboBox1.Items.AddRange(drives);
}

And here is the DrawItem event

private void comboBox1_DrawItem(object sender, DrawItemEventArgs e)
{
    if (e.Index != -1)
    {
        e.DrawBackground();
        var icon = GetIcon(comboBox1.Items[e.Index].ToString());
        e.Graphics.DrawIcon(icon, 3, e.Bounds.Top);
        e.Graphics.DrawString(comboBox1.Items[e.Index].ToString(),
            comboBox1.Font, Brushes.Black, icon.Width + 2, e.Bounds.Top);
        e.DrawFocusRectangle();
    }
}

And 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;

[DllImport("shell32.dll")]
private static extern IntPtr SHGetFileInfo(string pszPath,
                            uint dwFileAttributes,
                            ref SHFILEINFO psfi,
                            uint cbSizeFileInfo,
                            uint uFlags);
[StructLayout(LayoutKind.Sequential)]
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;
};

private Icon GetIcon(string fileName)
{
    IntPtr hImgSmall;
    SHFILEINFO shinfo = new SHFILEINFO();
    hImgSmall = SHGetFileInfo(fileName, 0, ref shinfo,
                (uint)Marshal.SizeOf(shinfo),
                    SHGFI_ICON |
                    SHGFI_SMALLICON);
    return Icon.FromHandle(shinfo.hIcon);
}

This implementation is using normal Combobox, you can do same thing by extending Combobox. So that it can be used in any project without any dependency.

One thought on “Drive combo box in C#

Leave a Reply

Your email address will not be published. Required fields are marked *

CAPTCHA Image

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>