Append to the default tooltip in a shell extension
Asked Answered
A

1

7

I have a shell extension built using SharpShell. I am wondering if it is possible to append to the tooltip you see when you mouse over a file:

enter image description here

I have read and tried to use a Shell Info Tip Handler, but the problem with this is that it overrides the entire tooltip with what you set it to, instead of giving you the ability to append a line of text to the default tooltip you normally would see, which is my desired outcome.

I have a feeling this may not be supported in SharpShell, as a result, it would help for me to get insights from people as to how I could additionally approach this problem within MSVC++ shell extensions as well.

Abstergent answered 8/9, 2016 at 18:41 Comment(12)
Did you try calling the base class from your override?Meditate
@BenVoigt I wish, it is an abstract base method unfortunately.Abstergent
Here's someone else who had the same question -- they asked in the wrong place and got no answer. social.microsoft.com/Forums/en-US/…Meditate
@BenVoigt We need Raymond Chen up in here, but the first thing he's going to say before providing a suitable answer is don't write your shell extensions in C# :)Abstergent
One, .NET 4 introducing the ability to load multiple CLR versions into a single process got rid of the worst of the complications of using C# (it might still not be the best idea). Two, even for a native shell extension, the question "How does my Info Tip Handler get the text that would have been displayed had my handler never been registered?" is still interesting. Since the registry registration doesn't maintain a stack of handlers, just one, this probably never can be answered... but perhaps one can still get the default text as if no handlers were registered at all.Meditate
Really it's the whole subclassing debacle all over again -- To undo subclassing, you put back the former window procedure. And instead of calling the default handler, you call the procedure you supplanted. But what if a middle subclass wants to remove itself? It doesn't know where the pointer to it is stored, and so cannot remove itself. Same issue here, if you remember what handler was installed before you replaced it, you can't assume the software providing that hasn't been uninstalled in the meantime, so you can neither usefully chain to it nor put it back in the registry.Meditate
Win32 eventually added SetWindowSubclass and RemoveWindowSubclass functions to make operations on the linked list available to all comers. But no such infrastructure exists for Shell Info Tip Handlers.Meditate
@BenVoigt I get what you're saying, but in this case its not that complicated, because I want to get the resulting tooltip for the file or folder as if no shell extensions or their corresponding handlers were to exist on the system. So like, a simple library which pre-computes this from the HKCR registry would suffice for my needs, anyways.Abstergent
The point of a custom handler is to do custom stuff, why not print the default text with the extra info? Appending you run the risk of appending to an appended other custom handler.Edentate
@Plutonix Because I am not certain of a suitable mechanism to obtain the default tool tip text of any given file shown in Explorer. It seems to be highly configurable via the HKCR registry, where some InfoTip strings can even reference assembly resources, and other things. I am not looking for a simple answer on parsing the HKCR registry though, as there's no way anyone's answer would get it right, right off the bat. I am trying to get a concrete answer on whether or not there is a standard way of doing this (Windows APIs or some undocumented Windows APIs, etc.)Abstergent
I have a solution but with using of Delphi (a lot of Delphi code). Do you need it?Starwort
@DenisAnisimov Possibly, but can you describe how it works in a comment first?Abstergent
A
1

This is possible, but not through a shell tooltip extension. Instead, through a shell property handler. The Recipe Property Handler is documented here and can be downloaded in full from this repository. Here's a picture of it in action in Windows 10:

enter image description here

It essentially adds extra file properties to the PerfectSteaks.recipe file by registering itself as a property handler, such as the property for Recipe difficulty who's key is Microsoft.SampleRecipe.Difficulty and can easily be set to show in Explorer by modifying the HKCR key HKEY_CLASSES_ROOT\SystemFileAssociations\.recipe to have InfoTip (of type REG_SZ) set as prop:System.ItemType;System.Author;System.Rating;Microsoft.SampleRecipe.Difficulty which causes it to display.

The properties are stored within the file itself. The .recipe file is an XML file which contains, among other things, the actual difficulty which the handler retrieves:

<RecipeInfo>
    <Difficulty>Hard</Difficulty>
    <PreparationTime>5</PreparationTime>
    <CookTime>20</CookTime>
    <Yield>2 servings</Yield>
</RecipeInfo>

This is not something unique these days because a lot of file formats do provide some form of extra internal API for storage. If you are working with Office files (which I am), you may notice they expose properties for storage within them for persistence using OLE. The DSOFile.dll (click here to download the source) is of utmost interest for Office files, and generally other files too. You will see it tries OLE storage within the Office file format itself, barring that it tries the Microsoft Office Metadata Handler for storage. If that fails, it finally tries using alternate streams (not a fan of alternate streams myself because they won't persist).

So that being said, with a combination of a shell property handler and similar tactics to DSOFile.dll, you can merge a solution for getting this job done in a proper way.

Abstergent answered 15/9, 2016 at 20:26 Comment(6)
I see the big problem if you use this method for files like .doc. Such file extensions already have installed Property handlers and your handler will override the existing. And as result shell will not be able to show properties processed by initial Property handler. In case of .doc format it will be Author, Comments and so on.Starwort
And minor note. This method is not universal. Default tooltip can be generated with another combination of PropertyKeys or can be generated with another InfoTip handler or can be generated with string from resources. So this method don`t append to the default tooltip, it creates the new one.Starwort
@DenisAnisimov I'll admit I was quick to jump the gun here, as that's exactly something I wanted to test today, if you can have multiple shell property handlers live side by side.Abstergent
@DenisAnisimov Why don't you post your Delphi-based solution in the meantime?Abstergent
I will but some later. The code is a part my big shell lib and I must to extract and create independent version that can be understood by you.Starwort
@DenisAnisimov Are you hosting it somewhere so I can check the source?Abstergent

© 2022 - 2024 — McMap. All rights reserved.