|
I just try your way to implement these codes, but I get the result as the previous.
so could you tell me how to do it.
thx in advance!
silas
|
|
|
|
|
Is there a way to extarct the files while drilling the tree?
|
|
|
|
|
I too would like to see an example on how to incorporate files into this control. I've been trying my best, but haven't got very far. I'm new to C# so it's kind of a struggle. I'm used to programming in ColdFusion for websites, and this is quite a change. Any help would be appreciated!
Thanks!
|
|
|
|
|
Hello again!
OK, this is a wierd one. I've set up the tree view control as part of a tab page, namely the first tab page. Everything was working fine until I added a tab page before the page with the tree view.
In the first case, the event handler fires FIRST when the form.Show() occurs, then my code drills down to a path.
Once I added the new tab, the event doesn't fire, which screws up my drill down call. The event fires ONLY when the tab page finally gets focus.
Good grief. Any ideas on how to get things properly initialized without relying on the focus mechanism? I'm a bit clueless right now.
[edit]
My only solution is to track the state of the ...Cancel event:
private void TreeViewBeforeExpand(object sender, System.Windows.Forms.TreeViewCancelEventArgs e)
{
this.BeginUpdate();
ShellOperations.ExpandBranch(e.Node, this.ImageList, showFoldersOnly);
this.EndUpdate();
if (beforeExpandFired==false)
{
beforeExpandFired=true;
if (drillToFolder != null)
{
DrillToFolder(drillToFolder);
}
}
}
public bool DrillToFolder(string folderPath)
{
if (!beforeExpandFired)
{
drillToFolder=folderPath;
return false;
}
...
}
[/edit]
Marc
STL, a liability factory - Anonymously A doable project is one that is small enough to be done quickly and big enough to be interesting - Ken Orr
Latest AAL Article
My blog
|
|
|
|
|
Sorry for the problems Marc, as I've said (too many times) before, this control has undergone dramatic changes since it's last posting but I just haven't had the time to write new article and clean/comment the code for CP distribution.
The update version has the following changes:
- Uses the System Image List directly, rather than fetching individual icons and populating a WinForms ImageList.
- Uses threading for populating / expanding Nodes
- Implements ISupportInitialize so there's no need to call an init function in order top populate the tree
- Includes a designer class
- Exposes new events and provides accessors for path properties rather than relying on methods
- Autmotically refreshes nodes in response the FileSystemWatcher events on NT/2K/XP systems(Not yet finished)
I downloaded this old class again today, and have to admit it's quite sad when compared to the current version. I have lots on my plate ATM, but will definately try to update this article soon. If you like I can email you the new code once I've completed the refresh code..
I will also run tests on your problem scenario and ensure it has been addressed before the next release.
|
|
|
|
|
Ooooh. I am drooling!
Furty wrote:
If you like I can email you the new code once I've completed the refresh code..
Definitely!
Looking forward to the update. I know what you mean about finding time to get things done!
Marc
STL, a liability factory - Anonymously A doable project is one that is small enough to be done quickly and big enough to be interesting - Ken Orr
Latest AAL Article
My blog
|
|
|
|
|
Don't want to rush you but your update sounds like it will greatly improve the control. Is there any way that a very impatient person like myself could get a preview version?
If so, jmcpher@clemson.edu; if not, any kind of ETA?
Either way, thanks for your great contribution to free code.
-John
|
|
|
|
|
Hi Furty,
Great code. I'm using it for a prototype project in the AAL. I made a couple modifications to also display files, which was easy to do. The performance is awful though--is the C#, the interop, or something else?
Also, since there are different versions of shell32.dll on different machines, how do I bind to this at runtime instead of at design time using "add COM reference"?
Thanks!
Marc
STL, a liability factory - Anonymously A doable project is one that is small enough to be done quickly and big enough to be interesting - Ken Orr
Latest AAL Article
My blog
|
|
|
|
|
Hi Marc, the 3 major performance limitations of this code are:
1) Heavy use of interop
2) On loading, it scans CD/DVD drives to check for root folders
3) Heavy use of interop
I have made some substantial improvements to this code since it was published here, but I just haven't the time to update the article - you'd as good as anyone how much time it takes to write an article for CP.. I hope to get around to it within the next few weeks, but can't make any promises.
On the subject of shell32.dll binding, I don't quite follow - AFAIK the generated Interop.Shell32.dll should not be dependant on any particular Shell32 version, and my code doesn't call any Shell32 methods that don't exist in early versions. Basically, if the system can run .Net it should be able to run this code as is - have you found otherwise?
|
|
|
|
|
I've just taken another look at the Interop.Shell32.dll and now see what you mean - my apologies. Even still, the code should still run on any .Net'able Windows system - are you having problems?
|
|
|
|
|
Hi Furty,
Thanks for digging further. Take a look at this message (and the preceding ones) on the AAL article I posted.
http://www.codeproject.com/csharp/aal-5a.asp#xx546661xx[^]
Any insights?
BTW, I'd love to test out your improvements when you feel ready.
Sorry for the long delay in getting back to you.
Marc
STL, a liability factory - Anonymously A doable project is one that is small enough to be done quickly and big enough to be interesting - Ken Orr
Latest AAL Article
My blog
|
|
|
|
|
I'd be interested in seeing the code updates as well.
Thanks...
|
|
|
|
|
Me too. I can't wait! I already rewrote the control: now it uses a system image list, and is only one class. But still, I'd like to see your new code, so I could improve mine.
B.t.w., by using a system image list, you don't need a manifest to let the treeview display the icons with the Windows XP shadow.
We are all men, except for the woman.
|
|
|
|
|
Hi Daniël,
Is it possible for you to send the piece of code you used for getting and attaching the system imagelist to the control?
I have developped a Shell List View Control like the one in Windows Explorer but actually i'm getting the icon of each file and it becomes very slow in large folders.
Thank you.
|
|
|
|
|
jgauthier wrote:
Is it possible for you to send the piece of code you used for getting and attaching the system imagelist to the control?
I used the system image list class, as written by Steve McMahon, here: http://www.vbaccelerator.com/home/NET/Code/Libraries/Shell_Projects/SysImageList/article.asp[^].
Then, reference Shell32.dll, and:
private SysImageList m_imlSmall;
m_imlSmall = new SysImageList(SysImageListSize.smallIcons);
SysImageListHelper.SetListViewImageList(this, m_imlSmall, false);
public void AnyMethod(string fldrpath){
Shell32.Shell shell = new Shell32.ShellClass();
Shell32.Folder folder = shell.NameSpace(fldrpath);
Shell32.FolderItem fldritem = GetFolderItem(folder);
item.ImageIndex = m_imlSmall.IconIndex(fldritem.Path, true);
}
I used this articles FolderTreeView control for the Shell32 code.
Good luck!
- Daniël
We are all men, except for the woman.
|
|
|
|
|
I would love to see how you implimented displaying files with this control. I've been picking around trying to get something to work, but I'm at a loss. If anyone could help I would be greatly appreciated!
Thanks,
Jason
|
|
|
|
|
How do I get this control to appear in design view? I keep on getting HRESULT 0x80131019 errors.
|
|
|
|
|
Hi there
Sorry, but just after I submited this message, I found some major mistakes in the code.
In GetFolderItemFromFolder I did not handle the COM refferance correctly. This is how it should be:
public static Shell32.FolderItem GetFolderItemFromFolder(Shell32.Folder folder)
{
if(folder != null)
{
try
{
IntPtr fldPtr = Marshal.GetComInterfaceForObject(folder, typeof(Shell32.Folder2));
try
{
Shell32.Folder2 fldr2 = (Shell32.Folder2)Marshal.GetObjectForIUnknown(fldPtr);
try
{
return fldr2.Self;
}
finally
{
Marshal.ReleaseComObject(fldr2);
}
}
finally
{
Marshal.Release(fldPtr);
}
}
catch{}
}
return null;
}
There are few mistakes in the DrillTreeByFolderList function (due to some last minute change). So this is the code that will compile:
private TreeNode DrillTreeByFolderList(TreeNodeCollection tnLst, ArrayList folderList)
{
Shell32.Folder seekFolder = folderList[folderList.Count - 1] as Shell32.Folder;
folderList.RemoveAt(folderList.Count - 1);
string s1 = seekFolder.Title;
Shell32.FolderItem seekFldItem = ShellOperations.GetFolderItemFromFolder(seekFolder);
if(seekFldItem != null)
s1 = seekFldItem.Name;
foreach(TreeNode tn in tnLst)
{
Shell32.FolderItem curFolder = (Shell32.FolderItem)tn.Tag;
string s2 = curFolder.Name;
if((String.Compare(s1, s2, true) == 0))
{
tn.Expand();
if(folderList.Count > 0)
return DrillTreeByFolderList(tn.Nodes, folderList);
else
return tn;
}
}
return null;
}
Ittay
|
|
|
|
|
Hi Furty
As far as I could see, no one gave the solution to the Folder --> FolderItem problem. The last I saw was the ParentFolder.Items loop.
Well, you where right, there is a shorter way, and it comes from using Shell32.dll version 5.0 or later on win-2000 & Millennium. (I see that the Interop.Shell32 you attached to the demo, is from this version).
So this is the function I added to the ShellOperations class in FolderTreeView.cs:
public static Shell32.FolderItem GetFolderItemFromFolder(Shell32.Folder folder)
{
if(folder != null)
{
try
{
IntPtr fldPtr = <a target=_blank title='New Window' href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemruntimeinteropservicesmarshalclassgetcominterfaceforobjecttopic.asp">Marshal.GetComInterfaceForObject</a>(folder, typeof(Shell32.Folder2));
Shell32.Folder2 fldr2 = (Shell32.Folder2)<a target=_blank title='New Window' href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemruntimeinteropservicesmarshalclassgetobjectforiunknowntopic.asp">Marshal.GetObjectForIUnknown</a>(fldPtr);
return <a target=_blank title='New Window' href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/objects/folder2/self.asp">fldr2.Self</a>;
}
catch{}
return null;
}
return null;
}
REMEMBER: This method might return null, if you do not have the right Shell32 version.
Now, that I have this short-cut, I changed the way DrillTree works.
The first change is in the way I think about locating the Tree-Path. I say, instead of looking from the root, lets start from the leaf.
We’ll get the folder using Shell.NameSpace, and fill a list with the Folder we found, and all its’ parent folders.
Then we’ll iterate backward in the list and forward in the tree, until we have the right node.
This is made out of two functions:
DrillToFolderByShell , replaces the original DrillToFolder we have now.
DrillTreeByFolderList , is the recursive TreeNode seek, the DrillToFolderByShell uses.
Both function are implemented in the FolderTreeView class .
DrillToFolderByShell:
public bool DrillToFolderByShell(string folderPath)
{
Shell32.Shell shell32 = new Shell32.ShellClass();
Shell32.Folder shell32Folder = shell32.NameSpace(folderPath);
if(shell32Folder != null)
{
ArrayList fullLst = new ArrayList();
fullLst.Add(shell32Folder);
Shell32.Folder par = shell32Folder.ParentFolder;
while(par != null)
{
fullLst.Add(par);
par = par.ParentFolder;
}
SelectedNode = DrillTreeByFolderList(Nodes, fullLst);
return SelectedNode != null;
}
else
throw new DirectoryNotFoundException("\"" + folderPath + "\" Not found");
}
DrillTreeByFolderList
private TreeNode DrillTreeByFolderList(TreeNodeCollection tnLst, ArrayList folderList)
{
Shell32.Folder seekFolder = folderList[titleList.Count - 1] as Shell32.Folder;
folderList.RemoveAt(titleList.Count - 1);
string s1 = seekFolder.Title;
Shell32.FolderItem seekFldItem = ShellOperations.GetFolderItemFromFolder(seekFolder);
if(seekFldItem != null)
s1 = seekFldItem.Name;
foreach(TreeNode tn in tnLst)
{
Shell32.FolderItem curFolder = (Shell32.FolderItem)tn.Tag;
string s2 = curFolder.Name;
if((String.Compare(s1, s2, true) == 0))
{
tn.Expand();
if(titleList.Count > 0)
return DrillTreeByTitleList(tn.Nodes, titleList);
else
return tn;
}
}
return null;
}
And this is it.
P.S. .NET 1.1 includes the DirectoryDialogBox, and I think that the Shell32 controls are close (if not included already). So all of this might be purely educational at the end.
Ittay
|
|
|
|
|
Thanks for the heads up Ittay, I will be updating the article and code as soon as I get through my current workload...
|
|
|
|
|
First of all, this is an excellent control. I have tested quite a few other folder tree view controls, but being a pure (more or less) .NET control, this one is really easy to extend and use in my .NET projects. Thanks, Furty!!
Now, there is a small issue with it; It lists all zip-files on my desktop. For all other folders, zip-files are not listed. (As far as I can tell...)
Is this a feature, bug or parameter that I have missed?
Best Regards,
Terje Krång, terje@dreamscape.no
|
|
|
|
|
Well, i cant answer to whether he deliberatley coded for this at all in his control. However, i can tell you that in WinXP, zip files are (for the most part) considered and treated as folders.
If you notice, when you dbl-click a zip, it opens a normal explorer window, not a zip program (unless youve changed that yourself).
This is probably why youre seeing this behaviour.
|
|
|
|
|
To stop zip files being listed under the Desktop node change line 452 from this:
if(item.IsFolder)
to this:
if( folderItem.IsFolder && !folderItem.IsBrowsable )
|
|
|
|
|
Could you explain how to use that Shell32.dll thing? I try to build a treeview control using your code you put up there, but I got a bunch of compile errors on Shell32. What reference should I have in order to use it?
Thanks.
|
|
|
|
|
Project -> Add Reference -> COM -> Browse (browse to C:\windows\system32\shell32.dll) select it, then compile
|
|
|
|
|