Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Shell Objects with different immediate parents

263 views
Skip to first unread message

Jim

unread,
Oct 16, 2006, 2:57:39 PM10/16/06
to

I just realized that the Search Explorer creates a data object that has
the desktop as the root and absolute PIDLs for the various objects in
the search. This works just fine if I create my own IDataObject from
scratch and add in HDrop and ShellIDList formats.

I am not trying to modify my shell library to have the
IShellFolder.GetUIObjectOf return an object that supports this same
feature. What I did was get the IShellFolder of the desktop and add
AbsolutePIDLs of objects in various location (files actually) and had
it create an IShellFolder and IContextMenu. Both succeded and gave me
an object. The problem is the IDataObject contains no shell clipboard
formats and when I IContextMenu.InvokeCommand beeps and fails.

Is this suppose to be supported?

Thanks,
Jim
--
www.mustangpeak.net

Jim

unread,
Oct 16, 2006, 6:54:09 PM10/16/06
to

> I am not trying to modify my shell library to have the
> IShellFolder.GetUIObjectOf return an object that supports this same

Sorry, I AM trying to modify......


Jim
--
www.mustangpeak.net

Jim Barry

unread,
Oct 17, 2006, 6:18:27 AM10/17/06
to
Jim wrote:
> What I did was get the IShellFolder of the desktop and add
> AbsolutePIDLs of objects in various location (files actually) and had
> it create an IShellFolder and IContextMenu. Both succeded and gave me
> an object. The problem is the IDataObject contains no shell clipboard
> formats and when I IContextMenu.InvokeCommand beeps and fails.
>
> Is this suppose to be supported?

No. As the GetUIObjectOf doc says, each ITEMIDLIST must contain a single item. The "Find" folder uses CDefFolderMenu_Create2Ex (similar to CDefFolderMenu_Create2) and SHCreateFileDataObject (exported but not documented).

--
Jim Barry, MVP (Windows SDK)

Jim

unread,
Oct 17, 2006, 8:49:27 AM10/17/06
to

Thanks Jim,


> No. As the GetUIObjectOf doc says, each ITEMIDLIST must contain a

Yea but the docs say a "lot of things" :^)

> single item. The "Find" folder uses CDefFolderMenu_Create2Ex (similar
> to CDefFolderMenu_Create2) and SHCreateFileDataObject (exported but
> not documented).

SHCreateFileDataObject - I don't see that in the SDK (not the latest I
have it just not installed yet). Do you have the prototype for that
function? I see the value is 740. I will need to convert it to Delphi.

CDefFolderMenu_Create2Ex - Can you peel back the onion a bit more here,
I am not a C guy. What does this class do internally to work with the
shell and files?

Thanks,
Jim
--
www.mustangpeak.net

JimKueneman

unread,
Oct 17, 2006, 12:49:01 PM10/17/06
to

"Jim" wrote:

> SHCreateFileDataObject - I don't see that in the SDK (not the latest I
> have it just not installed yet). Do you have the prototype for that
> function? I see the value is 740. I will need to convert it to Delphi.
>
> CDefFolderMenu_Create2Ex - Can you peel back the onion a bit more here,
> I am not a C guy. What does this class do internally to work with the
> shell and files?

Never mind I thought this was some MFC thing, not an exported function.
Still the prototype of SHCreateFileDataObject would be helpful.

Jim

>
> Thanks,
> Jim
> --
> www.mustangpeak.net
>

Jim Barry

unread,
Oct 18, 2006, 7:23:36 AM10/18/06
to
JimKueneman wrote:
> Never mind I thought this was some MFC thing, not an exported
> function. Still the prototype of SHCreateFileDataObject would be
> helpful.

Same as CIDLData_CreateFromIDArray except with an extra IDataObject pointer (which can be null) before the final [out] parameter. Note that it only appears in XP onwards.

Jim

unread,
Oct 18, 2006, 7:33:34 AM10/18/06
to
Jim Barry wrote:

Ah, ok so it would be better to implement this myself for better
compatibility with older OS's.

Is the paremeter list for CDefFolderMenu_Create2Ex the same as
CDefFolderMenu_Create2 and do you know the OS support for these?

Thanks,
Jim
--
www.mustangpeak.net

Jim Barry

unread,
Oct 18, 2006, 8:00:03 AM10/18/06
to
Jim wrote:
> Is the paremeter list for CDefFolderMenu_Create2Ex the same as
> CDefFolderMenu_Create2 and do you know the OS support for these?

Looks like Win98/Win2k onwards (as well as the NT4 "Active Desktop update").

Jim Barry

unread,
Oct 18, 2006, 8:25:04 AM10/18/06
to
Jim wrote:
> Is the paremeter list for CDefFolderMenu_Create2Ex the same as
> CDefFolderMenu_Create2 and do you know the OS support for these?

Sorry, CDefFolderMenu_Create2Ex isn't actually exported. You can generally figure out which functions are available in which versions using Geoff Chappell's excellent survey:

http://members.ozemail.com.au/~geo...@ozemail.com.au/samples/win32/shell/shell32/index.html

Jim

unread,
Oct 18, 2006, 8:39:07 AM10/18/06
to

> Sorry, CDefFolderMenu_Create2Ex isn't actually exported. You can
> generally figure out which functions are available in which versions
> using Geoff Chappell's excellent survey:
>
> http://members.ozemail.com.au/~geo...@ozemail.com.au/samples/win32/sh
> ell/shell32/index.html


Nice. thanks

Jim
--
www.mustangpeak.net

JimKueneman

unread,
Oct 20, 2006, 10:16:02 AM10/20/06
to

Hi Jim,

I am getting close. A couple of questions.

1) I can't get the menu to have the "Rename" item. I am not calling this
function from within a NSE I am calling it in response to a file search and I
have several file objects from various places in the shell namespace. For
the parameters of CDefFolderMenu_Create2 I am doing the following:

pidlFolder = PIDL of the desktop folder
wnd = HWnd of the window that is displaying the files in my app
cidl = number of files in my list
apidl = cidl number of Absolute (from the desktop) PIDLs for each file
psf = my own implemention of IShellFolder
lpfn = my callback
nKeys = number of registry keys to add their context menu handler to the menu
ahkeyClsKeys = registry keys, I am currenlty playing with "*", "Directory",
"Folder", and "Directory\Background".

In my IShellFolder implementation I respond to GetUIObjectOf and return an
IDataObject fill in with CF_HDROP and CF_SHELLIDLIST with fully qualified
paths and IDLists (I know the IDataObject is correct because if I paste it to
the clipboard I can do shell operations using it from the clipboard). I also
return an IDropTarget to support the "Paste" menu item.

GetAttributesOf is next called with cidl set to the number of file. This is
one of the few time I have ever seen this set to anything other than 1. The
PIDLs are fully qualifed which in the help for IShellFolder it says this:

"apidl
[in] Address of an array of pointers to ITEMIDLIST structures, each of
which uniquely identifies an item relative to the parent folder. Each
ITEMIDLIST structure must contain exactly one SHITEMID structure followed by
a terminating zero."

So that is not true an implementation of GetAttributesOf must handle
muli-level PIDLs.

I have tried a couple of things. One is to use the IShellFolder of the
Desktop as a proxy in my IShellFolder implementation and pass the call to it.
It appears to work and the SFGAO_CANRENAME is set. I also just tried to
return $FF so everything is set but still no Rename in the menu.

Any thougths?

2) Where is the "Send To" menu extension so I can request that be added to
the menu?

Thanks.

Chuck Chopp

unread,
Oct 20, 2006, 11:37:52 AM10/20/06
to
JimKueneman wrote:

> 2) Where is the "Send To" menu extension so I can request that be added to
> the menu?

I had to tangle with this recently. "SendTo" is an actual folder under the
user's profile, same level as where "My Documents", "Desktop" and "Start
Menu" are located. You have to either place a shortcut [to an EXE or some
sort of handler] or else create a subfolder under it and populate a
desktop.ini file in the subfolder to turn it into a junction point for a
shell extension.


--
Chuck Chopp

ChuckChopp (at) rtfmcsi (dot) com http://www.rtfmcsi.com

RTFM Consulting Services Inc. 864 801 2795 voice & voicemail
103 Autumn Hill Road 864 801 2774 fax
Greer, SC 29651

"Racing to save lives"
The Leukemia & Lymphoma Society - Team in Training
http://www.active.com/donate/tntsc/tntscCChopp

Do not send me unsolicited commercial email.

JimKueneman

unread,
Oct 20, 2006, 1:25:01 PM10/20/06
to

First thanks Chuck.

Second I have figured (1) out, I forgot to set the CMF_CANRENAME flag in the
call to IContextMenu.QueryContextMenu.


Jim

Jim

unread,
Oct 22, 2006, 10:23:38 PM10/22/06
to

> single item. The "Find" folder uses CDefFolderMenu_Create2Ex (similar
> to CDefFolderMenu_Create2) and SHCreateFileDataObject (exported but

I have this working for Find type PIDLs. Now I want to make a menu for
the background of a Listview and I am struggling on the paremeter list.

function(pidlFolder: PItemIdList; wnd: HWnd; cidl: uint; var apidl:
PItemIdList; psf: IShellFolder; lpfn: TFNDFMCallback; nKeys: UINT;
ahkeyClsKeys: PHKEY; var ppcm : IContextMenu): HRESULT; stdcall;

If I am getting a background menu for the root folder of a listview
view how should I fill this in so it will add the Paste, Paste Link,
and Properites items.

I tried to pass pidlFolder as the parent of the current folder with
apidl as the folder that has its contents in the listview. That gets
me the menu for the pidlFolder. Anyone know how this should be handled?

Thanks,
Jim
--
www.mustangpeak.net

Jim Barry

unread,
Oct 23, 2006, 6:53:43 AM10/23/06
to
JimKueneman wrote:
> GetAttributesOf is next called with cidl set to the number of file.
> This is one of the few time I have ever seen this set to anything
> other than 1. The PIDLs are fully qualifed which in the help for
> IShellFolder it says this:
>
> "apidl
> [in] Address of an array of pointers to ITEMIDLIST structures,
> each of which uniquely identifies an item relative to the parent
> folder. Each ITEMIDLIST structure must contain exactly one SHITEMID
> structure followed by a terminating zero."
>
> So that is not true an implementation of GetAttributesOf must handle
> muli-level PIDLs.

Read it again ;-) It's being called for multiple items, but each item should still be an immediate child of the folder (i.e. each ID-list contains a single ID).

> 2) Where is the "Send To" menu extension so I can request that be
> added to the menu?

Microsoft SendTo Service {7BA4C740-9E81-11CF-99D3-00AA004AE837}. It is registered under the AllFilesystemObjects key.

Jim Barry

unread,
Oct 23, 2006, 7:12:32 AM10/23/06
to
Jim wrote:
> If I am getting a background menu for the root folder of a listview
> view how should I fill this in so it will add the Paste, Paste Link,
> and Properites items.

I think you will need to add your own Properties item.

> I tried to pass pidlFolder as the parent of the current folder with
> apidl as the folder that has its contents in the listview.

You might try the current folder for pidlFolder and 0/NULL for cidl/apidl.

Jim

unread,
Oct 23, 2006, 8:38:57 AM10/23/06
to

> > So that is not true an implementation of GetAttributesOf must handle
> > muli-level PIDLs.
>
> Read it again ;-) It's being called for multiple items, but each item
> should still be an immediate child of the folder (i.e. each ID-list
> contains a single ID).

But if this is how you handle a "Find.." action with object from all
over the namespace you can not use a parent and single item IDLIST
array. The shells implementation of GetAttributes of works if IDLIST
array contains fully qualified PIDLs to each object in my Find list.
The reason I went down this path is because if you look at the
IDataObject of the objects in a shell search they are fully qualified
PIDLs with the parent being the desktop.

Jim
--
www.mustangpeak.net

Jim Barry

unread,
Oct 23, 2006, 3:57:11 PM10/23/06
to
Jim wrote:
> But if this is how you handle a "Find.." action with object from all
> over the namespace you can not use a parent and single item IDLIST
> array. The shells implementation of GetAttributes of works if IDLIST
> array contains fully qualified PIDLs to each object in my Find list.

Sorry, I completely misunderstood you. So you are saying your extension is called with fully qualified ID-lists? I am puzzled by this, as the desktop's GetAttributesOf method doesn't support multi-level ID-lists. It doesn't actually fail, but returns the attributes of the first item in the ID-list. For example, for filesystem items it always returns 0xb0000174, the attributes of "My Computer". What kind of junction point does your extension have?

Jim

unread,
Oct 23, 2006, 9:30:51 PM10/23/06
to

> Sorry, I completely misunderstood you. So you are saying your
> extension is called with fully qualified ID-lists? I am puzzled by
> this, as the desktop's GetAttributesOf method doesn't support
> multi-level ID-lists. It doesn't actually fail, but returns the
> attributes of the first item in the ID-list. For example, for
> filesystem items it always returns 0xb0000174, the attributes of "My
> Computer". What kind of junction point does your extension have?

Sorry Jim I keep jumping back and forth between two different ideas,
let me clarify.

1) I am not creating an NSE. I have a set of components that mimic
explorers listview and treeview. So what I am trying to do first is
mimic the menu when I click on the background of the listview. What I
am trying here is to let the shell do as much of the work as possible.
What I expect is when I pass the PIDL for the Folder in the first
parameter and NULL for the IDList and IShellFolder in the
CDefFolderMenu_Create2 call that the function will create an
IShellFolder object for that folder, query for and IDataObject and call
GetAttributesOf to decide what menu items can be added to the context
menu. As it stands all it contains is the shell extensions that I have
added via the ahkeyClsKeys parameter. I can support IShellFolder
myself via the psf parameter and handle the calls to create the
DataObject and the DropTarget objects then respond to the
GetAttributesOf and return the correct flags to add the correct menu
items but I am trying to get the function and the shell to do all this
for me.

2) The second thing I want to accomplish is to use this function to
handle a Search list of PIDLs from different folders. This I know I
have to override much of the built in functionality and do the actions
myself. As far as GetAttribuesOf working with multi-level PIDLs, I am
jumping to a conclusion in that if I handle the response to
GetUIObjectOf for the IDataObject and fill it in like Explorer does on
a search window, parent = destop and files = fully qualified PIDLs and
full paths in HDrop, then when GetAttributesOf is called it is called
with these full PIDLs that I filled in to the IDataObject. When I pass
those fully qualified PIDLs to the Desktops GetAttributes of I get
something back (My IShellFolder is a proxy for an IShellFolder object
based off the desktop so I can intercept calls to the methods before
passing them to the desktop IShellFolder interface). I assumed it
succeeded as it did not throw and error and sent me back set flags. I
may be off track based on what you said, I did not verify that the
results made sense or were for the correct objets. I guess I have to
take the fully qualified PIDLs that are passed and do my own validation
of what flags should be set in GetAttribuesOf

Does that help?
Jim
--
www.mustangpeak.net

Jim Barry

unread,
Oct 25, 2006, 9:09:29 AM10/25/06
to
Jim wrote:
> Sorry Jim I keep jumping back and forth between two different ideas,
> let me clarify.

OK, regarding point 1, the DefView's background menu is a composite menu comprising the DefView's own private menu and the menu of the folder (obtained via CreateViewObject). So basically, if you're not hosting the DefView then you're on your own here.

Regarding point 2, if you want to get the attributes for a fully qualified ID-list you are going to have to bind to the parent folder of the item first.

0 new messages