blog: riddles in programming

Discussion & Support for xplorer² professional

Moderators: fgagnon, nikos, Site Mods

User avatar
nikos
Site Admin
Site Admin
Posts: 15759
Joined: 2002 Feb 07, 15:57
Location: UK
Contact:

Post by nikos »

thanks for the code Jim. It looks like you are adding a few extra keys like PerceivedType etc which must be vista only -- i can't find HKCR\FileSystemAssociations in XP

my hunch is that the type of menu commands and duplicates depend on the selection. If say you have selected a *.h and a *.cpp file, then you'll get some "duplicates" called OpenWithMSDEV but each belongs to a different filetype, so it is technically correct albeit lame!

I don't get crashes but some funny first chance exceptions errors in kernel32.dll on account of "invalid handles" when the IContextMenu is released. It looks like the magic number is 17: If i pass 17 registry keys or less to CDefFolderMenu_Create2 then all is fine, from 18 and up (ie more and diverse file types) I start getting these exceptions which can cause a crash too

this is regardless of using my "fake"/subclassed folder or not so it looks like a problem with CDefFolderMenu_Create2 which i'll report to m$ and see what they'll come up with
User avatar
TiKu
Member
Member
Posts: 22
Joined: 2005 Mar 18, 17:47
Location: Unterföhring, Germany
Contact:

Post by TiKu »

Is it really necessary to hook the desktop's IShellFolder and provide a custom data object? I just started to implement cross-namespace context menus, but so far I didn't came across the situation that the data object provided by the desktop doesn't contain correct CF_HDROP data. On the other hand I did not yet test on anything other than Windows XP SP2.

I plan to use SHCreateDefaultContextMenu on Vista, because according to the docs you can let this API search for the correct registry keys itself. Do you have any experience with it?

BTW, many thanks Jim and Nikos for sharing all these information.
(German translator of xplorer² and editor²)
www.timosoft-software.de - the home of ExplorerTreeView
User avatar
TiKu
Member
Member
Posts: 22
Joined: 2005 Mar 18, 17:47
Location: Unterföhring, Germany
Contact:

Post by TiKu »

I took RegMon and checked which parts of the registry Explorer is accessing when I right-click a *.bas file and a *.txt file out of different folders in the search pane (XP SP2).

Case 1) The *.bas file is focused. The following keys were accessed (I picked the important ones):
  1. HKCR\.bas
  2. HKCR\VisualBasic.Module
  3. HKCR\VisualBasic.Module\CurVer
  4. HKCR\SystemFileAssociations\.bas  <- not existing
  5. HKCR\SystemFileAssociations\application  <- not existing
  6. HKCR\*
  7. HKCR\AllFileSystemObjects
  8. --- I think at this point CDefFolderMenu_Create2 is called ---
  9. HKCR\.txt
  10. HKCR\txtfile
  11. HKCR\txtfile\CurVer
  12. HKCR\txtfile\shell and subkeys
  13. HKCR\SystemFileAssociations\.txt
  14. HKCR\.txt\PerceivedType
  15. HKCR\SystemFileAssociations\text
  16. HKCR\SystemFileAssociations\text\shell and subkeys
Those keys, whose shellex\ContextMenuHandlers subkeys were accessed by CDefFolderMenu_Create2, are highlighted green.
My code, which is just Jims code translated to C++, accesses these keys:
  1. HKCR\.bas
  2. HKCR\VisualBasic.Module
  3. HKCR\VisualBasic.Module\CurVer
  4. HKCR\SystemFileAssociations\.bas  <- not existing
  5. HKCR\*
  6. HKCR\AllFileSystemObjects
  7. --- at this point CDefFolderMenu_Create2 is called ---
  8. HKCR\SystemFileAssociations\.bas  <- not existing
  9. HKCR\SystemFileAssociations\application  <- not existing
  10. NOTE: For the *.txt file no key seems to be accessed.
Case 2) The same test with the *.txt file being focused.
  1. HKCR\.txt
  2. HKCR\txtfile
  3. HKCR\txtfile\CurVer
  4. HKCR\SystemFileAssociations\.txt  <- not existing
  5. HKCR\.txt\PerceivedType  <- fallback to extension key
  6. HKCR\SystemFileAssociations\text
  7. HKCR\*
  8. HKCR\AllFileSystemObjects
  9. --- I think at this point CDefFolderMenu_Create2 is called ---
  10. NOTE: For the *.bas file no key seems to be accessed.
My/Jims code:
  1. HKCR\.txt
  2. HKCR\txtfile
  3. HKCR\txtfile\CurVer
  4. HKCR\SystemFileAssociations\.txt
  5. HKCR\*
  6. HKCR\AllFileSystemObjects
  7. --- at this point CDefFolderMenu_Create2 is called ---
  8. HKCR\.txt\PerceivedType
  9. HKCR\SystemFileAssociations\text
  10. NOTE: For the *.bas file no key seems to be accessed.
So I think Jims code should be slightly modified.
1) If the file extension belongs to a file class (e. g. txtfile), the extension key (.txt) should NOT be passed to CDefFolderMenu_Create2.
2) The PerceivedType thing should be done before calling CDefFolderMenu_Create2 and the key should be passed. "application" might be a fallback perceived type. (I wonder why CDefFolderMenu_Create2 doesn't seem to try reading HKCR\.bas\PerceivedType)

I implemented both modifications and now I get exactly the same context menus like in search pane. Well, almost - the "rename" verb is missing for some reason.
Now let's hope the code also works for other combinations than *.bas/*.txt. ;)
(German translator of xplorer² and editor²)
www.timosoft-software.de - the home of ExplorerTreeView
User avatar
nikos
Site Admin
Site Admin
Posts: 15759
Joined: 2002 Feb 07, 15:57
Location: UK
Contact:

Post by nikos »

the problem is that bug when you supply 16+ registry keys, so you should be striving to make the keys you need less, not more!

regarding the CF_HDROP, i also sometimes saw it filled by the desktop's folder but try combining something from c:\ and something from d:\ !
User avatar
TiKu
Member
Member
Posts: 22
Joined: 2005 Mar 18, 17:47
Location: Unterföhring, Germany
Contact:

Post by TiKu »

nikos wrote:the problem is that bug when you supply 16+ registry keys, so you should be striving to make the keys you need less, not more!
Actually this limit can't even be reached. As Jim said, only the filetype of the focused item is relevant, not all filetypes. E. g. if you have selected the following files:
  • Readme.txt
  • stdafx.h
  • Logfile.log
  • Prices.pdf
and Readme.txt is the one you right-click, then you must pass the following keys to CDefFolderMenu_Create2 (you can verify this with RegMon and Windows Explorer):
  1. HKCR\txtfile
  2. HKCR\SystemFileAssociations\text
  3. HKCR\*
  4. HKCR\AllFileSystemObjects
That's far away from the limit of 16. Actually 6 is the maximum you'll reach.
nikos wrote:regarding the CF_HDROP, i also sometimes saw it filled by the desktop's folder but try combining something from c:\ and something from d:\ !
Works for me, but I'll check on Windows 2000. I'll have to hook IShellFolder anyway, because GetAttributesOf doesn't handle full pIDLs well (that's the reason why I don't get the "rename" menu item).
(German translator of xplorer² and editor²)
www.timosoft-software.de - the home of ExplorerTreeView
JimKueneman
Member
Member
Posts: 13
Joined: 2007 Aug 13, 04:40

Post by JimKueneman »

Thanks for digging into this more TiKu.  I will update my components.

Also you must add CMF_CANRENAME to the flags for QueryContextMenu to get the Rename.  You then need to see if the Verb is 'rename' and you are responsible for the rename, don't call InvokeCommand with this verb.

Jim
User avatar
TiKu
Member
Member
Posts: 22
Joined: 2005 Mar 18, 17:47
Location: Unterföhring, Germany
Contact:

Post by TiKu »

I'm currently testing on Vista. So far SHCreateDefaultContextMenu seems to work as expected. I set the punkAssociationInfo, cKeys and aKeys members of DEFCONTEXTMENU to 0 and it looks like the API really does the ugly registry stuff itself.

BTW, currently I'm not hooking the desktop's IShellFolder. The problem with the rename verb turned out to have another reason.
In Debug mode of my app I'll verify that the IDataObject provided by the desktop contains correct CF_HDROP data and throw an assertion if it does not. If I ever come across the situation that the CF_HDROP data is not right, I'll activate the hooking, but so far it seems to be unnecessary.
(German translator of xplorer² and editor²)
www.timosoft-software.de - the home of ExplorerTreeView
JimKueneman
Member
Member
Posts: 13
Joined: 2007 Aug 13, 04:40

Post by JimKueneman »

In Debug mode of my app I'll verify that the IDataObject provided by the desktop contains correct CF_HDROP data and throw an assertion if it does not. If I ever come across the situation that the CF_HDROP data is not right, I'll activate the hooking, but so far it seems to be unnecessary.
Make sure you try what nikos mentioned.  Get a file from two different volumes and make sure that works as well.  That is one place is use to fail (I have not revisited this since Vista I was working on XP, Win2k and Win98).

Jim
User avatar
TiKu
Member
Member
Posts: 22
Joined: 2005 Mar 18, 17:47
Location: Unterföhring, Germany
Contact:

Post by TiKu »

Strange... This afternoon I did test it with 2 files from different drives and it worked. Now, on another machine but also with XP SP2, it fails and the hook is required.

Jim, earlier in this thread you mentioned you had to override GetAttributesOf() because of SFGAO_CANMOVE and SFGAO_CANCOPY. Have you still implemented it this way or turned it out to be unnecessary meanwhile?
(German translator of xplorer² and editor²)
www.timosoft-software.de - the home of ExplorerTreeView
JimKueneman
Member
Member
Posts: 13
Joined: 2007 Aug 13, 04:40

Post by JimKueneman »

That was a long time ago in "Jim Time"... :lol:

Ok, I looked at my code and yes I am still validating Copy and Cut manually in my proxy IShellFolder.  Not sure if it is still necessary.

Wow, there is a lot of code that I don't remember doing in that file....

Jim
User avatar
TiKu
Member
Member
Posts: 22
Joined: 2005 Mar 18, 17:47
Location: Unterföhring, Germany
Contact:

Post by TiKu »

:lol:

To make the TortoiseSVN context menu extension and SHMultiFileProperties happy, you also must add CFSTR_SHELLIDLIST data to the IDataObject returned in GetUIObjectOf.

Looks like everything is working now. :D Only the Send To sub menu seems to cause my IDataObject implementation run into an infinite loop.
(German translator of xplorer² and editor²)
www.timosoft-software.de - the home of ExplorerTreeView
joshcomley
New Member
Posts: 1
Joined: 2011 Mar 28, 21:50

Post by joshcomley »

Hi there,

I know this is an old thread, but being able to do what you achieve (context menu on files from multiple folders).

Do you guys know of any C# adaptation of your solution?

I'm really struggling with the C++... it's been 10 years since I was there!

Many thanks,
Josh
User avatar
nikos
Site Admin
Site Admin
Posts: 15759
Joined: 2002 Feb 07, 15:57
Location: UK
Contact:

Post by nikos »

sorry, my C# is worse than your C++
DavidXanatos
New Member
Posts: 1
Joined: 2021 Aug 19, 06:45

Re: blog: riddles in programming

Post by DavidXanatos »

nikos wrote: 2007 Jul 08, 08:46 here's the comment area for today's blog entry found at:
http://www.zabkat.com/blog/08Jul07.htm
Could you may be please provide an actually working example code?

as the comments says "... This is easier said than done but if you have an explorer type of application you most probably have such a class already. " and well I don't as I'm using a Qt based file system browser and want only to add the native windows menu, I'm quite far away and unexperienced with all that windows shell stuff.

Cheers
David X.
User avatar
nikos
Site Admin
Site Admin
Posts: 15759
Joined: 2002 Feb 07, 15:57
Location: UK
Contact:

Re: blog: riddles in programming

Post by nikos »

have a look at SHCreateDataObject API. If you search for it in github i'm sure you'll find samples
Post Reply