October, 2007

  • The Old New Thing

    Which windows appear in the Alt+Tab list?


    Commenter Phil Quirk wants to know what the rules are for determining which windows appear in the Alt+Tab list. It's actually pretty simple although hardly anything you'd be able to guess on your own. Note: The details of this algorithm are an implementation detail. It can change at any time, so don't rely on it. In fact, it already changed with Flip and Flip3D; I'm just talking about the Classic Alt+Tab window here.

    For each visible window, walk up its owner chain until you find the root owner. Then walk back down the visible last active popup chain until you find a visible window. If you're back to where you're started, then put the window in the Alt+Tab list. In pseudo-code:

    BOOL IsAltTabWindow(HWND hwnd)
     // Start at the root owner
     HWND hwndWalk = GetAncestor(hwnd, GA_ROOTOWNER);
     // See if we are the last active visible popup
     HWND hwndTry;
     while ((hwndTry = GetLastActivePopup(hwndWalk)) != hwndTry) {
      if (IsWindowVisible(hwndTry)) break;
      hwndWalk = hwndTry;
     return hwndWalk == hwnd;

    The purpose of this algorithm is to assign the most meaningful representative winow from each cluster of windows related by ownership. (Notice that the algorithm doesn't care whether the owned window is modal or non-modal.)

    At least that's the simple rule if you're not playing crazy window style games. The WS_EX_TOOLWINDOW and WS_EX_APPWINDOW extended styles were created so people can play games and put their window in the Alt+Tab list or take it out even if the simple rule would normally have decided otherwise. This is one of those "Okay, if you think you're smarter than Windows, here's your chance to prove it" options. Personally, I would avoid them since it makes your window behave differently from the rest of the windows in the system.

    A window with the WS_EX_TOOLWINDOW extended style is treated as if it weren't visible, even if it is. A window with the WS_EX_APPWINDOW extended style is treated as if it has no owner, even if it does.

    Once you start adding these extended styles, you enter the world of "I'm trying to work around the rules" and the result is typically even worse confusion than what you had without them.

    I'm not sure what the original commenter is getting at. The window hierarchy described in the suggestion (which doesn't make it so much a suggestion as it is a request for me to debug their problem) says that window C is modal on both windows A and B, which doesn't make sense to me, since a window has only one owner.

    The algorithm for choosing the Alt+Tab representative from each cluster of windows may not be the best, but it's what we have. I wouldn't be surprised if the details are tweaked from time to time. No, wait, let me rephrase that. I know that the details are tweaked from time to time. The spirit of the operation is preserved (to show the windows the user can switch to, using the most "natural" candidate for each cluster of windows), but the specific details may be fined-tuned as the concept of "naturalness" is refined.

  • The Old New Thing

    Why doesn't Explorer show recursive directory size as an optional column?


    "Why start up another program to see folder sizes, when they should just be right there, in Explorer, all the time?"

    The same reason \\ does not autocomplete to all the computers on the network: Because it would destroy corporate networks.

    Showing folder sizes "all the time" means that when you open, say, the root of a large server, Explorer would start running around recursively enumerating every single directory on the server in order to compute the folder sizes. One person doing this to a server is bad enough. Imagine if hundreds of people did it simultaneously: The server would be hammered continously.

    Even worse: imagine doing this across a limited-bandwidth link like a VPN or an overseas link. The link would be saturated with file enumerations and wouldn't have any bandwidth remaining for "real work". Even the change-notifications that Explorer registers are cause for much hair-pulling on corporate networks. (And these are change-notifications, which are passive.)

    Even on a home computer, computing folder sizes automatically is is still not a good idea. How would you like it if opening a folder caused Explorer to start churning your disk computing all the folder sizes recursively? (Then again, maybe you don't mind, in which case, go nuts.)

    (Of course, the question sidesteps the question the linked article tries to address, namely, "What do you mean by the size of a directory anyway?")

  • The Old New Thing

    Whose idea was it to make Ctrl+Backspace delete the previous word?


    James Manning mentioned in a footnote to a blog entry on PowerShell and WMI that he considers the Ctrl+Backspace shortcut key a Windows-ism. Where did this shortcut key come from?

    From a fan of the Brief editor.

    A few people in the early days of the Internet Explorer group used the Brief editor, which uses Ctrl+Backspace as the shortcut key to delete the previous word, and they liked it so much that one of them added it to the autocomplete handler. Therefore, any edit control that uses SHAutoComplete will gain this secret Ctrl+Backspace hotkey.

    This is one of those scary "rogue features". There's no spec, there's no testing, it's just a developer who spent some time whacking a feature into the product because he liked it. Sure, rogue features can often become useful, but they also create a lot of liability. Imagine if a rogue feature was the cause of a program crash, an application compatibility problem, or worse, a security vulnerability.

  • The Old New Thing

    The perils of translating words blindly without verifying them in context


    My fancy new office phone has an option to change the language of its user interface, so naturally I chose Swedish. Once I did that, I saw some obvious translation errors.

    • The Edit command was called Bearb... instead of Redig.... Apparently, the Swedish translation was created by starting with the German version, and they missed a spot and left a word in German (Bearbeiten). This also illustrates the perils of not leaving enough room for expansion. The English word Edit is just four letters long, but the German word is ten letters long (and the Swedish one eight letters), and the longer German and Swedish words get truncated.
    • The label First name was translated as Första namn. Första namn does mean first name, but in a literal sense, as in the sentence "There are ten names. The first name is Wilson." The correct translation is förnamn, which means given name (in contrast to efternamn, or family name). Similarly, the button Forward was translated as Vidare (opposite of backward) instead of Vidarekoppla (to forward a phone call).

    The first example above is just sloppiness, but the second one illustrates how a simple LocalizeString("some text") algorithm doesn't work. As Lance Fisher's teacher put it, "Russian is not a translation of English." You can't just take words and phrases in one language and put them through a simple mapping table and expect the result to be accurate.

    Back in the Windows 95 days, the German translation team needed some beta testers, and I volunteered. The most interesting translation bug I reported was one in which an English menu item Sort was translated as Art (which means class, kind) instead of Anordnen (which means to arrange). The one English word has two different meanings, and a blind dictionary translation won't know which one is intended.

  • The Old New Thing

    Superstition: Why is GetFileAttributes the way old-timers test file existence?


    If you ask an old-timer how to test for file existence, they'll say, "Use GetFileAttributes." This is still probably the quickest way to test for file existence, since it requires only a single call. Other methods such as FindFirstFile or CreateFile require a separate FindClose or CloseHandle call, which triggers another network round-trip, which adds to the cost.

    But back in the old days, the preference for GetFileAttributes wasn't just a performance tweak. If you tried to open the file to see if it existed, you could get the wrong answer!

    Some network providers had a feature called a "data path". You can add directories to the data path, and if any attempt to open a file failed, the network provider would try again in all the directories in the data path. For example, suppose your data path was \\server1\backups\dir1;\\server1\backups\dir2 and you tried to open the file File.txt. If the file File.txt could not be found in the current directory, the network provider would try again, looking for \\server1\backups\dir1\File.txt, and if it couldn't find that file, it would try again with \\server1\backups\dir2\File.txt.

    All this extra path searching happened behind Windows's back. Windows had no idea it was happening. All it knew is that it issued an open call, and the open succeeded.

    As a result, if you used the "open a file to see if it exists" algorithm, you would get the wrong result for any file that existed on the data path but not in the current directory. These network providers didn't search the data path in response to GetFileAttributes, however, so a call to GetFileAttributes would fail if the file didn't exist in the current directory, regardless of whether it existed on the data path.

    I don't know if any network providers still implement this data path feature, but Windows code in general sticks to GetFileAttributes, because it's better to be safe than sorry.

  • The Old New Thing

    You can't change it, but you can hide it and add something that looks like it


    Today we have another case of "Now you have two problems." The corporate customer already solved their problem halfway and needed help on the other half. The impossible half.

    We want to change the Add or Remove Programs icon in the Windows XP control panel so it runs our custom install management program instead of running the one built into Windows. In other words, we want to change what happens when the user clicks the Add or Remove Programs icon. Is this possible?

    What they specifically request isn't possible because the icon is provided by Add or Remove Programs itself, but you can easily get the same effect. This is why it's important to understand why somebody wants to do something even though they are asking how to do it. Once you understand why they're doing something, you can unwind the steps they've taken and come up with something that doesn't answer the specific question but still solves the bigger problem.

    You can't redirect an icon but you can remove the existing icon and replace it with something else. Set a policy to remove the existing Add or Remove Programs icon from the control panel and then write your own control panel called Add or Remove Programs.

    I'm not sure what happened next, but they acted as if I wrote, "Could you please repeat the question?"

    Raymond, we need to replace the link in the Control Panel with a custom program that elevates the user's privileges so that they can manage the programs on the computer. Is there any registry key or setting that specifies how the control panel applet is launched that we could inject an EXE into? This EXE would just be a wrapper for launching the original CPL.

    I'm assuming that the extra wrinkle of "And then we want to re-launch the original CPL" made them think their situation was somehow special, so that regular-grade advice wasn't good advice. They needed premium.

    You can still follow the original suggestion. Remove the original CPL via policy and add your custom EXE (which then launches the original CPL after doing whatever it wants).

    But no, that wasn't the problem. They simply missed the point entirely. They were so focused on looking for the sentence "Here is how you change what the icon launches" that they completely missed the point of the suggestion. They're looking for a solution to the specific problem instead of the bigger problem.

    How do you configure the policy to launch our EXE instead of the CPL?

    At this point I pulled out my bad analogy gun.

    In your car there is an ignition switch. It is wired to the starter. You want to make the driver take a breathalyzer test before they can start the car.

    Plan A (what you are proposing): Patch into the wire connecting the ignition switch to the starter so it goes through a breathalyzer. Unfortunately the wire is sheathed in kevlar and cannot be cut open. The designers of the wire did not include any hooks for breathalyzers.

    Plan B (my suggestion): Remove the old ignition switch and install a new ignition switch that is connected to a breathalyzer. If the driver passes the breathalyzer test, then your ignition switch turns the original ignition switch. Notice that this method doesn't require you to bust open the kevlar sheathing that protects the wire between the old ignition switch and the starter.

    All the driver sees is a keyhole. They stick the key in and turn the key. If you're really clever you make your new ignition switch's faceplate look just like the original so the driver can't tell the difference between the two methods (all they see is a keyhole, a breathalyzer, and if they pass, the car starts).

    • The existing CPL is the old ignition switch.
    • Your replacement program is the new ignition switch.
    • Deploying the Hide the Add or Remove Programs control panel policy is removing the old ignition switch.
    • The Add or Remove Programs icon is the keyhole.
    • The way Windows XP works, the keyhole leads to the old ignition switch.
    • Plan B: Use policy to remove the old ignition switch, and install new ignition switch (your replacement program). Use some paint to make the new keyhole look just like old keyhole. The person in driver's seat is none the wiser.

    You know you're in trouble when I have to pull out my bad analogy gun.

    Note: I don't know whether this trick will actually work, but it seemed a useful example of the principle of "Just because it has to look like something doesn't mean it has to be that something."

  • The Old New Thing

    Suggestion Box 3, short answers (part 1 of who knows how many)


    Some suggestion box topics turn into daily entries. Others deserve just a sentence or two. Here are the short answers.

    Can you shed some light on RPC_E_CANTCALLOUT_ININPUTSYNCCALL?
    This one is kind of bizarre, because the person who asked the question linked to the answer!
    What form do application hacks usually take in Windows?

    They take many forms, depending on the situation, but checking a window caption is definitely ill-advised, since that creates the opportunity both for false positives (what if an unrelated program happens to have the same caption?) and false negatives (will the German version of the program have the same caption?). On a related note, Chris Jackson writes about the shim proces itself, which you might find interesting.

    Why doesn't PathFileExists support UNCs?

    Actually, it does. What the documentation is trying to say is that it doesn't work is for things like \\server. That will return FALSE even if the server exists. (I've sent a clarification to the documentation team. Who knows whether they'll accept it.)

    A series of remarks (but no question) about Kennedy-Western University

    This wasn't a topic suggestion, just somebody who wanted to take what I said and argue against it with made-up facts. "I to enjoy people that display their ignorance in frount of all of us." You can get a mirror at Ikea for just a few dollars.

    How do I put focus on a window without raising it?

    One of the window manager's design principles is that the active window comes to the top.

    Some really long list of complaints

    Um, I didn't see a topic suggestion in there. (Not that I really had much incentive to look hard for one.) It looks like just a bunch of ranting.

    On tooltips that get stuck behind other windows (Question was duplicated. How hard is it to search the Suggestion Box page to see if somebody already asked your question?)

    If you set your owner correctly and don't play weird games, everything will be just fine. The problem is that the taskbar has to play weird games because of all the other applications that play even weirder games. When you play weird games, things get weird.

    Is there a way to send input other than SendInput?

    No. You can try to fake it but you're going to run into problems.

    Why doesn't AltGr+Del act like Ctrl+Alt+Del?

    I don't know but I can guess, and so can you. Hint: Component layering. Low-level components vs. higher-level components.

    Why do some MSDN samples use the goto statement?

    That's a coding style issue. Believe it or not, different people have different styles, and there is no mandated "MSDN coding style". Some people are more averse to the goto statement than others.

    A question putatively about WS_TABSTOP

    Somthing is horribly wrong with your program design if each edit control in your dialog has its own message pump! Fix that first, then the tab stop issue should fix itself.

    Why can't you call SetFocus() on a window in another thread?

    I covered this in my PDC 2005 talk.

    Another category is people who ask a question I've already answered or ask a question that has already been asked.

    Why doesn't the taskbar have my pet feature? Again. And again. And again. Is it so hard to search on the very page you're posting your suggestion to?

    I already discussed the feature process. I happen to know the person responsible for Start menu and taskbar features in Windows Vista. The list of design changes and feature requests was over 200 items long and obviously not all of them could be addressed. (And that list was just of the design changes and feature requests that overcame the starting point of minus 100 points.)

    What are these mystery folders in my Program Files directory?


    What is the deal with the time zone map?

    This question was asked over two years after I answered it. What's particularly baffling about this one is that the time zone article is one of the most frequently-linked entries I've written! How could the person not have found it?

    Is there way to get the current full path from an Explorer window?

    I answered this over a year previously and then again three months before the suggestion was posted.

    Why do some files come up strange in Notepad?

    I answered this over two years previously.

    Why does the resource compiler complain about strings longer than 255 characters?

    I answered this over two years previously.

    And then there are the people who ask questions on things that I explicitly listed as topics I am not inclined to cover.

    And then there are the suggestions that are so wildly off topic I don't even know why they bothered to ask me, such as this person who wants me to discuss a VB6 language feature and another who wants me to discuss non-short-circuit evaluation in Visual Basic. I have no idea why they chose me to ask these questions. In my experience, VB doesn't even stand for Visual Basic! Another person asked a long, rambling question about Unicode IME that I got tired of reading.

    I'm kind of baffled by this comment asking how to post a comment.

    Other topics I am unlikely to cover are personal biography since that just leads to WikiStalking.

    Don't ask the same question to multiple people. It duplicates effort. (Another example.)

    And then there are people who just like to natter on about their uneventful lives, yammering repetitively about how nothing is going on and that they are bored. Hey, don't take your boredom out on me. I'm trying to get some work done here. If you want to chatter, go start your own blog.

    Generic viagra credit cards ringtones.

    The ideal length for a topic suggestion is a single paragraph between two to four sentences. If it's too short, there isn't enough context. If it's too long, I will lose interest and not bother reading the suggestion.

    That's all the short answers for this year. (You may have noticed that I've generally been using Mondays to following up on topics posted to the suggestion box or in blog comments.)

  • The Old New Thing

    How do I delay the automatic logon process?


    To solve some problems you need to place one foot outside the box.

    We have a number of kiosk machines that are networked wirelessly. Each machine is configured with automatic logon so that things return to normal after power is restored after an outage. The problem is that the wireless switch takes a long time to recover from a power failure, so when the kiosk machines try to log on, they can't. We have to go around to all the machines and manually log them on after waiting a few minutes for the switch to get itself back up. Is there a way we can delay the automatic logon or convince automatic logon to pause and retry?

    Your first reaction may be to write a custom logon provider or otherwise control the GINA. But there's a much lower-tech solution.

    Go to your boot.ini file (or if you're using Windows Vista, use bcdedit) to increase the boot menu timeout. The timeout value in boot.ini can go as high as 11 million seconds (about four months). If your wireless switch takes more than four months to get itself into a ready state, then you've got worse problems.

  • The Old New Thing

    What's the deal with the EM_SETHILITE message?


    If you look up the documentation on the EM_SETHILITE and EM_GETHILITE messages, they just say "not implemented". What's going on here?

    The EM_SETHILITE and EM_GETHILITE messages were added back in 2002 for the breadcrumb bar to use. Back in those days, the breadcrumb bar wasn't what you see in Windows Vista today, a series of buttons with drop-down arrows, each representing a level in the hierarchy. The breadcrumb bar back in those days was just a fancy-looking address bar (i.e., an edit control). Instead of having a button for each level in the hierarchy, the breadcrumb bar would highlight a path component if you moved the mouse over it (or used the keyboard to select it). Instead of having drop-down arrows, the breadcrumb bar would wait for you to hover your mouse and the highlighted path would auto-open to show the menu of sibling items.

    The design of the breadcrumb bar changed and the "fancy-looking address bar" design was abandoned. The functionality of the EM_SETHILITE and EM_GETHILITE messages was ripped out, but the message numbers were left behind to avoid build breaks in case anybody was using those messages. Of course the messages have no effect any more, but at least the product still builds. The people who were using the message can then wean themselves from it on their own schedule.

    This is one of the realities of developing both a library and the library's clients simultaneously. If you are the person who is responsible for the library and you intend to make a breaking change, you have to do it in stages so that all the clients can make the transition smoothly. It's not like you can go in and change all the clients yourself since they aren't yours to change, and you might not have access to the source code anyway. The clients belong to other teams, or even other companies. You have to coordinate with those other teams and let them know what your transition plan is so they can work it into their schedule.

    The fact that the EM_GETHILITE and EM_SETHILITE messages still linger is just leftover dirt that never got cleaned up. What's in the header files now is the penultimate stage of the transition plan. The final stage would have been to remove the messages from the header file entirely, but the "no changes to public header files allowed" deadline came before the final stage could be executed, and now that the messages are in a public header file, they have to stay in there forever. Even though they don't do anything.

  • The Old New Thing

    Microspeak: Actionable


    The word actionable has as its primary meaning "providing grounds for legal action", but in the world of management, it is the secondary meaning "capable of being acted upon" that is more common. Something that is actionable provides a specific demand for action. Although I'm not necessarily a big fan of the word itself, I definitely appreciate the value of the concept it is trying to capture.

    Not Actionable Actionable
    I'm thirsty. Can I get a glass of water?
    This checkbox moved. Move it back.
    Explain why you moved it.
    Create a duplicate checkbox at the old location.
    I'm seeing behavior X. Help me get behavior Y.
    Explain why I'm getting X.

    The concept is valuable because it emphasizes the importance of clear communication, and making sure people understand what you want. Without it, meetings turn into a passive-aggressive-athon, with people saying, "Oh, sorry, I didn't realize you wanted me to do anything about that. I thought you were just venting."

    That's also why I'm not happy with the nounification of the word ask. It's not a requirement; it's not a demand. It's this vague ask thing. How do you prioritize an ask?

Page 1 of 4 (33 items) 1234