• The Old New Thing

    Being in upper management must damage certain portions of your brain


    The air must be thinner the higher up the management chain you go, or maybe it just gives you more opportunities to look stupid. Like this message:

    From: <some upper manager>
    Subject: <some subject>

    I will try to keep this relatively brief as I know how busy everyone is.

    <... 4-page message follows...>

    If this is brief, I'd hate to see a "somewhat lengthy" message.

  • The Old New Thing

    Why can't I use the same tree item multiple times?


    It's the continuing balance between ease-of-use and generality.

    At a literal level, you can't use the same tree items in multiple places in the tree, because then various properties would become ambiguous, properties like TVGN_PARENT or TVIS_EXPANDED. (If a tree could be in two places, then it would have two parents, for example.)

    Of course, this problem could have been solved by separating the item content from the item presence. So instead of just having an HTREEITEM, there would be, say, HTREENODE and HTREENODECONTENTS. The node would represent a physical location in the tree, and the item contents would represent the contents of that node: its name, icon, etc.

    Sure, that could have been done, but remember the balance. You're making the common case hard in order to benefit the rare case. Now everybody who is manipulating treeviews has to worry about twice as many objects (what used to be one item is now a node plus contents). This is generally not the balance you want to strike when designing an interface.

    When you design an interface, you want to make the common case easier than the rare case.

    A program that wants this separation can, of course, do the separation manually. Put all the contents in a separate shareable structure and have your HTREEITEMs refer to that shared structure in their lParams. This is more work for the program, but now the cost is being shouldered by the one who wants the extra functionality.

  • The Old New Thing

    What's this fascination with Germanic languages?


    Some people wondered about my fascination with Germanic languages and asked why I didn't branch out to other language families.

    It's basically laziness.

    I grew up speaking English (and a little of the Holo dialect, most of which has by now vanished from disuse), then studied German in high school and college, and most recently added Swedish in preparation for a trip there.

    Swedish was easy to pick up because it nestles nicely between German and English. And that's when I realized that laziness was the key: If you always pick a language close to the ones you already know, it will not be so hard to learn.

    So my list of languages follows a chain of closely-related languages, so each one can be used as leverage for the next. Except for Icelandic, which strikes me as "like German, before the Germans decided to simplify their grammar" - that has its own appeal. I saved it for last.

    I have colleagues who speak Dutch and Afrikaans, so learning those languages would allow me to confuse and annoy them. Because that's the main reason for learning a language: To confuse and annoy.

    (One of my South African colleagues describes Afrikaans as "the language you get when you throw a bunch of Dutchmen into the bush and have them chased by lions for a few hundred years.")

    I have a former colleague who has since returned to Denmark. We always teased him about his native country and language when he was around, and he was a good sport about it. He's the one who taught me the phrase "En gang til for prins Knud". I removed Danish from the list of Germanic languages partly to tease him from afar and partly because the strange Danish pronunciation scares me.

    But for now, my pan-Germanic ambitions are on hold. As the Swedes out there already know, I've started studying Mandarin Chinese Even though I grew up with a tonal language (Holo has seven tones, as opposed to just the four of Mandarin), I never got very good at pronouncing the tones, even though I can hear the difference easily in most cases. So I'm in the embarrassing position of speaking badly and recognizing it immediately.

    Update: With some help from my father, I think I figured out the Mandarin third tone, which was the only one I had been having trouble with. The trick: The way the books explain how the third tone works does not match the way people pronounce it in real life. But the way the books explain it is so deeply ingrained in the way people think about the pronunciation of the tone that they continue to insist that's how it's done even though it isn't.

  • The Old New Thing

    Why does the Links folder keep re-creating itself?


    Those of you who dislike the Links folder have probably tried to delete it, only to discover that it keeps coming back. Why is that?

    This is Internet Explorer trying to do some auto-repair. It noticed that the Links folder is missing, so it figures, "Gosh, it must be corrupted! I'd better fix the problem by creating a replacement."

    People complain that computers can't perform self-repair, and then when the software tries to perform self-repair, they get mad. "But I wanted it to stay broken." You can't win.

    The way to indicate, "Yes, I know about the Links folder, but I don't want to use it" is to hide it.

    This is extraordinarily similar to a problem some people have with Device Manager. They don't want Windows to use a particular device, so they delete it. And then it gets re-detected and added back.

    Because when you delete the device, you're saying, "Forget everything you know about this device." Then when it gets re-detected, Windows says, "Gosh, here's a device I've never seen before! The user must have bought it recently. Let me add it to the device tree so the user can use it."

    In other words, Windows behaves the way it does because the alternative is even worse: You buy a device, plug it in, and nothing happens.

    If you have a device that you don't want Windows to use, go into the Device Manager and Disable it rather than deleting it. This means, "Yes, I know about this device, but I don't want to use it."

  • The Old New Thing

    Fees disguised as taxes


    It has become customary in the telecommunications industry to quote a low price and then add half as much to it in "fees".

    Regulatory Programs Fee. It sure sounds like a government tax.

    It isn't.

    There's been a new round of official-sounding line items on telephone bills, which are really just ways for telephone companies to raise rates while still being able to quote a low price.

    The issue was raised as a shareholder proposal in Verizon's 2004 proxy statement. The proposal starts out sounding very much like a crackpot (perhaps because the proposer is a crackpot), and the logic is rather twisted, but the underlying theme is still there: Price hikes disguised as official-sounding fees.

    How I long for the European rule that the quoted price must accurately represent the actual amount of money you will pay, including taxes and fees. None of this "quote a low price and then add a ton of mandatory surcharges" nonsense.

  • The Old New Thing

    The difference between thread-safety and re-entrancy


    An operation is "thread-safe" if it can be performed from multiple threads safely, even if the calls happen simultaneously on multiple threads.

    An operation is re-entrant if it can be performed while the operation is already in progress (perhaps in another context). This is a stronger concept than thread-safety, because the second attempt to perform the operation can even come from within the same thread.

    Consider the following function:

    int length = 0;
    char *s = NULL;
    // Note: Since strings end with a 0, if we want to
    // add a 0, we encode it as "\0", and encode a
    // backslash as "\\".
    // WARNING! This code is buggy - do not use!
    void AddToString(int ch)
      // +1 for the character we're about to add
      // +1 for the null terminator
      char *newString = realloc(s, (length+1) * sizeof(char));
      if (newString) {
        if (ch == '\0' || ch == '\\') {
          AddToString('\\'); // escape prefix
        newString[length++] = ch;
        newString[length] = '\0';
        s = newString;

    This function is thread-safe because the critical section prevents two threads from attempting to add to the string simultaneously. However, it is not re-entrant.

    The internal call to AddToString occurs while the data structures are unstable. At the point of the call, execution re-enters the start of the function AddToString, but this time the attempt to realloc the memory will use a pointer (s) that is no longer valid. (It was invalidated by the call to realloc performed by the caller.)

  • The Old New Thing

    You can already see the bug report that led to this dialog box


    It's like stupid warning labels on consumer products: Once you read the warning label, you can already imagine the lawsuit that required the warning label to be written in the first place.

    Use that same imagination to interpret this Windows XP SP2 setup error message.

    [Dumb typo in title fixed 7:43am.]

  • The Old New Thing

    When does SHLoadInProc unload a DLL?


    The SHLoadInProc function instructs Explorer to create an instance of a particular CLSID. This causes the DLL responsible for that CLSID to be loaded.

    But when is it unloaded?

    This is one of those puzzles you should be able to figure out by thinking about it.

    Consider: The object is created by calling CoCreateInstance and then immediately releasing the returned object. That's all. Explorer pays no attention to your DLL from then on.

    With this hint, maybe now you can answer the question: When is it unloaded?

    Still don't know? Here's another hint: The issue is no longer a shell issue. Now it's a COM issue.

    When is any DLL loaded via CoCreateInstance unloaded?

    Answer: The DLL is periodically asked whether it is safe to unload. Once the DLL response in the affirmative (via S_OK), COM will unload it.

  • The Old New Thing

    Ringside seats at Fruit Fly Fight Club


    The first rule of Fruit Fly Fight Club: Flies can't talk about Fruit Fly Fight Club. Because they can't talk at all. At least not to humans.

    Researchers at Harvard Medical School took a break from studying lobster fighting and shifted their focus to fruit fly fights, and even mutant fruit fly fights.

    (Via The Annals of Improbable Research.)

    Fruit flies are strange creatures. Or perhaps it's that fruit fly researchers are strange creatures.

    One of my cousins was a fruit fly researcher. She took fruit fly testicles and squashed them and then studied them under a microscope, looking for... something... I forget. I think just finding the fruit fly testicles in the first place was accomplishment enough.

    Fruit fly researchers like to give their discoveries strange names. Typically, a gene is named after what results when you disable it. For example, a gene without which fruit flies die in two days is named Kenny, after the South Park character.

    My favorite: The gene without which fruit flies get drunk really easily is called cheap date. (That last page has several more funny gene names.)

    Yes, that's right. Fruit flies get drunk. There's a fruit fly drunk-o-meter, though I forget how it works. But one amusing aspect of fruit fly drunkenness is that just before they finally pass out, there's a big burst of activity.

    Strange gene naming has spread beyond the fruit fly world. There is a human gene named sonic hedgehog after the Sega video game character. (It's related to the fruit fly gene "hedgehog", so named because disabling it causes the fly to develop into a ball with spikes.)

  • The Old New Thing

    Suggestion box


    Post suggestions for future topics here instead of posting off-topic comments. Note that the suggestion box is emptied and read periodically so don't be surprised if your suggestion vanishes. (Note also that I am under no obligation to accept any suggestion.)

    Topics I are more inclined to cover:

    • Windows history (particularly the Windows 95 era).
    • Windows user interface programming in Win32, and shell programming in particular.
    • General programming topics (selectively).
    • Issues of general interest.
    • My personal hobbies.

    Topics I am not inclined to cover:

    • The blog software itself.  You can send feedback about .Text to its author, Scott Watermasysk.
    • Internet Explorer. You can try IE folks like Tony Schreiner, jeffdav, and Dave Massy.
    • Visual Studio.  You can try one of the Visual Studio blogs.
    • Non-software Microsoft topics, such as product support policies, marketing tactics, and hiring policy.
    • Microsoft software that isn't Windows. (Exchange, Office, ...)
    • Windows topics outside user interface programming. (Plug and Play, Terminal Services, Windows Messenger, Outlook Express, SQL, IIS, remoting, SOA...)
    • User interface programming in anything other than Win32. (Because I know nothing about it.)
    • Debugging a specific problem. (Not of general interest.)
    • Legal issues.
    • Predictions for the future. (What's the title of this blog again?)
Page 420 of 464 (4,635 items) «418419420421422»