September, 2007

  • The Old New Thing

    Astrologers struggling with reclassification of Pluto


    One of the consequences of the demotion of Pluto from planet to dwarf planet is being felt by astrologers, who now have to decide what role the body plays in the lives of mere humans.

    I remember reading an article many years ago wherein the writer asked several astrologers what impact the discovery of a new planet would have on their craft and whether it would render earlier predictions incorrect.

    Some argued that horoscopes developed before all nine planets (as there were then) were discovered were inaccurate. As astronomers discover more planets, the predictions of astrologers become more accurate. This position at least strikes me as defensible once you get over the proposition that a hunk of icy rock orbiting at the edge of the known solar system has any influence whatsoever on whether you feel cranky today.

    The position I found more baffling was the one that claimed that those old horoscopes were still good, because only after they are discovered do planets begin to influence the lives of humans. Why would a hunk of rock behave differently depending on whether we know it exists or not?

    Or maybe their point is that astrology is all about how humans perceive the planets and not the other way around.

  • The Old New Thing

    Making some statements and asking for advice isn't a question


    This is a corollary to Don't forget to ask your question: Making some statements and asking for advice isn't a question.

    When we do X, and then select Y, and then click the Q button, we get an error message saying that Q can't be performed because "The computer Z that Y refers to cannot be contacted." Can you provide advice?

    Now, this person did remember to ask a question, but the question doesn't really specify what sort of advice was desired. In this case, the question might be "Can you please provide advice on how we can avoid that error message?" But even that isn't a good question.

    The error message already told you how to fix the problem: Re-establish the connection to the computer Z. Is the problem that you think the connection is working and you're still getting the error? Is the problem that you don't want to or can't establish a connection to computer Z, but you still want to perform operation Q? Why do you think it should be possible to perform the operation even though there is no Z? Do you simply want to suppress the error message?

  • The Old New Thing

    The wisdom of seventh graders: A Wrinkle in Time


    The recent passing of Madeleine L'Engle reminded me of a quiz seventh grade students were given in order to see whether they were at least paying attention during a reading of a chapter from A Wrinkle in Time. I forget the question exactly, but it asked the students about the mechanism that Mrs Who, Which and Whatsit use to travel through the universe. The correct answer was "The fifth dimension."

    One student, who was apparently was paying only part attention during class, wrote "The third dimension."

    Let's run down the street. "Woo! I'm travelling through the third dimension!"

  • The Old New Thing

    What's the difference between EM_UNDO and WM_UNDO?


    Daniel Chait wonders why we have both EM_UNDO and WM_UNDO. You know, I wonder the same thing. But I'm going to make an educated guess.

    Actually, most of what I write is just a lot of educated guessing. Like my explanation of why GetWindowText has such complicated rules? A guess. Why address space granularity is 64KB? A guess. Why most EM_* messages are in the system message range? A guess. Mind you, it's logical guesswork, usually strongly guided by the principle of "Imagine if this were possible."

    Today's guesswork: The history of EM_UNDO and WM_UNDO.

    It seems obvious that EM_UNDO came first. After all, why would there need to be a EM_UNDO message if a WM_UNDO already existed?

    At some point, somebody decided, "Hey, this sounds like something that people might want to do more generally." New messages WM_CUT, WM_COPY, WM_PASTE, WM_CLEAR, and WM_UNDO were added, and the first control to implement them was the edit control.

    Therefore, the answer to the question is that for edit controls, the difference is that there is no difference.

    The window manager does not provide a default implementation for any of these new messages. (Obviously, because the window manager is not psychic.) If you want your control to support those operations, you'll have to respond to the messages yourself.

  • The Old New Thing

    The Minimalist Jukebox Festival


    Last year, NPR covered The Minimalist Jukebox Festival, a week-long exploration of the school of minimalist music. The NPR story includes a clip of my favorite minimalist work: Music for 18 Musicians, as well as a telling of the classic minimalism knock-knock joke.

    I remember reading somewhere that the world premiere of Music for 18 Musicians was performed by an ensemble of only seventeen musicians by doubling up a vocalist with an instrumental line. This was done to reduce the cost of travel. If true, it would make for another one of those "Unfair trivia questions" like "How many years did the Hundred Years' War last?"

    One last story about 18 Musicians before I let you go. One of the managers in my group needed an audio CD to demonstrate some feature or other, so he came into my office and borrowed my copy of 18 Musicians, unaware of what lay in store. When he returned the CD afterwards, he told me that when he popped in the CD, he thought it was skipping, since the opening of the piece consists of a single note repeated. That's what you get when you borrow a CD of minimalism...

  • The Old New Thing

    If control-specific messages belong to the WM_USER range, why are messages like BM_SETCHECK in the system message range?


    When I discussed which message numbers belong to whom, you may have noticed that the messages for edit boxes, buttons, list boxes, combo boxes, scroll bars, and static controls go into the system range even though they are control-specific. How did those messages end up there?

    They didn't start out there.

    In 16-bit windows, these control-specific messages were in the control-specific message range, as you would expect.

    #define LB_ADDSTRING      (WM_USER + 1)
    #define LB_INSERTSTRING   (WM_USER + 2)
    #define LB_DELETESTRING   (WM_USER + 3)
    #define LB_RESETCONTENT   (WM_USER + 5)
    #define LB_SETSEL         (WM_USER + 6)
    #define LB_SETCURSEL      (WM_USER + 7)
    #define LB_GETSEL         (WM_USER + 8)
    #define LB_GETCURSEL      (WM_USER + 9)
    #define LB_GETTEXT        (WM_USER + 10)

    Imagine what would have happened had these message numbers been preserved during the transition to Win32,

    (Giving you time to exercise your imagination.)

    Here's a hint. Since 16-bit Windows ran all programs in the same address space, programs could do things like this:

    char buffer[100];
    HWND hwndLB = <a list box that belongs to another process>
    SendMessage(hwndLB, LB_GETTEXT, 0, (LPARAM)(LPSTR)buffer);

    This reads the text of an item in a list box that belongs to another process. Since processes ran in the same address space, the address of the buffer in the sending process is valid in the receiving process, so that when the receiving list box copies the result to the buffer, it all works.

    Now go back and imagine what would have happened had these message numbers been preserved during the transition to Win32.

    (Giving you time to exercise your imagination.)

    Consider a 32-bit program that does exactly the same thing that the code fragment above does. The code probably was simply left unchanged when the program was ported from 16-bit to 32-bit code, since it doesn't generate any compiler warnings and therefore does nothing to draw attention to itself as needing special treatment.

    But since processes run in separate address spaces in Win32, the program now crashes. Well, more accurately, it crashes that other program, since it is the other program that tries to copy the text into the pointer that it was led to believe was a valid buffer but in fact was a pointer into the wrong address space.

    Just what you want. A perfectly legitimate program crashes because of somebody else's bug. If you're lucky, the programmers will catch this bug during testing, but how will they know what the problem is, since their program doesn't crash; it's some other program that crashes! If you're not lucky, the bug will slip through testing (for example, it might be in a rarely-executed code path), and the experience of the end user is "Microsoft Word crashes randomly. What a piece of junk." (When in reality, the crash is being caused by some other program entirely.)

    To avoid this problem, all the "legacy" messages from the controls built into the window manager were moved into the system message category. That way, when you sent message 0x0189, the window manager knew that it was LB_GETTEXT and could do the parameter marshalling for you. If it had been left in the WM_USER range, the window manager wouldn't know what to do when it gets message 0x040A since that might be LB_GETTEXT, or it might be TTM_HITTESTA or TBM_SETSEL or any of a number of other control-specific messages.

    Theoretically, this motion needed to be done only for legacy messages; i.e., window messages that existed in 16-bit Windows. (Noting that Windows 95 added some new 16-bit messages, so this remapping had to continue at least through Windows NT 4 with the shell update release.) Nevertheless, the window manager team added the *_GET*INFO messages in the system message range even though there was no need to put them there from a compatibility standpoint. My suspicion is that it was done to make things easier for accessibility tools.

    Note however that placing new messages in the system message range is more the exception than the rule for the edit box and other "core" controls. For example, the new message EM_SETCUEBANNER has the numeric value 0x1501, which is well into the WM_USER range. If you try to send this message across processes without taking the necessary precautions, you will crash the target process.

    (Note: Standard disclaimers apply. I won't bother repeating this disclaimer on future articles.)

  • The Old New Thing

    Wayback machine: The Fake Job


    Digging through my pile of junk, I found a reference to a fake article in The New Yorker magazine titled My Fake Job that turned out to be (partly) fake itself. Unfortunately, I missed the article the first time around so I didn't get to see what all the excitement was about, but it sure sounded like a funny article. (Fractionally more details from the article here.)

    I understand there are these buildings called "libraries" that keep hard copies of this stuff. Need to make a mental note to check one out someday.

  • The Old New Thing

    Sometimes it feels like the effort isn't even appreciated


    Some time ago, the application compatibility folks found a program that was corrupting the heap, and they applied a fix that worked around the specific type of corruption that the program performed.

    And then a bug came on that same program. It was a heap corruption failure during the program's processing of global destructors.

    The authors of that program were so clever, they found a way around the compatibility fix and managed to corrupt the heap anyway!

    Update: To clarify, there was no updated version of the program. (That's why I wrote "that same program" and not "an updated version of that program".) There was a bug in XYZ Version 2.1. We added a compatibility fix for it. And then later, another bug came in, also for XYZ Version 2.1 showing that the compatibility fix wasn't good enough. We tried to fix their heap corruption, but they were too clever and corrupted it in another way in a different part of the program.

  • The Old New Thing

    It's that season again: The 2007 Microsoft Company Meeting


    Yes, it's that time of year again, time for the annual Microsoft Company Meeting, and therefore time for another of Raymond's reminiscences about meetings past. (If you want a report on the meeting itself, I'm sure Mini-Microsoft will oblige. Here's the company meeting preview.)

    Over a decade ago, one of my colleagues informally organized a bike ride to the company meeting. (I didn't go; this was before I had taken up bicycling.) He got a small group of people from the organization to join him, and as they headed out in the morning, they "accidentally" made a wrong turn and headed towards North Bend instead of Seattle. By the time they "realized their mistake" it was too late, and they were "forced" to bicycle through rural King County, arriving back at work just as the meeting ended.

  • The Old New Thing

    If your theory is "build it and they will come", you have to make sure there is a "they"


    Creating an infrastructure for managing the content you wish you had doesn't actually create that content.

    Another possible response to the crisis management issue I considered yesterday is to say "Okay, we need to have an official Company X Breaking News site so that people who are looking for an official response to some hot topic can find it."

    Except that if you look at the original problem, it wouldn't have helped. The problem wasn't that there was a response to the hot topic that nobody could find. There was no response at all because the people who would formulate that response were busy working on the problem. Having a "Company X Breaking News" site wouldn't have helped because there was no content to put in it in the first place!

    Generate the content first, and then worry about how to present it. And I think that once the content shows up—wherever it shows up—people will find it even without needing a "Company X Breaking News" site. Some blogger will find it, and if it really is a hot topic, then the link will spread. (And if it's not a hot topic, then the link will languish since nobody cares about it.)

    This is something I see a lot of: thinking that you can solve the "We need good content!" problem by creating some infrastructure to manage that content you want to have. This isn't a "Build it and they will come" thing, because there is no they. The way to solve the "We need good content!" problem is "Produce good content!"

Page 3 of 4 (36 items) 1234