• The Old New Thing

    WM_KILLFOCUS is the wrong time to do field validation


    "I'll do my field validation when I get a WM_KILLFOCUS message."

    This is wrong for multiple reasons.

    First, you may not get your focus loss message until it's too late.

    Consider a dialog box with an edit control and an OK button. The edit control validates its contents on receipt of the WM_KILLFOCUS message. Suppose the user fills in some invalid data.

    Under favorable circumstances, the user clicks the OK button. Clicking the OK button causes focus to move away from the edit control, so the edit control's WM_KILLFOCUS runs and gets a chance to tell the user that the field is no good. Since button clicks do not fire until the mouse is released while still over the button, invalid data will pop up a message box, which steals focus, and now the mouse-button-release doesn't go to the button control. Result: Error message and IDOK action does not execute.

    Now let's consider less favorable circumstances. Instead of clicking on the OK button, the user just presses Enter or types the keyboard accelerator for whatever button dismisses the dialog. The accelerator is converted by IsDialogMessage into a WM_COMMAND with the button control ID. Focus does not change.

    So now the IDOK (or whatever) handler runs and calls EndDialog() or performs whatever action the button represents. If the dialog exits, then focus will leave the edit control as part of dialog box destruction, and only then will the validation occur, but it's too late now. The dialog is already exiting.

    Alternatively, if the action in response to the button is not dialog termination but rather starting some other procedure, then it will do it based on the unvalidated data in the dialog box, which is likely not what you want. Only when that procedure moves focus (say, by displaying a progress dialog) will the edit control receive a WM_KILLFOCUS, at which time it is too late to do anything. The procedure (using the unvalidated data) is already under way.

    There is also a usability problem with validating on focus loss. Suppose the user starts typing data into the edit control, and then the user gets distracted. Maybe they need to open a piece of email that has the information they need. Maybe they got a phone call and need to look up something in their Contacts database. Maybe they went to the bathroom and the screen saver just kicked in. The user does not want a "Sorry, that partial information you entered is invalid" error dialog, because they aren't yet finished entering the data.

    I've told you all the places you shouldn't do validation but haven't said where you should.

    Do the validation when the users indicate that they are done with data entry and want to go on to the next step. For a simple dialog, this would mean performing validation when the OK or other action verb button is clicked. For a wizard, it would be when the Next button is clicked. For a tabbed dialog, it would be when the user tabs to a new page.

    (Warnings that do not change focus are permitted, like the balloon tip that apperas if you accidentally turn on Caps Lock while typing your password.)

  • The Old New Thing

    A $2 billion bridge to one person


    The New York Times reported on two enormous construction projects of dubious merit:

    [The first bridge] would connect [Ketchikan, population 7845] to an island that has about 50 residents and the area's airport, which offers six flights a day (a few more in summer). It could cost about $200 million.

    The other bridge would span an inlet for nearly two miles to tie Anchorage to a port that has a single regular tenant and almost no homes or businesses. It would cost up to $2 billion.

    The first bridge replaces a five minute ferry ride with a drive that most likely will take even longer.

    And the representative from Alaska behind these pointless construction projects is hardly ashamed of this. Quite the contrary: He's proud of his achievement.

    "I stuffed it like a turkey."

    United States politics is not about trying to make the world a better place. It's about doing whatever it takes to get re-elected.

  • The Old New Thing

    Mapping all those "strange" digits to "0" through "9"

    In an earlier article, I discussed how the Char.IsDigit() method and its Win32 counterpart, GetStringTypeEx report things to be digits that aren't just "0" through "9".

    If you really care just about "0" through "9", then you can test for them explicitly. For example, as a regular expression, use [0-9] instead of \d. Alternatively, for a regular expression, you can enable ECMA mode via RegexOptions.ECMAScript. Note that this controls much more than just the interpretation of the \d character class, so make sure to read carefully to ensure that you really want all the ECMA behavior.

    It has been pointed out to me that there is a way to convert all those "strange" digits to the "0" through "9" range, namely by calling the FoldString function with the MAP_FOLDDIGITS flag.

    (I put the word "strange" in quotation marks because of course they aren't strange at all. Just different.)

    This converts digits but doesn't help with decimal points, so you still have to deal with correctly interpreting "1,500" as either "one thousand five hundred" (as it would be in the United States) or "one and a half" (as it would be in most of Europe). For that, you need to call GetLocaleInfo to get the LOCAL_SDECIMAL and LOCAL_STHOUSAND strings.

  • The Old New Thing

    Sorry, no free ice cream in Tennessee; it's illegal

    It seems that giving away ice cream has been illegal in Tennessee since 1957, when state legislators were trying to combat alleged unfair trade practices by the dairy industry.

    Upon its being alerted to the existence of this law, the state Senate and House unanimously passed a bill to repeal the law, sending it to the governor for signature.

    Aha, but it's not as simple as you think.

    The bill as written would have eliminated an entire section of state law covering unfair trade practices and frozen desserts.

    The bill was withdrawn after some lawmakers got calls from dairy company officials who feared the bill was too broad.

    It is unclear whether an amended bill will pass in time for Baskin-Robbins' free cone day, planned for April 28.

    (Links courtesy of Fark. It's not news. It's Fark.)

  • The Old New Thing

    Why can't I install Windows on my USB drive?


    A collection of limitations (both hardware and software) currently prevent Windows from booting and running off a USB drive. Some of them are described in this whitepaper from WinHEC 2003. Another reason not mentioned in this paper is that during any hot-plug operation, the USB bus is completely reinitialized. Windows really doesn't like it when it loses access to its boot device. Imagine, you plug in a USB camera, the USB bus reinitializes, Windows loses access to the boot drive, and *oops* the kernel needs to page in some data and it can't.


    But who knows, someday maybe it will work.

  • The Old New Thing

    Astonishingly, rules apply to everyone.


    Spain's Crown Prince and his fiancée are outraged that they had to go through airport security in Miami.

    "The prince and his bodyguard felt they should not be subjected to the screening, but if they do not have an escort from the State Department or the Secret Service, it is required," she added. "It is the law."

    Apparently, the Prince did not give the standard 72 hours' notice to obtain pre-clearance. (Hm, I wonder if I can get pre-clearance by submitting my itinerary 72 hours in advance.)

    What bugs me even more is that the officials in Miami are all apologetic!

    Miami-Dade County Mayor Alex Penelas sent the royal family a letter of apology on the same day, calling the situation "lamentable".

    Reminds me of an article in the New York Times Magazine a few years ago titled Life is a Contact Sport [fee required], describing a mandatory meeting for all NFL rookies to introduce them to the "real world". My favorite part was this:

    Kendrell Bell, a Pittsburgh Steelers linebacker, tells of his great awakening to the verities of income tax: "I got a million-dollar signing bonus. But then I got the check, and it was only $624,000. I thought, Oh, well, I'll get the other half later. Then I found out that's all there was. I thought, They can't do this to me. Then I got on the Internet and I found out they can."

    Shocking! Football players have to pay income tax! Where will the injustice end?

    Happy Tax Day (US).

  • The Old New Thing

    Not all short filenames contain a tilde


    I'm sure everybody has seen the autogenerated short names for long file names. For the long name "Long name for file.txt", you might get "LONGNA~1.TXT" or possibly "LO18C9~1.TXT" if there are a lot of collisions.

    What you may not know is that sometimes there is no tilde at all!

    Each filesystem decides how it wants to implement short filenames. Windows 95 uses the "~n" method exclusively. Windows NT adds the hexadecimal hash overflow technique. But some filesystems (like Novell) just truncate the name. "Long name for file.txt" on a Novell server will come out to just "LONGNAME.TXT".

    So don't assume that all short names contain tildes. They don't. This means no cheating on skipping a call to GetLongFileName if you don't see any tildes, since your optimization is invalid on Novell networks.

  • The Old New Thing

    Playing on an entirely different level


    Competitive Scrabble® is another game entirely. For example, here's a game from the 2001 World Championship. You can follow it move-by-move, or you can read the game commentary.

    The name "Stefan" you see in the commentary is Wall Street Journal reporter Stefan Fatsis, author of Word Freak: Heartbreak, Triumph, Genius and Obsession in the World of Competitive Scrabble Players, a book that is on my list of "books I really want to read".

  • The Old New Thing

    First thing we do is kill all the jerks


    There a fascinating article in today's New York Times on a troop of baboons which went pacifist:

    ... researchers describe the drastic temperamental and tonal shift that occurred in a troop of 62 baboons when its most belligerent members vanished from the scene. The victims were all dominant adult males that had been strong and snarly enough to fight with a neighboring baboon troop over the spoils at a tourist lodge garbage dump, and were exposed there to meat tainted with bovine tuberculosis, which soon killed them. Left behind... were the 50 percent of males that had been too subordinate to try dump brawling, as well as all the females and their young. With that change in demographics came a cultural swing toward pacifism, a relaxing of the usually parlous baboon hierarchy, and a willingness to use affection and mutual grooming rather than threats, swipes and bites to foster a patriotic spirit.

    It has been twenty years since this cataclysmic event and the amicable atmosphere persists even though none of the original male survivors is still around.

    "We don't yet understand the mechanism of transmittal... but the jerky new guys are obviously learning, ‘We don't do things like that around here.’"

    Of course, baboons will be baboons.

    The new-fashioned Forest Troop is no United Nations, or even the average frat house. Its citizens remain highly aggressive and argumentative, and the males still obsess over hierarchy. "We're talking about baboons here," said Dr. Sapolsky.

    Sounds a lot like the real United Nations to me.

  • The Old New Thing

    Unicode collation is hard


    The principle of "garbage in, garbage out" applies to Unicode collation. If you hand it a meaningless string and ask to compare it to another meaningless string, you get meaningless results.

    I am not a Unicode expert; I just play one on the web. A real Unicode expert is Michael Kaplan, whose explanation of how comparing invalid Unicode strings result in nonsensical results I strongly recommend to those who attempt to generate random test strings in Unicode.

Page 420 of 453 (4,523 items) «418419420421422»