Date: | August 12, 2015 / year-entry #169 |
Tags: | other |
Orig Link: | https://blogs.msdn.microsoft.com/oldnewthing/20150812-00/?p=91831 |
Comments: | 21 |
Summary: | This question came in from two customers. I'm pretty sure it was two customers rather than one customer going on a fishing expedition because the questions came six months apart, and the scenarios were different. |
This question came in from two customers. I'm pretty sure it was two customers rather than one customer going on a fishing expedition because the questions came six months apart, and the scenarios were different. Suppose you remove all shortcuts to Explorer from the taskbar and the Start menu. Then you create a shortcut to Explorer and put it on the desktop. Wait, you're not done yet. Now view the Properties of that shortcut, use the Change Icon button, and give it some random icon. The uglier the better. Last step: Go to the Taskbar properties and set Taskbar buttons to Always combine, hide labels. All right, now open an Explorer window. Observe that it has the ugly icon in the taskbar rather than an icon that matches the Explorer window that you opened. What's going on here? Last step first: Since you configured the taskbar as Always combine, the icon for the Explorer does not come from the window itself, but is rather the group icon. Okay, so where does the taskbar get the group icon from? The taskbar looks in the following places to get the group icon:
Normally, a shortcut is found on the Start menu,
but in this case,
the user explicitly removed all shortcuts to
In other words, the reason you're getting an ugly icon is that when Windows tries to figure out the icon to show for Explorer groups, you deleted all the good icons and left only the ugly icon. Okay, so why does the taskbar even bother looking at shortcuts on the Start menu and on the desktop? Why doesn't it just show the icon for the executable itself?
A lot of applications don't bother giving their executable a
nice icon.
The theory being,
"Well, we give our Start menu shortcut a nice icon.
And when the program runs, it registers a nice icon
when it calls
So that's where the first rule comes from: See if there is a shortcut to the program on the Start menu. If so, then use that icon, because that's the icon the program wants to show to the user to say "Hey, run my program!" But even with that, there were still some incorrect icons. Those were from programs who installed their shortcut on the desktop rather than the Start menu. That's why there is rule number two. Only if there is no shortcut on the Start menu or the desktop does the taskbar look to the executable itself. It so happens that Explorer already has to keep track of every shortcut on the Start menu and on the desktop, because it needs to keep track of any hotkeys registered by those shortcuts. Having it keep track of yet another piece of information for every shortcut wasn't too much of an extra burden. Bonus chatter: Why not just create a compatibility shim for these ugly applications? In general, when you find these sorts of compatibility issues, you can choose to fix them either by accommodating the issue in the core operating system, or by creating a compatibility shim that applies only to the applications affected by the issue. If the problem is widespread, then you just have to suck it up and put the compatibility behavior in the core operating system. Otherwise, the compatibility database would be bloated with thousands of entries. What's more, it's clear that there will be a very long tail of affected applications, seeing as the default icon for MFC applications is the generic MFC icon, and there are probably a whole lot of vertical-market and line-of-business applications that are just using the default icon without realizing it. These applications are not big-market mainstream applications, so they will likely never come to the attention of the application compatibility team. |
Comments (21)
Comments are closed. |
Also, compatibility shims work as replacements for functions at runtime. They can't affect other processes. Explorer happens to be a different process than the offending program.
This icon lookup also seems to apply to the applications icon in the "new" taskbar button context menu…
Obviously I'm missing something, because to me it seems like the right thing to do is use the icon specified in the RegisterClass call. Is the issue just that if you need to combine multiple windows then you don't know which class to pull the icon from?
Gabe: Which RegisterClass call? You may have multiple classes of windows grouped together, each with their own icon.
> The executable itself is buried off in the Program Files directory, which nobody should be messing with anyway, so who cares if it has an ugly icon there?
It might even not be the same executable. The executable in the Start Menu, with the nice icon, might be a windowless "launcher" which loads the correct executable from the Program Files directory (and which actually shows the windows).
I would have thought that in the case of multiple classes of windows grouped together, a heuristic like "pick the one of the window class that was registered first" or the like would work better than "find a icon of a shortcut in the Start Menu". Though I'm sure it must have been considered, and the Windows compatibility team finds programs much stranger than those I deal with regularly.
> It might even not be the same executable. The executable in the Start Menu, with the nice icon, might be a windowless "launcher" which loads the correct executable from the Program Files directory (and which actually shows the windows).
My mental model of the taskbar says that it doesn't have access to the shortcut that launched the applications, it only stores a list of executable paths (of the current top level unowned windows). So the way it gets icons is that it searches for shortcuts by executable path in the order described in the post. By the time an application gets to the taskbar, a reference to the shortcut that launched it is no longer available, so you'll get weird icons in the scenario you described if the window-showing .exe has the wrong icon.
> "pick the one of the window class that was registered first"
Which would be the splash screen on a lot of applications. And I don't think I have ever given my splash screens an icon. So we would be back to the start of the problem.
Anyone who uses the MFC icon *demonstrably* doesn't care what their application looks like, so why bother to prettify them? With hindsight, it would have been better if the App Wizard had not included a default icon. This would have meant that all the people who don't care would have a null icon, which is both efficient and easily detected by external processes (like Explorer).
So, um, back to work on the time machine I guess.
By "pick the one of the window class that was registered first", I meant of the windows currently in the group. Presumably the splash screen wouldn't be in the group very long, and even if it were, it presumably had an icon in the taskbar in the pre-combined-windows days?
GetWindowClassRegsitrationTime
function. Also, most apps don't may close attention to the order in which they register their classes. It is common to register a helper class before the main window class. -Raymond]I have a hard time imaging why someone would put something other than the icon for the main window first in the EXE's icon list; except for some old 3.1 era programs where the first icon of an exe was not obvious. (I've got exactly 1 example of getting a bad icon that way, and that was in fact the reason. Confused the heck out of me until I happened to notice it was a 16 bit exe.)
I wonder if this is why the icon for Command Prompt windows sometimes changes to an icon from some other random application. Random Application must add a Start Menu shortcut that runs cmd.exe (with some parameters, to run its batch file or whatever) and with its icon. And the taskbar must just pick the first shortcut it sees that runs cmd.exe. I would've thought it would prefer the one with no command-line parameters.
"It so happens that Explorer already has to keep track of every shortcut on the Start menu and on the desktop, because it needs to keep track of any hotkeys registered by those shortcuts"
Does Microsoft know how many people use this functionality?
@boogaloo, Raymond: I use it. Not much anymore, but it has its uses.
I would have said "at the time you're combining the taskbar items, look at the icons that would be displayed if they weren't combined. If they're all the same (which seems like the 99% case), then just display that icon. If they're different, have some heuristic for choosing one: most common, or leftmost, or rightmost, or whatever." Surely that would be easier than scanning all over creation for an icon.
Or maybe just don't combine the items on the taskbar if the buttons are different. I doubt users mental model includes the concept of which EXE each window is tied to, so if two windows of the same process have different icons, most users probably don't expect them to be combined anyway.
I must agree with MV. Pick one from the uncombined.
Getting it from the start menu or desktop sounds fine to me. After all, that's going to be the most recognizable icon for your program – it's the thing people click on to run it!
[Actually, comparing icons is hard.]
Why the heck are you comparing images? Compare filename.exe and resource number.
I think you accidentally answered a question I've had for years. I've long known about the hotkey feature, but never used it. I always wondered though how it could possibly work. After all, how is the poor computer to know if in some dusty corner of the hard disk is a shortcut with a hotkey? It never occurred to me that it only works if the shortcut file is on the desktop or start menu. In retrospect, it seems like a rather good idea: it works with all the shortcuts the user is likely to care about, and you don't have to pay for a full disk scan. Thanks for the accidental enlightenment!
Using a non-runtime icon resolution also has the consistency advantage:
The icon used for pinned applications will be the same as the icon used in grouping.
I too think the current implementation was the best way to go.
Always add an icon for an application.