October, 2007

  • The Old New Thing

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

    • 32 Comments

    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

    Microspeak: Actionable

    • 31 Comments

    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?

  • The Old New Thing

    The three tiers of a mixing room of a movie studio

    • 3 Comments

    Kai Jones describes what you see in the mixing room of a movie studio. It's very simple but very telling. I won't give away the punch line; go read it yourself. (It's the paragraph that begins, "We also went into the sound building.")

    (Via Anita Rowland.)

  • The Old New Thing

    Why does ICE16 complain about product names longer than 63 characters?

    • 19 Comments

    If you merge in the Internal Consistency Evaluators into your MSI package, you may run into error ICE16, complaining that the product name is longer than 63 characters. Why is this so bad?

    Well, it isn't really, at least not any more. The original Windows 95 version of the Add/Remove Programs control panel did limit product names to 63 characters. (If you had a longer name, it didn't show up at all because the call to RegQueryValueEx failed with ERROR_MORE_DATA.) This limit was raised to around 259 characters starting with Windows 2000, the version that introduced the fancy list with icons and sizes. However, ICE rule 16 still checks against the old limitation because it doesn't know whether or not your program was designed to run on versions of Windows prior to Windows 2000.

    If your program doesn't install on those older versions of Windows, then you can disregard the 63-character limit; the new limit is approximately 259 characters.

  • The Old New Thing

    Which windows appear in the Alt+Tab list?

    • 16 Comments

    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

    The dangers of taking a service droid off script

    • 25 Comments

    In the discussion last year regarding retail companies allegedly not collecting personal information as aggressively, a few people mentioned tactics for confusing salesdroids. For a while, I would intentionally confuse salesdroids by using my passport as identification. But far more frustrating is when I manage to confuse salesdroids completely by accident.

  • The Old New Thing

    The early days of the Microsoft cafeterias

    • 4 Comments

    A tour of Redmond campus cafeterias back in the old days took much less time than it would require nowadays. Back then, the cafeterias were tiny affairs, the size of maybe three offices not counting the prep area, with a seating capacity of maybe a dozen tables. Each cafeteria had a theme, so going to lunch back in the day was not "Let's go to the nearby mega-cafeteria and decide what we'll have." It was "Let's decide what we'll have, and then go to the mini-cafeteria that is serving it."

    Here are the cafeterias on campus back in The Before Time, along with their specialties:

    • Building 1: Lite Bite. Low-calorie and vegetarian food.
    • Building 4: Wild Pizza. Pizza, a hot entree, and sandwiches made to order.
    • Building 5: Burger Bar. The grill, and home of the famous Blibbet Burger.
    • Building 8: American Fare. Traditional American food for the meat-and-potatoes kind of guy.
    • Building 9: International Cuisine. A different featured country every week.
    • Building 10: American Fare. Traditional American food for the meat-and-potatoes kind of guy.

    All cafeterias had a salad bar, and the cafeterias in buildings 8 through 10 were extra large: In addition to the featured theme, they also had a grill and made sandwiches to order. (It was like three cafeterias in one!)

    I myself have never even seen a Blibbet Burger, much less eaten one. Larry Osterman has some Blibbet memories, and Adam Barr has more cafeteria memories.

  • The Old New Thing

    The perils of translating words blindly without verifying them in context

    • 51 Comments

    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

    Another celebrity knitter: Tracey Ullman

    • 9 Comments

    Tracey Ullman joins the roster of celebrity knitters with her book Knit 2 Together: Patterns and Stories for Serious Knitting Fun. (She also gets to add to the pile of books whose titles are of the form Catchy title: Long boring subtitle.)

  • The Old New Thing

    The most important choice in writing is not what you say, it's what you don't say

    • 34 Comments

    "The most important choice in writing is not what you say. It's what you don't say." Eric Gunnerson gave me that advice when I was writing my book. It's sort of the writing version of "You don't know what you do until you know what you don't do."

    That's why I'll write

    Of course, you probably wonder this magical pfl comes from. It comes from the Multilanguage Object in mlang.

      IMLangFontLink2 *pfl;
      CoCreateInstance(CLSID_CMultiLanguage, NULL,
                       CLSCTX_ALL, IID_IMLangFontLink2, (void**)&pfl);
      ...
      pfl->Release();
    

    and not

    The pfl variable we've been using is an interface pointer to the IMLangFontLink2 interface. We obtain this pointer by calling the CoCreateInstance function, asking for the object whose class ID is CLSID_CMultiLanguage (defined in the mlang.h header file) and specifying the interface ID (IID) of IID_IMLangFontLink2. The interface ID is a 128-bit value that uniquely identifies an interface; we use it here to specify that we wish to have access to the IMLangFontLink2 interface. Since COM uses explicit reference counting, we must remember to call the IUnknown::Release method when we are finished with the interface pointer. Each call to the IUnknown::Release method decrements the reference count by one, and when the reference count drops to zero, the object is destroyed.

      IMLangFontLink2 *pfl;
      CoCreateInstance(CLSID_CMultiLanguage, NULL,
                       CLSCTX_ALL, IID_IMLangFontLink2, (void**)&pfl);
      ...
      pfl->Release();
    

    This is why I hate reading technical books. People think it's better to write fifty words when ten are enough, that you should explain everything in excruciatingly tedious detail just in case there's a reader out there who sees the word CoCreateInstance and says, "Gosh, I don't know what that is, and I'm going to declare this book useless unless it explains everything from first principles."

    What next? "The left open brace begins a block of statements"?

Page 3 of 4 (33 items) 1234