February, 2007

  • The Old New Thing

    Why can't I create my dialog box? Rookie mistake #2

    • 8 Comments

    Another class of rookie mistake is less obvious from looking at the code.

    #define DLG_SAMPLE 1
    
    DLG_SAMPLE DIALOGEX 32, 32, 210, 200
    ...
    BEGIN
     ...
     CONTROL "",IDC_LISTVIEW,WC_LISTVIEW,LVS_REPORT |
             WS_TABSTOP | WS_BORDER,
             14,92,182, 80
     ...
    END
    
    DialogBox(hinst, MAKEINTRESOURCE(DLG_SAMPLE),
              hwnd, SampleDlgProc);
    

    The problem with this code is that we forgot to call InitCommonControlsEx to register the listview class. More generally, the problem is that one of the controls on the dialog uses a window class that was not registered. (For example, maybe there's a rich edit control on the dialog, but nobody remembered to load the rich edit library.)

    Next time, a sophomore version of this mistake.

  • The Old New Thing

    Why can't I create my dialog box? Rookie mistake #1

    • 21 Comments

    Each dialog box resource is specified either by an integer ordinal or by a string name. But a simple typo will turn one into the other.

    #define DLG_OPEN 1
    #define DLG_WARN_REMOVEABLE 2
    
    DLG_OPEN DIALOG 32, 32, 267, 73
    ...
    BEGIN
      ...
    END
    
    DLG_WARN_REMOVABLE DIALOG 32, 32, 267, 73
    ...
    BEGIN
      ...
    END
    
    DialogBox(hInstance, TEXT("DLG_OPEN"),
              hwnd, OpenDialogProc);
    
    DialogBox(hInstance, MAKEINTRESOURCE(DLG_WARN_REMOVEABLE),
              hwnd, WarnRemoveableDialogProc);
    

    Do you see the two "classic rookie mistakes"?

    It may be easier to spot if you take the resource file and send it through the preprocessor first:

    1 DIALOG 32, 32, 267, 73
    ...
    BEGIN
      ...
    END
    
    DLG_WARN_REMOVABLE DIALOG 32, 32, 267, 73
    ...
    BEGIN
      ...
    END
    

    The first call to DialogBox passes TEXT("DLG_OPEN") as the resource name. But notice that there is no resource with that name. The preprocessor turned DLG_OPEN into 1 thanks to the line #define DLG_OPEN 1 in the header file. Therefore, the call to DialogBox fails since there is no dialog box named DLG_OPEN. The dialog box you want goes by the integer name 1.

    DialogBox(hInstance, MAKEINTRESOURCE(DLG_OPEN),
              hwnd, OpenDialogProc);
    

    The second mistake is more subtle. Notice that the name of the second dialog is spelled inconsistently. The header file calls it DLG_WARN_REMOVEABLE, but the resource file calls it DLG_WARN_REMOVABLE. As a result, the preprocessor macro is not invoked, and the result is a dialog that goes by the string name TEXT("DLG_WARN_REMOVABLE"). However, the code asks for MAKEINTRESOURCE(DLG_WARN_REMOVEABLE), which doesn't exist.

    To fix the second issue, you first have to decide what you really wanted. You probably wanted an integer dialog resource, in which case the fix is to correct the resource file:

    DLG_WARN_REMOVEABLE DIALOG 32, 32, 267, 73
    

    On the other hand, if you really wanted the dialog box to be a named resource (note: this is extremely rare), then you need to request it by name:

    DialogBox(hInstance, TEXT("DLG_WARN_REMOVABLE"),
              hwnd, WarnRemoveableDialogProc);
    

    We'll look at a few more "rookie mistakes" over the next couple of days.

  • The Old New Thing

    Bonus material for The Old New Thing (the book) is now available for download

    • 28 Comments

    I've just been informed by my publisher that the bonus chapters from my book are now available for download. Click on "Sample Chapters". Sorry they're late.

    The source code for the programs in the book can be downloaded from the "Source Code" link. And on a more embarrassing note, there's that "Errata" link, too.

  • The Old New Thing

    Public service announcement for United States taxpayers: In tax year 2006, you can claim a $30 refund if you owned a telephone

    • 75 Comments

    The United States government authorized a one-time refund of long-distance excise taxes paid between March 2003 and July 2006, but early returns suggest that many taxpayers are unaware of this refund. (Here's the IRS press release that goes into more detail and includes a list of most common mistakes people have been making.) The easy way to claim this is merely to take the standard deduction of $refund; the hard way is to collect all your telephone bills from that period and compute how much long distance excise tax you actually paid.

    This entry also illustrates how all the nitpicking from commenters over the years has altered the way I write, forcing me to put all sorts of clarifying information into the subject line—making it rather unwieldy—so that people won't carp about how the entry applies only to United States income taxes. Remember when blogs were an informal communication mechanism? Where you could leave mathematical precision behind, relying on your readers to fill in the gaps? When you could toss together a sample program without people obsessing over the grayscale algorithm you used? Or use phrases like "regular people like you and me" without being taken to task for implying that other people aren't regular? I miss those days. Blogging isn't all that much fun now; it's more of a chore.

    (And I predict that somebody is going to nitpick my article and lambaste me for missing the fact that the exact amount of the refund varies depending on how many exemptions you claim. So here's the disclaimer: This entry is provided for informational purposes only and should not be construed as providing tax advice. Consult with an attorney or tax professonal regarding any specific legal or tax situation.)

  • The Old New Thing

    Why did Explorer say "The target you specified is on the desktop"?

    • 34 Comments

    In Windows 95, if you had a shortcut to a file on the desktop, view the shortcut's properties, and then clicked "Find Target", you got the message "The target you specified is on the desktop". It also selected the item on the desktop to help you find it.

    But why didn't it just open an Explorer window that viewed the desktop?

    Because in Windows 95, you couldn't display the desktop in an Explorer window. The only way to see the desktop was to minimize all your application windows. There wasn't a "Show Desktop" button in Windows 95 either. Therefore, the shortcut property sheet did as much as it could: It highlighted the item on the desktop, but it couldn't open Explorer or show the desktop. Instead, it just told you "Hey, it's on your desktop," with an implied, "I took you as far as I could, sorry."

    Fortunately, the inability to show the desktop in an Explorer window was removed in later versions of Windows, and the strange dialog box disappeared as well.

  • The Old New Thing

    The publicity machine doesn't stop: TechNet podcast interview

    • 14 Comments

    The TechNet Magazine Podcast page has just posted their February 2007 entry, which includes an interview with little old me in the second half. I haven't listened to the whole interview yet, but what struck me immediately is that I was pretty darned punchy and goofy, whereas I think the host was trying to take a more serious tone. Oops.

  • The Old New Thing

    Super Bowl Sunday: The day the entire country stops doing anything

    • 23 Comments

    This upcoming Sunday features an event that means absolutely nothing to people outside the United States: The Super Bowl. I call it an event because it is more than simply a football game. It's an American institution. Even people who think a nose guard is a piece of safety equipment will watch the game, or at least pretend to be interested in it for a few hours.

    At a party last year, I met someone who spent time as an emergency room doctor, and he told me that the entire hospital goes quiet when the Super Bowl is on. Patients don't come in. Inpatients don't call for nurses. Those who are already in the waiting room are transfixed by the television set. It's like a national hypnosis has taken over.

    A few months ago, I met someone who works in a hospital as a mental health specialist and asked her whether the Super Bowl had the same sedative effect on her patients. "Nope. These people are oblivious to the Super Bowl."

    Perhaps they were French.

    (Note: I won't be able to use this joke for much longer.)

  • The Old New Thing

    The ironic thing about fixing a bug

    • 42 Comments

    The ironic thing about fixing a bug, or at least once I mention on this web site that I fixed a particular bug, is that people immediately complain that I didn't fix some other bug. One school of complaint believes that cosmetic bugs should be fixed first: "You suck. I mean, look at these egregious cosmetic bugs. If you can't get even those right, then obviously you can't get the other stuff right either." The opposite school believes that cosmetic bugs should be fixed last: "You suck. I mean, why are you fixing cosmetic bugs when there are these other bugs!"

    But at least both camps agree on one thing: I suck.

    I think I'd be better off if I said I didn't fix any bugs at all.

  • The Old New Thing

    The network interoperability compatibility problem, second follow-up

    • 60 Comments

    I post this entry with great reluctance, because I can feel the heat from the pilot lights of the flame throwers all the way from here.

    The struggle with the network interoperability problem continued for several months after I brought up the topic. In that time, a significant number of network attached storage devices were found that did not implement "fast mode" queries correctly. (Buried in this query are some of them; there are others.) Some of them were Samba-based whose vendors did not have an upgrade available that fixed the bug. But many of them used custom implementations of CIFS; consequently, any Samba-specific solutions would not have helped those devices. (Most of the auto-detection suggestions people proposed addressed only the Samba scenario. Those non-Samba devices would still not have worked.) Even worse, most of the devices are low-cost solutions which aren't firmware-upgradable or have any vendor support.

    Some of the reports came from people running fully-patched well-known Linux distributions. So much for being in all the new commercially supported offerings over the next couple months.

    Furthermore, those buggy non-Samba implementations mishandled fast mode queries in different ways. For example, one of them I was asked to look at didn't return any error codes at all. It just returned garbage data (most noticeably, corrupting the file name by deleting the first five characters). How do you detect that this has happened? If the server reports "I have a file called e.txt", is Windows supposed to say, "Oh, I don't think so. I bet you're one of those buggy servers that chops off the first five letters of file names and that you really meant to say (scrunches forehead in concentration) readme.txt"? What if you really had a file called e.txt? What if the server said, "This directory has two files, 1.txt and 2.txt"? Is this a buggy server? Maybe the files are really abcde1.txt and defgh2.txt, or maybe the server wasn't lying and the files really are 1.txt and 2.txt.

    One device simply crashed if asked to perform a fast mode query. Another wedged up and had to be reset. "Oh, looks like somebody brought their Vista laptop from home and plugged it into the corporate network. Our document server crashed again."

    Given the much broader ways that servers mishandled fast queries, any attempt at auto-detecting them will necessarily be incomplete and fail to detect broken servers. This is fundamentally the case for servers which return perfectly formed, but incorrect, data. And even if the detection were perfect, if it left the server in a crashed or hung state, that wouldn't be much consolation.

    Given this new information, the solution that was settled on was simply to stop using "fast mode" queries for anything other than local devices. The most popular file system drivers for local devices (NTFS, FAT, CDFS, UDF) are all under Microsoft's control and they have already been tested with fast mode queries.

    Such is the sad but all-too-true cost of interoperability and compatibility.

    (To address other minor points: It's not the case that the Vista developers "knew the [fast mode query] would break Samba-based devices since late 2005". The fast mode query was added, and the incompatibility with Samba wasn't discovered until March 2006. "Why didn't you notify the Samba team?" Because by the time we found the problem, they had already fixed it.)

Page 4 of 4 (39 items) 1234