Article View: borland.public.cppbuilder.nativeapi
Article #14218Re: How to determine folder type from PIDL?
From: Martin Nijhoff
Date: Thu, 21 Aug 2003 10:08
Date: Thu, 21 Aug 2003 10:08
90 lines
5549 bytes
5549 bytes
> What EXACTLY are you trying to determine? Please provide an actual
example.
Here is the whole story of what I am trying to do (sorry for the length of
it):
I am populating a tree view component derived from TTreeView, with local and
network folders, like the Windows Explorer does.
I start with the desktop folder, which I retrieve using
SHGetDesktopFolder(). Using IShellFolder::EnumObjects(), I add all the
subfolders of the desktop folder as child nodes to the tree. For each of
these subfolders, I bind to the subfolder using IShellFolder::BindToObject()
and do an EnumObjects() on it. For each node that is added to the tree, I
store the relative PIDL of the folder in relation to its parent folder (in
the Data member of TTreeNode) and the type of folder (for example 'virtual
folder', 'network node', etc.).
An example of the tree looks like this:
- Desktop (type='desktop')
+- My computer (type='my computer')
| +- Windows 98 (C:) (type='folder')
| +- Data (D:) (type='folder')
+- Network neighborhood (type='net hood')
+- Entire network (type='entire network')
| +- Workgroup 1 (type='workgroup')
| | +- User (type='network node')
| | +- Share (type='folder')
| +- Workgroup 2 (type='workgroup')
+- User (type='network node')
+- Share (type='folder')
To complicate things, in Windows XP there is another 'level' between 'Entire
network' and the workgroups:
+- Network neighborhood (type='net hood')
+- Entire network (type='entire network')
| +- Microsoft terminal services (type=?)
| +- Microsoft Windows network (type=?)
| | +- Workgroup 1 (type='workgroup')
| | | +- User (type='network node')
| | +- Workgroup 2 (type='workgroup')
| +- Web client network (type=?)
+- User (type='network node')
I added a property to the component that allows the user to add virtual
folders to the tree or to ignore virtual folders alltogether. Skipping
virtual folders on the local machine (listed under 'My computer') works
fine. However, skipping all virtual folders on the network (listed under
'Network neighborhood') leaves me with an empty 'Network neighborhood' node,
since all of its subfolders are virtual folders. Therefore, I would like to
distinguish between the different subfolders of 'Network neighborhood', so
that I can add the 'Entire network' node and the nodes for all the
workgroups, users and shares listed in it, but skip any virtual folders that
are located in the network shares or any of their subfolders.
How do I determine the type of folders in the network neighborhood?
This part describes a related problem which I posted earlier to this
newsgroup (see 'Getting PIDL for UNC path'):
I have also added a property to the component that can be used to get the
path name of the currently selected folder in the tree (when read from) or
to select a folder based on a certain path name (when written to). To get
the pathname, I use the relative PIDL that is stored with the currently
selected node and append the relative PIDL that is stored with its parent
node in front of it, and repeat this until I have an absolute PIDL for the
folder. Then I use IShellFolder::GetDisplayNameOf() to get the path name for
this absolute PIDL. This all works fine.
To select the node for a certain path name, I first break the path into
subfolder names and then traverse the tree, starting at the desktop node,
determine the relative PIDL of the subfolder using
IShellFolder::ParseDisplayName() and try to find a child node with the same
relative PIDL. Then I use IShellFolder::BindToObject() with the relative
PIDL and repeat the process for the next subfolder name, until the required
tree node is found and make it the active selection. This works fine on
local folders, but not on network folders, because
IShellFolder::ParseDisplayName() returns a PIDL that differs from the PIDL
that was returned by IShellFolder::EnumObjects() when populating the tree.
Also, when I combine all the relative PIDLs I obtained in the way I
described above, into an absolute PIDL, then this is identical to the
absolute PIDL that is returned by IShellFolder::ParseDisplayName() when I
supply it the absolute path name to the folder. So it doesn't matter if I
use a number of relative path names or a single absolute path name in
obtaining the PIDL, it still differs from the PIDL stored in the tree.
What am I doing wrong? Is there a workaround?
Technical Details
Message-ID:
<3f449de7@newsgroups.borland.com>Path:
arc1-ca.pugleaf.net!archiver1.google.com!news1.google.com!sn-xit-02!sn-xit-06!sn-xit-08!supernews.com!newsfeed.wirehub.nl!news.kweb.on.ca!KWeb!newsgroups.borland.com!not-for-mailReferences:
<3f3782b0@newsgroups.borland.com> <s8ffjvkf7v1t1o8cjs4m3seh824k3m0nes@4ax.com> <3f4090a4$1@newsgroups.borland.com> <3f410dc3@newsgroups.borland.com>Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 10cc67,f3af26e9e5d9f602 X-Google-Attributes: gid10cc67,public X-Google-ArrivalTime: 2003-08-21 03:27:20 PST From: "Martin Nijhoff" <dont@mail.me> Newsgroups: borland.public.cppbuilder.nativeapi References: <3f3782b0@newsgroups.borland.com> <s8ffjvkf7v1t1o8cjs4m3seh824k3m0nes@4ax.com> <3f4090a4$1@newsgroups.borland.com> <3f410dc3@newsgroups.borland.com> Subject: Re: How to determine folder type from PIDL? Date: Thu, 21 Aug 2003 12:08:05 +0200 Lines: 92 X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 6.00.2600.0000 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2600.0000 NNTP-Posting-Host: 81.68.1.114 Message-ID: <3f449de7@newsgroups.borland.com> X-Trace: newsgroups.borland.com 1061461479 81.68.1.114 (21 Aug 2003 03:24:39 -0700) Path: arc1-ca.pugleaf.net!archiver1.google.com!news1.google.com!sn-xit-02!sn-xit-06!sn-xit-08!supernews.com!newsfeed.wirehub.nl!news.kweb.on.ca!KWeb!newsgroups.borland.com!not-for-mail