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
Sorry, I AM trying to modify......
Jim
--
www.mustangpeak.net
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)
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
"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
>
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.
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
Looks like Win98/Win2k onwards (as well as the NT4 "Active Desktop update").
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
Nice. thanks
Jim
--
www.mustangpeak.net
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.
> 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.
Second I have figured (1) out, I forgot to set the CMF_CANRENAME flag in the
call to IContextMenu.QueryContextMenu.
Jim
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
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.
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.
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
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
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.