|
Thanks for the wonderful control. I am trying to use this in a project I am working on, but I need to be able to show all files and folders on the filesystem. I have modified the control to show files as well as folders, but I am not sure how to make it show hidden folders/files. Any help would be appreciated.
Thanks,
Scott
|
|
|
|
|
Hy Scott
is it easy to show files as well as folders? Can you show me the way?
Thx,
Peter
|
|
|
|
|
To show hidden folders, you need to modify the file FolderTreeView.cs by replacing line 523
foreach(Shell32.FolderItem item in folder.Items())
with
Shell32.FolderItems3 items = (Shell32.FolderItems3 )folder.Items();
int SHCONTF_INCLUDEHIDDEN = 128;
int SHCONTF_FOLDERS = 32;
int SHCONTF_NONFOLDERS = 64;
items.Filter(SHCONTF_INCLUDEHIDDEN | SHCONTF_NONFOLDERS | SHCONTF_FOLDERS, "*");
foreach (Shell32.FolderItem item in items)
...
Version 3 of FolderItems supports this type of filtering.
Jos
modified on Saturday, October 31, 2009 12:51 PM
|
|
|
|
|
Any idea why the "My Documents" icon returned is not the good one ?
Jonathan.
|
|
|
|
|
Congratulation for your control.
I used some of your code in a ExplorerListView component i'm currently developping.
It should be finished very soon.
I will post it here after that, so everyone can use it.
Regards.
|
|
|
|
|
I have a Folder class instance. I need to get the ParentFolder. I tried with the property "PArentFolder" from the Folder class but i need to have a FolderItem for the parent not a Folder. Does somebody knows how to get a FolderItem object from a Fodler object ?
Thanks.
|
|
|
|
|
Ahhh yes, I remember this Here is the code I came up with, it may not be the best way, but it worked for me when looking for the desktop dir, while keeping the vitrual desktop namespace members.
Shell32.Folder dfolder = shell32.NameSpace(ShellFolder.DesktopDirectory);<br />
foreach(Shell32.FolderItem fi in dfolder.ParentFolder.Items())<br />
{<br />
<br />
if(fi.Name == dfolder.Title)<br />
{<br />
myFolderItem = fi;<br />
break;<br />
}<br />
}
if you find a better way, let me know..
|
|
|
|
|
Heh heh,
It's funny we had the same idea I did it like that while i find a better idea.
Looping through all element in large folders (don't forget my component display files too ) is quite "slow". And just for your info, i think it must be a very good idea to try to optimize the icons things. I mean, getting the system image list directly like somebody else suggest you in another thread.
I tested my control in folder having more than 1000 items, and after that returning getting item icon handles (Icon.FromHandle(info.hIcon);) failed for each subsequent item...
I'll try to find a way to optimize that.
Thanks.
Jonathan
|
|
|
|
|
I'd love to be able to convert, or access the system image list, but my (albeit feeble) efforts to do so have lead nowhere - I wonder if there's any shell guru's out there who want to take on the challenge?
As for your file list view, for now all I can do is give you this piece of code which caches icons by their path into a hashtable. You will probably want to change this to work by file extension rather than path, and add some checks for extensions that have unique icons such as .exe and .lnk
Hope this helps!
<br />
using System;<br />
using System.Collections;<br />
using System.Runtime.InteropServices;<br />
using System.Drawing;<br />
using System.Windows.Forms;<br />
<br />
#region ExtractIcons Class<br />
<br />
public class ExtractIcons<br />
{<br />
private Hashtable shellIcons;<br />
private Hashtable fileIcons;<br />
<br />
#region Constructor<br />
<br />
public ExtractIcons()<br />
{<br />
shellIcons = new Hashtable();<br />
fileIcons = new Hashtable();<br />
}<br />
<br />
#endregion<br />
<br />
#region Structs & Enum<br />
<br />
[StructLayout(LayoutKind.Sequential)]<br />
private struct SHFILEINFO<br />
{<br />
public SHFILEINFO(bool b)<br />
{<br />
hIcon=IntPtr.Zero;iIcon=0;dwAttributes=0;szDisplayName="";szTypeName="";<br />
}<br />
public IntPtr hIcon;<br />
public int iIcon;<br />
public uint dwAttributes;<br />
[MarshalAs(UnmanagedType.LPStr, SizeConst=260)]<br />
public string szDisplayName;<br />
[MarshalAs(UnmanagedType.LPStr, SizeConst=80)]<br />
public string szTypeName;<br />
};<br />
<br />
private enum SHGFI<br />
{<br />
SHGFI_ICON = 0x000000100,
SHGFI_DISPLAYNAME = 0x000000200,
SHGFI_TYPENAME = 0x000000400,
SHGFI_ATTRIBUTES = 0x000000800,
SHGFI_ICONLOCATION = 0x000001000,
SHGFI_EXETYPE = 0x000002000,
SHGFI_SYSICONINDEX = 0x000004000,
SHGFI_LINKOVERLAY = 0x000008000,
SHGFI_SELECTED = 0x000010000,
SHGFI_ATTR_SPECIFIED = 0x000020000,
SHGFI_LARGEICON = 0x000000000,
SHGFI_SMALLICON = 0x000000001,
SHGFI_OPENICON = 0x000000002,
SHGFI_SHELLICONSIZE = 0x000000004,
SHGFI_PIDL = 0x000000008,
SHGFI_USEFILEATTRIBUTES = 0x000000010
}<br />
<br />
#endregion<br />
<br />
#region Get File / Folder Icons<br />
<br />
<br />
[DllImport("Shell32.dll")]<br />
private static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, <br />
out SHFILEINFO psfi, uint cbfileInfo, SHGFI uFlags );<br />
<br />
public int GetIcon(string strPath, bool large, bool selected, ImageList imageList)<br />
{<br />
if(fileIcons.ContainsKey(strPath + large.ToString()))<br />
{<br />
imageList.Images.Add((Icon)fileIcons[strPath + large.ToString()]);<br />
return imageList.Images.Count - 1;<br />
}<br />
else<br />
{<br />
try<br />
{<br />
SHFILEINFO info = new SHFILEINFO(true);<br />
int cbFileInfo = Marshal.SizeOf(info);<br />
SHGFI flags;<br />
if(large)<br />
{<br />
if (!selected)<br />
flags = SHGFI.SHGFI_ICON|SHGFI.SHGFI_LARGEICON;<br />
else<br />
flags = SHGFI.SHGFI_ICON|SHGFI.SHGFI_LARGEICON|SHGFI.SHGFI_OPENICON;<br />
}<br />
else<br />
{<br />
if (!selected)<br />
flags = SHGFI.SHGFI_ICON|SHGFI.SHGFI_SMALLICON;<br />
else<br />
flags = SHGFI.SHGFI_ICON|SHGFI.SHGFI_SMALLICON|SHGFI.SHGFI_OPENICON;<br />
}<br />
<br />
SHGetFileInfo(strPath, 256, out info,(uint)cbFileInfo, flags);<br />
<br />
Icon icn;<br />
icn = (Icon)Icon.FromHandle(info.hIcon).Clone();<br />
User32.DestroyIcon( info.hIcon ); <br />
<br />
fileIcons.Add(strPath + large.ToString(), icn);<br />
<br />
imageList.Images.Add(icn);<br />
return imageList.Images.Count - 1;<br />
}<br />
catch<br />
{<br />
return -1;<br />
}<br />
}<br />
}<br />
<br />
#endregion<br />
<br />
#region Get Specific Shell Icon<br />
<br />
<br />
[DllImport("Shell32.dll", CharSet=CharSet.Auto)]<br />
private static extern int ExtractIconEx(<br />
string lpszFile, int nIconIndex, IntPtr[] phiconLarge, IntPtr[] phiconSmall, int nIcons );<br />
<br />
public Icon GetShellIcon(int iconIndex)<br />
{<br />
if(shellIcons.ContainsKey(iconIndex))<br />
{<br />
return (Icon)shellIcons[iconIndex];<br />
}<br />
else<br />
{<br />
Icon icn;<br />
IntPtr[] handlesIconLarge = new IntPtr[1];<br />
IntPtr[] handlesIconSmall = new IntPtr[1];<br />
int i = ExtractIconEx(Environment.SystemDirectory + "\\shell32.dll", iconIndex, <br />
handlesIconLarge, handlesIconSmall, 1);<br />
if(handlesIconSmall.Length > 0 && handlesIconSmall[0] != IntPtr.Zero)<br />
{<br />
icn = (Icon)Icon.FromHandle(handlesIconSmall[0]).Clone();<br />
User32.DestroyIcon( handlesIconSmall[0] ); <br />
}<br />
else<br />
{<br />
icn = null;<br />
}<br />
shellIcons.Add(iconIndex, icn);<br />
return icn;<br />
}<br />
}<br />
<br />
#endregion<br />
<br />
}<br />
<br />
#region Destroy Icon<br />
public class User32<br />
{<br />
[DllImport("User32.dll")]<br />
public static extern int DestroyIcon( IntPtr hIcon );<br />
}<br />
#endregion<br />
<br />
#endregion<br />
|
|
|
|
|
:confusedconfusedHi all.
I want a right to left treeview for a right to left treeview.
is anyone to help me.
thanks.
|
|
|
|
|
Using the concept of "Mirroring" i have done it.
Search for it in msdn.
But there are no other ways to do it.
Even i have create my own flipped control from Scratch with out using
windows api.
Srinivas
|
|
|
|
|
Since you're already interop'ing with Shell32.dll, why not just use the BrowseForFolder property? Currently, this is what many projects do. Here is some sample code, assuming you created the interop assembly for Shell32.dll:
Shell32.ShellClass shell = new Shell32.ShellClass();
Shell32.Folder2 folder = (Shell32.Folder2)shell.BrowserForFolder(
this.Handle, "Browse for Folder", 0, 0);
string path = folder.Self.Path;
You could still wrap this in a class (like having a CLS-compliant enumeration for all the startup-directories), but all the UI is taken care of for you. You can still provide a callback (in the form of a delegate) to customize the UI, too.
"Well, I wouldn't say I've been missing it, Bob." - Peter Gibbons
|
|
|
|
|
Correct me if I'm wrong, but all that will do is create a BrowseForFolder dialog, which is not the required result here.
|
|
|
|
|
I'd like to solve the problem with the desktop shellfolder, but I've gone as far as I can with the code provided. I noticed the Interop.shell32.dll file, and I'm curious where it came from, and if its possible to get the code for it. It looks like a very useful wrapper for shell32.dll, and I'd love to know how it was written, not to mention the fact that if I understand how it works, I may be able to figure out this problem with the desktop.
Thanks.
|
|
|
|
|
If you add a reference to a COM library in vs.net it automatically wraps them up with a Interop.*.dll - that's all I can tell you I'm afraid, don't know anything else about it.
As far as the FolderTreeView, I will be posting a major update to this soon - I have solved the desktop namespace problem (it was actually embarassingly simple), and am adding a couple of features to it, such as a DrillToFolder method. Stay tuned
|
|
|
|
|
While your into updating the control, I have a request. I noticed that you repeatedly add icons to the controls imagelist. If its a folder icon, its possible that it will be added hundreds of times, possibly more depending on how far down and around you drill. You can watch memory usage go up in taskmanager as more icons are added.
Is there any way you could use the systems imagelist, and just grab the image id's from it, rather than building one dynamically? That would be great if you could, and if not, no problem, I'm working on an interop library of my own for shell32.dll, comctl32.dll, and uxtheme.dll, which will provide access to the system imagelist. Its just going to take me a good long while to learn the API's for all three DLL's and figure out how to create a custom inderop library for them.
|
|
|
|
|
Jon Rista wrote:
I'm working on an interop library of my own for shell32.dll, comctl32.dll, and uxtheme.dll, which will provide access to the system imagelist
The next revision has been finished, Chris should be updating the article over the next couple of days. V1.1 now properly starts at the Desktop namespace, showing My Computer, Network Neighborhood, Recycle Bin etc. I have also added a startup folder driller, but the imagelist works just the same as before. I had thought to write code to manage the icons better, but I guess I was just too lazy to save the 1KB here and there
If you are willing to share some of your code, perhaps you can help make this control better
|
|
|
|
|
DOH!! LOL Just found this in shell32 documentation:
HRESULT SHGetDesktopFolder(
IShellFolder **ppshf
);
Anyway, I'd be glad to share my code. This is currently a learning project, but eventually I want to provide an interop library that lets you call all the unmanaged functions included in Shell32.dll, Comctl32.dll, and uxtheme.dll. Shell32.dll contains a lot of COM objects and interfaces, but there is also a whole list of static functions that you can't call when you add shell32.dll as a reference. Great stuff like SHGetImageList, which returns an IImageList interface to the system imagelist.
|
|
|
|
|
I've emailed Chris the version 1.11 code, demo, image and html to update this article, I guess he must be busy.. It fixes the known issues with this control, bar the image list bloat you've noted. Your project sounds very interesting, I'm curious to see it applied to this control - and possibly some others I'm working on..
|
|
|
|
|
some code such as my computer,my neighbor could not displayed.
|
|
|
|
|
In fact, comparing to Windows Explorer, what the tree control is missing is the actual Explorer namespaces.
Fortunately, they are easy to lookup. See this article[^].
In short, default namespaces (MyComputer, MyDocuments, Recyclebin, network neighbourhood, Internet Explorer, and Control panel) are all accessed through this registry scheme :
HKEY_LOCAL_MACHINE
Software
Microsoft
Windows
CurrentVersion
Explorer
Virtual Folder Name
Namespace
{Extension CLSID}
sometimes it helps to look at the IL generated code
a MS guy on develop.com "answering" .NET issues
|
|
|
|
|
StephaneRodriguez wrote:
In short, default namespaces (MyComputer, MyDocuments, Recyclebin, network neighbourhood, Internet Explorer, and Control panel) are all accessed through this registry scheme :
You may use this to get some of them Environment.SpecialFolder with GetFolderPath from Environment namespace.
Best Regards,
Laurent Kempé [Microsoft .NET MVP]
Visit my web site Tech Head.
---
Old programmers never die, they just branch to a new address.
|
|
|
|
|
Thanks for the feedback Laurent and Stephane, I am familiar with both of the methods provided, but both methods only provide me with a string path, not a Shell32.FolderItem object, which is what I need.
Of course, if I knew how to create a Shell32.FolderItem object from a string path, then both methods would work just fine, and my problem would be solved
|
|
|
|
|
Hi,
This is an excellent tree control.
Here is a simple way to display "Control panel" also in the tree control...
All one has to do is simply comment out this line
if(item.IsFileSystem && item.IsFolder && item.IsBrowsable)
in the ExpandBranch method of ShellOperations
class . Of course selecting control panel in this tree control may have some wanted/unwanted behaviour..
Cheers
|
|
|
|
|