May, 2007

  • The Old New Thing

    You'd think questions about underwear were understood to be off-limits


    Strange what sorts of things need to be spelled out explicitly nowadays. You know you're in trouble when your employee training includes a discussion of company policy regarding employees making inappropriate comments or questions about underwear.

  • The Old New Thing

    Visual C++ 2005 will generate manifests for you


    New in Visual C++ 2005 is the ability to specify a manifest dependency via a #pragma directive. This greatly simplifies using version 6 of the shell common controls. You just have to drop the line

    // do not use - see discussion below
    #pragma comment(linker, \
        "\"/manifestdependency:type='Win32' "\
        "name='Microsoft.Windows.Common-Controls' "\
        "version='' "\
        "processorArchitecture='X86' "\
        "publicKeyToken='6595b64144ccf1df' "\

    into your program and the linker will do the rest.

    Note that the processor architecture is hard-coded into the above directive, which means that if you are targetting x64, you'll get the wrong manifest. To fix that, we need to do some preprocessor munging.

    #if defined(_M_IX86)
    #elif defined(_M_AMD64)
    #elif defined(_M_IA64)
    #error Unknown processor architecture.
    #pragma comment(linker, \
        "\"/manifestdependency:type='Win32' "\
        "name='Microsoft.Windows.Common-Controls' "\
        "version='' "\
        "processorArchitecture='" MANIFEST_PROCESSORARCHITECTURE "' "\
        "publicKeyToken='6595b64144ccf1df' "\

    Update: I didn't know that * is allowed here to indicate "all architectures". That simplifies matters greatly.

    #pragma comment(linker, \
        "\"/manifestdependency:type='Win32' "\
        "name='Microsoft.Windows.Common-Controls' "\
        "version='' "\
        "processorArchitecture='*' "\
        "publicKeyToken='6595b64144ccf1df' "\

    Nitpicker's corner

    * That wasn't a footnote marker.

  • The Old New Thing

    The three things you need to know about tsunamis


    One of my friends is involved with Science on Tap, a free, informal monthly get-together in the Seattle area covering science topics for the general public. (Recent coverage in the Seattle-PI.) The topic for July 30th is "The three things you need to know about tsunamis", and a title like that pretty much sells itself.

  • The Old New Thing

    The sad predicament of the unempowered manager


    I just made up that term now because I needed a word to describe the situation where some manager is put in charge of a feature but is not given a staff to implement that feature. This happens more often than you might think, since there are many features that are "horizontal", i.e., features which affect all teams throughout the project. So-called taxes often fall into this category, such as power management, accessibility, and multiple monitors. (Larry Osterman calls them *bilities. I call them taxes.)

    The unempowered manager is in a predicament, having been assigned a task without a staff to accomplish it. All the unempowered manager can do is nag other people, usually about bugs that fall into the manager's area.

    Now, most of these unempowered managers understand that they are just one of many demands on the development teams, providing advice as necessary (since they have valuable specialized knowledge about the problem area) but basically trying to stay out of the way.

    Others, on the other hand, take upon themselves a much more active role in "driving" their pet issues. This means that I will get mail like this:

    You have an elephant† bug

    The following elephant bug is assigned to you:

    16384 Elephants not available in animal dropdown box (opened 2006/05/12)

    What is the ETA for fixing this bug?

    Somebody you've never heard of

    This is another case of "You're not my manager". My manager decides what tasks I should be working on and in what order. If you think this bug should be higher on my priority list, feel free to set up a little meeting with my manager to work this out. Until then, don't bug me. I have work to do.

    "But elephant-compatibility is important."

    Are you saying that all my other tasks are unimportant? What makes elephant-compatibility more important than my other tasks? Do you even know what my other tasks are?

    At one point, this got so bad, with many managers nagging me about their favorite bugs on a nearly daily basis, that I created a SharePoint site‡ called "Raymond's task list for <date>". Whenever somebody sent me nag mail, I replied, "I have added your request to my SharePoint site and assigned it a default priority." And then I never heard from them again.

    For those new to this web site (and a reminder to those with poor memory):

    †I disguise the name because (1) it's not important to the story, and because (2) the goal is not to ridicule but rather to illustrate a point. Attempts to guess what "elephant" is will be deleted. Don't make me delete further stories in this series like I did with "Stories about Bob."

    Nitpicker's corner

    ‡Or, if you're a trademark lawyer, "A Web site powered by Microsoft® SharePoint® services."

    *Here's your stupid asterisk.

  • The Old New Thing

    Let's talk like people


    On Mark Rosenfelder's Zompist web site I found a series of cultural guides named How to tell if you're ‹nationality. All of the entries are simultaneously funny and insightful, such as this one from Turkey:

    A company can fire just about anybody it wants. But it will also hire anybody.

    For some reason, my favorite is this one from the Polish entry:

    When you negotiate, you are polite, of course, but it's only good business to 'play hardball'. You don't say what you mean, you pretend not to know many things, but you surely never lie. You know the other side does the same thing, and they know you know. Many people are tired of it, so they start talking normally. You say "let's talk like people" then.

    I like how the Poles understand that it's all an act, and they have a code for saying, "This is stupid."

    While you're there, you should also check out The Zompist Phrasebook, the absolutely worst phrasebook you'll ever find that's still hilarious.

  • The Old New Thing

    Psychic debugging: Why does FormatMessage say the resource couldn't be found?


    Solving this next problem should be a snap with your nascent psychic powers:

    I'm trying use FormatMessage to load a resource string with one insertion in it, and this doesn't work for some reason. The string is "Blah blah blah %1. Blah blah blah." The call to FormatMessage fails, and GetLastError() returns ERROR_RESOURCE_TYPE_NOT_FOUND. What am I doing wrong?
    LPTSTR pszInsertion = TEXT("Sample");
    LPTSTR pszResult;
            //I also tried an instance handle and NULL.
            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // default language
            (LPTSTR) &pszResult,
            (va_list*) &pszInsertion); 

    Hint: Take a closer look at the parameter IDS_MY_CUSTOM_MESSAGE.

    Hint 2: What does "IDS_" tell you?

    Resource identifiers that begin with "IDS_" are typically string resource identifiers, not message resource identifiers. There is no strong consensus on the naming convention for message resource identifiers, although I've seen "MSG_". Part of the reason why there is no strong consensus on the naming convention for message resource identifiers is that almost nobody uses message resources! I don't understand why they were added to Win32, since there was already a way of embedding strings in resources, namely, string resources.

    That's why you're getting ERROR_RESOURCE_TYPE_NOT_FOUND. There is no message resource in your module. If you're not going to use a message resource, you'll have to use the FORMAT_MESSAGE_FROM_STRING flag and pass the format string explicitly.

    DWORD_PTR rgdwInsertions[1] = { (DWORD_PTR)TEXT("Sample") };
    TCHAR szFormat[256];
    LoadString(hInstance, IDS_MY_CUSTOM_MESSAGE, szFormat, 256);
    LPTSTR pszResult;
            (LPTSTR) &pszResult,
            (va_list*) &rgdwInsertions); 

    I also made a slight change to the final parameter. When you use FORMAT_MESSAGE_ARGUMENT_ARRAY, the last parameter must be an array of DWORD_PTRs. (The parameter must be cast to va_list* to keep the compiler happy.) It so happens that the original code got away with this mistake since sizeof(DWORD_PTR) == sizeof(LPTSTR) and they both have the same alignment requirements. On the other hand, if the insertion were a DWORD, passing (va_list*)&dwValue is definitely wrong and can crash if you're sufficiently unlucky. (Determining the conditions under which your luck runs out is left as an exercise.)

  • The Old New Thing

    Cool, they're using Roman numerals!


    The IT department here will periodically send out notifications regarding changes to the network infrastructure or updates that are being deployed across the company. One of my colleagues sent me email saying, "Cool, they're using Roman numerals!" It was in response to one particular IT notification that included the following sentence:

    This update will require approximately X minutes.
  • The Old New Thing

    Raymond's SIFF schedule (2007)


    Nobody asked, but I'm going to post it anyway. These are the movies I'm planning on seeing, along with my twisted take on the plot, based solely on the movie description.

    12:08 East of Bucharest Fri May 25 5:00pm (PP)
    Residents of a Romanian town differ in their recollections of how they overthrew Ceaucescu.
    Fair Play Sat May 26 1:15pm (N)
    Office politics viewed through the filter of "casual" outdoor sporting activities.
    Outsourced (sold out) May 31 7:00pm (LS)
    American's job is outsourced to India. He is sent to train his replacement. She's cute.
    Death at a Funeral Fri Jun 1 7:00pm (LS)
    Fancy funeral. Somebody dies. Hilarity ensues.
    Cashback Sat Jun 2 6:45pm (LS)
    Clerks + Heroes = ?
    Tell No One Sun Jun 3 1:30pm (N)
    French thriller. Man accused of wife's death. Will probably spend a lot of time running.
    Falling Sun Jun 3 9pm (HE)
    High school friends reunite. Drama ensues.¹
    2 Days in Paris Tue Jun 5 7pm (LS)
    French screwball comedy. That's all you need to know.
    Hula Girls Sat Jun 9 4pm (LS)
    Japanese town reinvents itself as a spa. With hula girls.²
    Grandhotel Mon Jun 11 4:30pm (LS)
    Intruiguing rom-com set in a hotel.
    The Boss of It All Wed Jun 13 7pm (LS)
    Company director shifts blame to imaginary superior. Works great until people ask to meet him.³
    Vacation Sun Jun 17 11am (LS)
    Quiet family get-away. Relatives show up unexpectedly. Drama ensues.¹

    ¹These movies were chosen in large part to serve as German lessons.

    ²I have a weak spot for slightly off-kilter Japanese movies set in the modern day.

    ³Swedish class group movie. Even though it's in Danish.

    Since Outsourced is sold out, I'll have to find another movie to replace it. Possibilities include French for Beginners, Mushihi, The Three Musketeers (animated), and Eagle vs. Shark.

  • The Old New Thing

    The parameters to PostQueuedCompletionStatus are not interpreted


    Larry Osterman mentioned this almost in passing quite a while ago, that the parameters to PostQueuedCompletionStatus are not interpreted by the operating system. Well, obviously the first parameter, the handle to the completion port, is interpreted as the handle to the completion port. But the other parameters, dwNumberOfBytesTransferred, dwCompletionKey, and lpOverlapped are not interpreted at all. Even though they have names, the names don't mean anything. Whatever values you pass for those three parameters merely pop out of GetQueuedCompletionStatus when the notification packet makes it to the head of the queue.

    Why do the parameters have names if the names don't mean anything?

    Because the operating system itself will post notifications to the completion port if you ask it to, and in that case, the values returned by the GetQueuedCompletionStatus function really mean something related to their names. For example, if you issued an asynchronous read to a file that is associated with a completion port, then the dwNumberOfBytesTransferred really is the number of bytes transferred, the dwCompletionKey really is the completion key that you associated with the file handle when you called CreateIoCompletionPort, and the lpOverlapped really is the pointer to the OVERLAPPED structure that you originally issued the read request against.

    But if you call PostQueuedCompletionStatus manually, then you can choose any values you want. Of course, if you're going to mix operating system-generated completion port activity with manually-generated completion port activity, it would be in your best interest to use the dwCompletionKey (or if you're really clever, the lpOverlapped) in a consistent manner so that you can tell whether a notification came from the I/O subsystem or was one you generated manually.

    But it's up to you.

  • The Old New Thing

    Being nominated for the Nobel Prize isn't as big a deal as it sounds


    Occasionally, somebody will use the fact that they were nominated for the Nobel Prize as some sort of proof that they are a qualified or well-respected person. Except that it proves no such thing.

    This isn't like the Academy Awards or the Pulizter Prize for which receiving a nomination means that you are one of a handful of finalists. For the Nobel Prize committee, nomination is just the first step, and there is no restriction on how many people can be nominated. In particular, the list of people authorized to submit nominations for the Nobel Peace Prize includes "members of national assemblies and governments of states." For the United States, this means that any member of the Executive Branch and any member of Congress can submit a nomination. Deputy Under-Secretary of Transportation? Sure.

    The easiest way in is to convince a House Representative to submit a nomination for you, since there are over 400 of those positions, and each one represents fewer than a million people. Representatives are known for being quirky, so shop around. I'm sure you'll find somebody who would be willing to submit your name. It costs them nothing, after all.

    According to the rules of the Nobel Committee, the list of nominees (and nominators) is kept secret for fifty years. You can search the database of Peace Prize nominees from 1901 to 1951 to see whether your favorite figure or organization is in it.

    With a nod to Godwin's Law,† I point out that even Adolf Hitler was nominated for a Nobel Peace Prize.

    Nitpicker's corner

    †Notice that I am not invoking Godwin's Law, since this is not an instance of it. I'm merely acknowledging its existence.

Page 1 of 5 (44 items) 12345