September, 2010

  • The Old New Thing

    2010 Q3 link clearance: Microsoft blogger edition


    It's that time again: Sending some link love to my colleagues.

  • The Old New Thing

    Why doesn't the TAB key work on controls I've marked as WS_TABSTOP?


    A customer had a programming problem regarding tab stops:

    I create a parent window (child of main frame) as below

    // Create the popup window that holds the toolbar.
    if (!CreateEx(
            0, 0, 0, 0,

    This window hosts 2 toolbar windows. Each toolbar window has the WS_TABSTOP style set using SetWindowLong.

    // Set tab stop for accessibility
    DWORD dwStyles = ::GetWindowLong(GetSafeHwnd(), GWL_STYLE);
    ::SetWindowLong(GetSafeHwnd(), GWL_STYLE, dwStyles | WS_TABSTOP);

    MSDN states

    WS_EX_CONTROLPARENT Allows the user to navigate among the child windows of the window by using the TAB key.

    But I am not able to use TAB to navigate to second toolbar. I tried handling WM_GETDLGCODE and return DLGC_WANTTAB. But this message is not sent to parent.

    I can try subclassing the toolbar to handle TAB key, but if I do that, then what's the point of the WS_TABSTOP and WS_EX_CONTROLPARENT styles?

    You already know how to solve this customer's problem. The quoted documentation comes from the MFC documentation on extended window styles. You may find that the documentation in the Platform SDK to be a bit better. Which is not unexpected, since extended window styles are a Platform SDK feature; MFC is merely surfacing the underlying Win32 functionality in its own framework.

    Final clue: Look at this old blog entry, but come to it with a different point of view.

    I used my psychic powers to solve this one. A close reading of the description of the problem reveals that the window in question is not part of a dialog box, which means that the standard dialog message loop is not active. Which means that a crucial step is missing.

    Did you remember to call IsDialogMessage in your message loop?

    The customer confirmed that this was the missing step.

    You are right, my window is not a dialog box. Handling IsDialogMessage solved the issue.
  • The Old New Thing

    We apologize for the delay, but there is an issue with the music


    After the opening work of the Seattle Symphony concert last Saturday night, the orchestra members rearranged themselves to play the Foote, but conductor Gerard Schwarz didn't come out onto the stage. The delay grew and people started wondering what was going on.

    An announcement was made over the public address system: "We apologize for the delay, but there is an issue with the music."

    This only created more confusion. What does "an issue with the music" mean?

    Eventually, Schwarz took the podium and explained what happened. It turned into a game of good news/bad news. "The good news is that one of the orchestra members was so dedicated that even after two concerts, he wanted to practice the piece some more. The bad news is that he left the music at home. Fortunately, he doesn't live far away, and he has his part in the Brahms memorized, so we will play the Brahms now and perform the Foote after the intermission."

    And just for the record, my impressions of the concert, since you didn't ask.

    • Schwantner The Poet's Hour: Calm, soothing music from the orchestra is rudely disturbed by dissonant music from the violin soloist.
    • Brahms Symphony #3: No real surprises.
    • Foote Francesca da Rimini: I was pleasantly surprised by this piece. It was actually rather nice.
    • Prokofiev Piano Concerto #2: While technically impressive, I understand why this piece received a hostile reception at its premiere.
    • New hairstyles (and colors) for the concertmaster and principal second violin.
  • The Old New Thing

    Where did my mail control panel icon go?


    A customer ran into the following problem:

    I was trying to add another email account to Outlook, and the instructions say that I should go to the mail icon in the Control Panel, which to my surprise is nowhere to be found! How can I figure out what went wrong?

    A little bit of psychic debugging will solve this.

    The customer was running Windows Vista, 64-bit edition. On 64-bit versions of Windows XP and Windows Vista, the Control Panel shows only 64-bit control panels. The 32-bit control panels are off in a separate 32-bit control panel, which you can find by clicking the View 32-bit Control Panel Items icon.

    The separation of 32-bit and 64-bit control panels is an unfortunate consequence of the rule that 64-bit processes cannot load 32-bit DLLs and vice versa. On 64-bit Windows, Explorer is a 64-bit process, which means that it can't load traditional 32-bit control panels. (Recall that control panel applications run as DLLs inside the host process.) Therefore, Explorer has to pass off the work of working with 32-bit control panel applications to a 32-bit alter ego process.

    Fortunately, Windows 7 no longer segregates control panel applications by bitness: They all appear in the main Control Panel. This was done by running a puppet 32-bit copy of the Control Panel behind the scenes and making the puppet do the main Control panel's bidding whenever it needed to access information about 32-bit control panel applications.

    "Hey, go enumerate the 32-bit control panel applications for me."

    "Hey, go get the icon for this 32-bit control panel application."

    "Hey, go launch this 32-bit control panel application."

    "Hey, go make me a sandwich."

    "Hey, give me a backrub."

  • The Old New Thing

    Speculation around Microsoft Company Meeting 2010


    Today is Microsoft's annual Company Meeting.

    Back in August, the Real Estate and Facilities department sent a message to our group of buildings to inform us that the locker rooms would be closed "due to the filming of an upcoming corporate initiative."

    Speculation swirled as to what sort of "upcoming corporate initiative" would require filming in a locker room. The Company Meeting was only a month away, and I suggested that Steve Ballmer might be filming a (shudder) parody of the Old Spice Guy commercial.

    Picking up the ball, one of my colleagues wrote the proposed script for this parody:

    Hello developers. How are you? Fantastic.

    Does your CEO look like me? Yes.

    Can he code like me? Yes.

    Should you be using Windows 7? I don't know.

    Do you like the feel of productivity? Do you want an operating system that can stream your favorite movies while you tweet about the interesting article you're currently reading on Wikipedia? Of course you do.

    SWANDIVE into the best user experience of your life!

    So should you be using Windows 7? You tell me.

    Here's the commercial being parodied, and the first commercial in the series.

  • The Old New Thing

    Children's reactions to macadamia nuts dipped in chocolate


    Some time ago, we had some people over our house for dinner, and we had a selection of desserts including chocolate-covered macadamia nuts. The children in attendance finished their dinner before the adults (because the adults were busy doing boring things like talking) and were excused to go play.

    It so happens that the play room is right next to the kitchen, and in the kitchen was the dessert table, including a bowl of chocolate-covered macadamia nuts, which the children managed to consume in their entirety before the adults finally finished talking and went to get dessert.

    The second half of the story didn't come until a few days later, when we were taking out the recycling. At the bottom of the recycling bin was a collection of macadamia nuts with all the chocolate sucked off.

    (I was reminded of this story by laonianren's comment on chocolate-covered Brazil nuts.)

  • The Old New Thing

    Why not just require each application to declare what version of Windows it is compatible with?


    Via the Suggestion Box, Arno Shoedl asked, "could not a lot of compatibility problems be solved by simply declaring (via manifest?) the earliest and latest version of Windows a program has been tested to run on?"

    Actually, programs already declare that, sort of. Each module has a subsystem field in the header that specifies the earliest version of Windows the program will run on. There isn't a corresponding way to declare the maximum version of Windows you want to run on, however, so the manifesty thing could be done there. (There is a new manifesty way of saying what version of Windows you would like to see.)

    But let's look at the bigger picture: In order to benefit from this proposed feature, an application author would have to do some extra work to declare in a manifest what versions of Windows they prefer to run on. That's already a bunch of work that gets in the way (because to an application author, any amount of work greater than zero that doesn't correspond to business logic is "a bunch of work that gets in the way"). Which means most people won't bother doing it.

    So you're back to where you started.

    Even if we could somehow convince application authors to get off their butts and do things that do not benefit them personally (like all the other programming taxes), that won't help all the programs out there that don't have any such manifest.

    "Okay, well, let's just say that any program that doesn't have a compatibility manifest is treated as compatible with a maximum of Windows 7."

    Great. Where do you put the manifest for a batch file?

    There's a bigger problem, which is applications which are built out of DLLs. What if an application is manifested as "I have been tested only on Windows XP" and it loads a DLL that is manifested as "I have been tested only on Windows Vista"? Now there is no version of Windows that both the application and the DLL have been tested with together. What does GetVersion return? Even if your program doesn't have a plug-in model, you're not out of the woods. If you call ShellExecute or GetOpenFileName, the shell namespace will get loaded, and with it all sorts of shell extensions who may be manifested all sorts of different ways.

    And then you have the cross-process communication problem. Suppose you drag an object out of a program marked as I was tested with Windows 7 and drag it over a window that belongs to a program marked as I was tested only with Windows XP. How do you communicate this information back to the data source so it knows "Be very careful. You're from the future. Don't tell that process about any data that didn't exist in Windows XP. You might disrupt the time stream."

    Another problem, of course, is that just because a program says that it has been tested on Windows XP doesn't mean that it's actually going to run on Windows XP. There are many categories of bugs that appear only on configurations that were unusual on Windows XP but more common on later versions of Windows. (For example, "My user profile isn't in a directory called Documents and Settings.") Even if a program says that it was tested on Windows XP, that doesn't mean that running the old Windows XP operating system code is enough to keep it happy.

    And of course there's the question of whether you want this in the first place. If we had introduced this model back in Windows 2000, by the time you have reached Windows 7, you could have a screen with applications that have three different visual styles: A program manifested as being tested only on Windows 2000 would have the Windows 2000 look, another program would have the Windows XP look, and a third program would have the another program would have the Windows 7 look. Even better: When Windows 7 came out, no applications would have the Windows 7 look since the manifest couldn't declare that it was compatible with something that didn't exist.

    Looking at it another way, the manifest is basically a way for an application to say "Please run me in compatibility mode." But as we saw before, application compatibility layers are there for the customer, not for the program.

    Bonus reading: Manifesting for Compatibility on Windows 7.

  • The Old New Thing

    Does anybody actually like Brazil nuts?


    Brazil nuts are perhaps best known for floating to the top of a jar of mixed nuts. According to Wikipedia,¹ the reason for the phenomenon is not well understood.

    At least in my house, the reason for the phenomenon is quite clear: Brazil nuts float to the top because nobody in my house likes Brazil nuts. When you reach in and grab a handful of nuts, you toss the Brazil nuts back into the jar, which is why they end up on top.

    A few months ago, I asked "Does anybody actually like Brazil nuts?" A lot of people agreed with my opinion of them, but there was a notable dissenter: Larry Osterman. There is now a symbiotic relationship between my family and Larry Osterman. Every so often, I will skim off the Brazil nuts and bring them to Larry. Both sides win: We get rid of the annoying Brazil nuts, and Larry gets a small bag of Brazil nuts.

    ¹ Translation: I could just as well be making this up.

  • The Old New Thing

    How reliable is the BatteryLifePercent member of the SYSTEM_POWER_STATUS structure?


    A customer was writing a program that called Get­System­Power­Status and used the SYSTEM_POWER_STATUS.Battery­Life­Percent value. The customer wanted to know whether a reported battery life percentage of 38% really means that the remaining battery life is between 37.5% and 38.5%.

    Although the value is reported to 1% precision, the accuracy in practice is much worse. Similarly, the Battery­Life­Time is reported in seconds, but if your battery actually lasts exactly the amount of time predicted by that field (and not a second longer or shorter), it's almost certainly a fluke. Even a stopped clock is right twice a day.

    These battery levels come from the hardware itself, so you are at the mercy of whoever manufactured your motherboard. Some laptops update the values at 1-second intervals; others can take 5 seconds or more. In practice, these hardware-reported values have been found not to be particularly precise, and in odd cases have occasionally been spotted behaving in strange ways, such as spiking briefly and then returning to a sane value.

    But if you use the values (as flaky as they might be), you'll at least be in good company: These are the same values that the Windows Battery Meter displays.

    Bonus chatter: There's another interface for retrieving battery life information, and that's WMI Win32_Battery.Estimated­Run­Time. The values for this also come from the hardware, but they are more unstable than the values returned by Get­System­Power­Status because the estimated run time is an extrapolation based on the current battery load. This makes it more sensitive to short-term fluctuations in energy consumption, creating the paradoxical situation where more accurate information is actually less useful.

  • The Old New Thing

    Pizza: The reference food for young children


    One way to convince a child to try out an unfamiliar food is to say that it's an alternate form of pizza. Here are some examples. Feel free to add more in the comments.

    • Quesadilla: Mexican pizza
    • Dosa: Indian pizza
    • Quiche: French deep-dish pizza

    I had originally listed crêpe as French pizza, then realized it's more like a French pancake. (I wonder what the Italian version of pizza would be...)

Page 1 of 4 (31 items) 1234