Shell Namespace

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Shell Namespace

Louis Sumberg-2
I'm looking for some help or pointers here.  I want to put the functionality
of BrowseFolderDialog in a non-modal treeview, a la the left side of Windows
Explorer.

 From reading MSDN, it seems like IShellFolder is where to, in proper
parlance, navigate the shell namespace.  From MSDN, "The simplest way to
start is to have your application call SHGetDesktopFolder to retrieve the
desktop's IShellFolder interface. Then, to navigate downward through the
namespace, your application can follow these steps:
  1. Enumerate the folder's contents.
  2. Determine which objects are subfolders, and select one.
  3. Bind to the subfolder to retrieve its IShellFolder interface.
Repeat these steps as often as necessary to reach the target."

Per a 2/29/99 post by Blair, evaluating "pDesktopFolder := ShellLibrary
default getDesktopFolder" returns an IShellFolder instance.  This instance
represents the namespace root, the desktop.  Proceding with #1 just above,
again from MSDN, "Enumerating the Contents of a Folder:  The first thing you
usually want to do with a folder is to find out what it contains. You must
first call the folder's IShellFolder::EnumObjects method. The folder will
create a standard OLE enumeration object and return its IEnumIDList
interface. This interface exposes four standard methods-Clone, Next, Reset,
and Skip-that can be used to enumerate the contents of the folder.  The
basic procedure for enumerating a folder's contents is:
  1. Call the folders IShellFolder::EnumObjects method to retrieve a pointer
to an enumeration object's IEnumIDList interface.
  2.  Pass an unallocated PIDL to IEnumIDList::Next. Next takes care of
allocating the PIDL, but the application must deallocate it when it is no
longer needed. When Next returns, the PIDL will contain just the object's
item ID and the terminating NULLs. In other words, it is a single-level
PIDL, relative to the folder, not a fully-qualified PIDL.
  3. Repeat step 2 until Next returns S_FALSE to indicate that all items
have been enumerated.
  4. Call IEnumIDList::Release to release the enumeration object."

I see that IShellFolder has a method #EnumObjects:grfFlags:ppenumIDList:,
but how to use it, I don't know.  It looks like the first parameter (a
Windows handle) can be nil, and the flags parameter can be some number
(0,1,2, etc -- I don't have the actual enumeration constants definitions),
but the third parameter, ppenumIDList, an "address that receives a pointer
to the IEnumIDList interface of the enumeration object created by this
method", egads.  I see that class IENumXXX responds to #clone, #next, #reset
and #skip, so I figured there's some sort of connection between that and the
IEnumIDList interface.

I'm basically spinning my wheels at this point.  Has anyone implemented this
functionality?  If not, any pointers on how to proceed would be greatly
appreciated.

-- Louis


Reply | Threaded
Open this post in threaded view
|

Re: Shell Namespace

Bill Schwab
Louis,

> I see that IShellFolder has a method #EnumObjects:grfFlags:ppenumIDList:,
> but how to use it, I don't know.  It looks like the first parameter (a
> Windows handle) can be nil, and the flags parameter can be some number
> (0,1,2, etc -- I don't have the actual enumeration constants definitions),
> but the third parameter, ppenumIDList, an "address that receives a pointer
> to the IEnumIDList interface of the enumeration object created by this
> method", egads.  I see that class IENumXXX responds to #clone, #next,
#reset
> and #skip, so I figured there's some sort of connection between that and
the
> IEnumIDList interface.
>
> I'm basically spinning my wheels at this point.  Has anyone implemented
this
> functionality?  If not, any pointers on how to proceed would be greatly
> appreciated.

Start with Dolphin's EnumRECT sample, which appears to be installed under
the Samples directory in 4.0.  Look at that, and you'll know more than I do
:)

Have a good one,

Bill

--
Wilhelm K. Schwab, Ph.D.
[hidden email]


Reply | Threaded
Open this post in threaded view
|

Re: Shell Namespace

Louis Sumberg-2
Bill,

> Start with Dolphin's EnumRECT sample, which appears to be installed under
> the Samples directory in 4.0.  Look at that, and you'll know more than I
do
> :)

Thanks for the pointer.  I looked at it -- Isn't that about creating COM
servers?  ... as opposed to using an existing COM server (IShellFolder
interface).  (Hmm, like I know what I'm talking about.)  I'll be posting
something soon along another path I'm trying to tread.

-- Louis


Reply | Threaded
Open this post in threaded view
|

Re: Shell Namespace

Louis Sumberg-2
In reply to this post by Louis Sumberg-2
As a followup to my last post on navigating the Shell namespace, I didn't
get far, but here's what I have in a workspace:

"Return an IShellFolder instance that points to the desktop folder."
pDesktopFolder := ShellLibrary default getDesktopFolder.

"Allocate a pointer to external memory for the 'enumeration object'."
enumAddress := WindowsShellMemory new.

"Set flags for the enumeration."
grfFlags := 32 | 64 | 128. "folders, includeHidden, nonFolders"

"Set enumAddress to, per MSDN, 'Address that receives a pointer to the
IEnumIDList interface of the enumeration object created by this method
[IShellFolder::EnumObjects]'.  Answer 0 if successful."
result := pDesktopFolder EnumObjects: nil grfFlags: grfFlags ppenumIDList:
enumAddress.

"Return an IEnumIDList instance based on enumAddress."
iEnumIDList := IEnumIDList fromAddress: enumAddress.

"Start enumerating folders.  Return an instance of ITEMIDLIST."
itemIDList := iEnumIDList nextAvailable.

"Create STRRET structure to hold folder's display name."
strret := STRRET new uType: 2. "uType = 2 means return string in STRRET
cStr"

"Get display name."
pDesktopFolder GetDisplayNameOf: itemIDList uFlags: 1 lpName: strret.

The last line returns a walkback with "The parameter is incorrect" which
makes some sense, considering lpvoids are expected for the first and third
parameters.  I tried passing them in with asParameter and then with
yourAddress but got the same walkback.

Some more info:  I found a type library on the Net (from the CCRP project)
and used that to generate the classes for IEnumIDList, ITEMIDLIST, STRRET,
and SHITEMID (just don't try to say that last one out loud).  The package
with these classes is at
http://www.mindspring.com/~lsumberg/Dolphin/LasShellAddons.pac.

Methods I added (in the package) are:
  IEnumIDList class>>elementClass, which returns ITEMIDLIST.
  IEnumIDList>>newElement, which returns ITEMIDLIST new: 264.  I know this
is hokey, but without ": 264" I get a walkback "Invalid access to memory
location.  Reading ..."  At least this kept me alive for another line or two
of code.
  IEnumIDList>>nextAvailable, which I just copied from IEnumXXX.
  ITEMIDLIST>>new, which returns a pointer.

Bottom line is the wheels are still spinning but I'm stumped, in this just
and noble cause.

-- Louis


Reply | Threaded
Open this post in threaded view
|

Re: Shell Namespace

Louis Sumberg-2
I tried "translating" some C examples (in MSDN and on the Net) into Dolphin.
One is at http://www.mindspring.com/~lsumberg/Dolphin/EnumerateFolders1.rtf.
I copied the MSDN text into a workspace and then constructed the Dolphin
equivalent, interspersed between the C code.  The rtf file can be opened in
a workspace and the code viewed and evaluated there.  The C code is all in
red.  The Dolphin code and comments are in the familiar black, blue and
green.

The class definition for IEnumIDList, is at
http://www.mindspring.com/~lsumberg/Dolphin/IEnumIDList.cls.  This is a
plain vanilla wrapper (around the COM interface IEnumIDList) that was
generated from a typelib.

I'm not sure what my question is, other than "How come it doesn't work?"  It
could be a case of Pointer Disorder Syndrome.  The comments sort of indicate
what I think is going on and show where it bombs.

This time around I just used the structures (i.e., IEnumIDList in this
example) generated by Dolphin through the typelib.  I was hoping that using
WindowsShellMemory as a pointer would be sufficient, used in combination
with other Windows methods that would extract the "real" values.  I suspect
that the first few lines are ok, but that ppenum, isn't really doing the
trick.  I'm hoping that someone who knows C and COM can take a look and help
here.

Thanks in advance.

-- Louis