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();
            cboDrives.Items.AddRange(drives);
        }


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


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

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

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; 

        [DllImport("shell32.dll")]
        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);
        }

        [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;
        };


Done.

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

Comments

  1. Anonymous8/19/2013

    Thanx Dud...

    ReplyDelete
  2. Whoa! I’m enjoying the template/theme of this website. It’s simple, yet effective. A lot of times it’s very hard to get that “perfect balance” between superb usability and visual appeal. I must say you’ve done a very good job with this.

    AWS Certification Training Online Toronto
    AWS Certification Training Online Newyork
    AWS Certification Training Online London

    ReplyDelete
  3. Excellant post!!!. The strategy you have posted on this technology helped me to get into the next level and had lot of information in it.
    Python training in bangalore
    Python course in pune
    Python training in bangalore

    ReplyDelete

Post a Comment

Popular posts from this blog

Auto Scroll in Common Controls

Convert typed library (.tlb) to .net assembly?

Disable close button on form - C#