File browser in c#

P

Peter Larsen

Hi,

I want to be able to show a file browser embedded on a form - a browser
which is similar to the browser you get by SHBrowseForFolder().
Is that possible ?

Thank you in advance.
BR
Peter Larsen
 
G

Guest

Hello,

Yes, it's possible via Shell API. Be aware of several tips and tricks when
implementing with .Net.
- You can obtain handle to the system's image list using SHGetFileInfo,
unfortunatelly you cannot set ImageList.Handle property directly because it's
readonly. The trick is to send TVM_SETIMAGELIST message to your tree view
control with handle returned by SHGetFileInfo.
- Use BeforeExpand event to populate child nodes

Hope this helps
 
P

Peter Larsen

Hi Milosz,

Thanks for your comment and for the tips.

This is what i'm doing today - except from the TVM_SETIMAGELIST stuff.
Right now i am saving the icon in a ImageList and setting StateImageList
property to each tree-node.

I am not sure how to use TVM_SETIMAGELIST from within C# and i'm not sure
what it actually do.
Please give me more info :)

/Peter
 
G

Guest

Please find messy rough example below (Sorry for the mess but i didn't have
much time :])

-- BEGIN CODE --
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Runtime.InteropServices;

namespace DirectoryBrowser
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.TreeView Browser;
private System.Windows.Forms.ImageList imageList1;
private System.ComponentModel.IContainer components;

public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.Browser = new System.Windows.Forms.TreeView();
this.imageList1 = new System.Windows.Forms.ImageList(this.components);
this.SuspendLayout();
//
// Browser
//
this.Browser.ImageIndex = -1;
this.Browser.Location = new System.Drawing.Point(32, 36);
this.Browser.Name = "Browser";
this.Browser.Nodes.AddRange(new System.Windows.Forms.TreeNode[] {
new System.Windows.Forms.TreeNode("Node0")});
this.Browser.SelectedImageIndex = -1;
this.Browser.Size = new System.Drawing.Size(444, 452);
this.Browser.TabIndex = 0;
//
// imageList1
//
this.imageList1.ImageSize = new System.Drawing.Size(16, 16);
this.imageList1.TransparentColor = System.Drawing.Color.Transparent;
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(748, 566);
this.Controls.Add(this.Browser);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
this.ResumeLayout(false);

}
#endregion

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}

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

private const UInt32 TV_FIRST = 4352;
private const UInt32 TVSIL_NORMAL = 0;
private const UInt32 TVSIL_STATE = 2;
private const UInt32 TVM_SETIMAGELIST = TV_FIRST + 9;
private const UInt32 TVM_GETNEXTITEM = TV_FIRST + 10;
private const UInt32 TVIF_HANDLE = 16;
private const UInt32 TVIF_STATE = 8;
private const UInt32 TVIS_STATEIMAGEMASK = 61440;
private const UInt32 TVM_SETITEM = TV_FIRST + 13;
private const UInt32 TVGN_ROOT = 0;

[StructLayout(LayoutKind.Sequential, Pack=8, CharSet=CharSet.Auto)]
private struct TVITEM
{
public uint mask;
public IntPtr hItem;
public uint state;
public uint stateMask;
public IntPtr pszText;
public int cchTextMax;
public int iImage;
public int iSelectedImage;
public int cChildren;
public IntPtr lParam;
}

[DllImport("user32.dll")]
private static extern UInt32 SendMessage( IntPtr hWnd, UInt32 Msg,
UInt32 wParam, UInt32 lParam);

private const int MAX_PATH = 256;

[Flags]
private enum SHGetFileInfoConstants : int
{
SHGFI_ICON = 0x100, // get icon
SHGFI_DISPLAYNAME = 0x200, // get display name
SHGFI_TYPENAME = 0x400, // get type name
SHGFI_ATTRIBUTES = 0x800, // get attributes
SHGFI_ICONLOCATION = 0x1000, // get icon location
SHGFI_EXETYPE = 0x2000, // return exe type
SHGFI_SYSICONINDEX = 0x4000, // get system icon index
SHGFI_LINKOVERLAY = 0x8000, // put a link overlay on icon
SHGFI_SELECTED = 0x10000, // show icon in selected state
SHGFI_ATTR_SPECIFIED = 0x20000, // get only specified attributes
SHGFI_LARGEICON = 0x0, // get large icon
SHGFI_SMALLICON = 0x1, // get small icon
SHGFI_OPENICON = 0x2, // get open icon
SHGFI_SHELLICONSIZE = 0x4, // get shell size icon
SHGFI_PIDL = 0x8, // pszPath is a pidl
SHGFI_USEFILEATTRIBUTES = 0x10, // use passed dwFileAttribute
SHGFI_ADDOVERLAYS = 0x000000020, // apply the appropriate overlays
SHGFI_OVERLAYINDEX = 0x000000040 // Get the index of the overlay
}

private enum IconSize
{
Small = 0,
Large = 1
}

private const int FILE_ATTRIBUTE_NORMAL = 0x80;

[StructLayout(LayoutKind.Sequential)]
private struct SHFILEINFO
{
public IntPtr hIcon;
public int iIcon;
public int dwAttributes;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=MAX_PATH)]
public string szDisplayName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=80)]
public string szTypeName;
}

[DllImport("shell32")]
private static extern IntPtr SHGetFileInfo (
string pszPath,
int dwFileAttributes,
ref SHFILEINFO psfi,
uint cbFileInfo,
uint uFlags);


private void Form1_Load(object sender, System.EventArgs e)
{
this.SetImageList();

foreach (string file in System.IO.Directory.GetFiles("c:\\", "*.*"))
{
TreeNode node = Browser.Nodes.Add(System.IO.Path.GetFileName(file));
node.ImageIndex = GetImageIndex(file, IconSize.Small);
}
}

/// <summary>
///
/// </summary>
/// <param name="file"></param>
/// <returns></returns>
private int GetImageIndex(string file, IconSize size)
{
SHFILEINFO shfi = new SHFILEINFO();
SHGetFileInfoConstants flags =
SHGetFileInfoConstants.SHGFI_SYSICONINDEX;

/* Check the size specified for return. */
if (size == IconSize.Small)
{
flags |= SHGetFileInfoConstants.SHGFI_SMALLICON ;
}
else
{
flags |= SHGetFileInfoConstants.SHGFI_LARGEICON;
}

SHGetFileInfo(file,
FILE_ATTRIBUTE_NORMAL,
ref shfi,
(uint) System.Runtime.InteropServices.Marshal.SizeOf(shfi),
(uint) flags);

return shfi.iIcon;
}

private void SetImageList()
{
SendMessage(
Browser.Handle,
TVM_SETIMAGELIST,
TVSIL_NORMAL,
(uint) this.GetSystemImageListHandle(IconSize.Small).ToInt32());
}

private IntPtr GetSystemImageListHandle(IconSize size)
{
SHGetFileInfoConstants dwFlags =
//SHGetFileInfoConstants.SHGFI_USEFILEATTRIBUTES |
SHGetFileInfoConstants.SHGFI_SYSICONINDEX ;
if (size == IconSize.Small)
{
dwFlags |= SHGetFileInfoConstants.SHGFI_SMALLICON;
}
else
{
dwFlags |= SHGetFileInfoConstants.SHGFI_LARGEICON;
}
// Get image list
SHFILEINFO shfi = new SHFILEINFO();
uint shfiSize = (uint)Marshal.SizeOf(shfi.GetType());

// Call SHGetFileInfo to get the image list handle
// using an arbitrary file:
return SHGetFileInfo(
"c:\\",
FILE_ATTRIBUTE_NORMAL,
ref shfi,
shfiSize,
(uint)dwFlags);

}

}
}
-- END CODE --

Hope this helps
 
P

Peter Larsen

Thanks it works.
There are still a lot of things to do, but the concept is clear to me now.
Thanks for your time.
/Peter
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top