• The Old New Thing

    I'll see (some of) you in Los Angeles in September

    • 49 Comments

    Jeremy Mazner has asked me to put together a 400-level session at this year's PDC. I came up with the title "Five(ish) things every Win32 developer should know (but likely doesn't)". Of course, now I have to think of five things! Here are some ideas I've been kicking around.

    • The memory scene: Physical address space != physical memory != virtual memory != virtual address space
    • Consequences of the way CPUs work: How my O(n) algorithm can run circles around your O(log n) algorithm; why much of what you learned in school simply doesn't matter
    • Parent vs. owner windows
    • Asynchronous input queues, the hazards of attaching thread input, and how it happens without your knowledge
    • Dialog units, DPI and the overloaded term "large fonts"

    Would you go to a talk that covered these topics? If not, what topics would you rather hear me talk about?

    Follow-up: The talk will be a little over an hour. (And fixed the title. Thanks, Dave.)

  • The Old New Thing

    Why does the Run dialog autocorrect but not the Run key?

    • 3 Comments

    In an earlier comment, Aswin Gunawan asked why the Run dialog does autocorrection but not the Run key?

    One is a programmatic interface and the other is an end-user control.

    End users are not expected to be understand how computers do things. They want, and even expect, the computer to help them out with what they're typing. This means spell-checking, guessing missing information, and generally "doing what I mean". For example, web browsers don't require you to type "http://" or "ftp://" in front of web addresses any more; they guess whether you're trying to connect to an FTP site or an HTTP site based on context. Of course, sometimes the computer guesses wrong—maybe you really wanted to use HTTP to connect to a site whose name begins with "ftp."—in which case you can re-enter the command and provide more information so the computer won't have to guess as much.

    Programming interfaces, on the other hand, are for people who do understand how computers do things. If a program makes an invalid request to a function, the expectation is that the function will return an error and not try to "guess" what the programmer "really meant to do". Because a computer program can't look at the "autocorrected" result and say, "No, that's not quite what I meant," and retry the operation with "a few more hints". (Heck, if the program had "some more hints", why not just pass the "fully hinted" version in the first place? Save you the trouble of calling the function twice.)

    Computer programs prefer predictability. Autocorrection and context-driven guessing are unpredictable. Imagine how much harder it would be to write code if a stretch of code changed it behavior based on fuzzy logic like "Well, there was a file in the directory that had a similar name, so I used that one instead", or "This class doesn't have a field called 'current', but the one over there does, so I'll guess that you meant that one."

    I'm sure some people will point out that the CreateProcess function breaks this rule of "don't guess; just fail". We'll discuss this next time.

  • The Old New Thing

    Google is the cute two-year-old girl with curly blond hair that gets all the attention

    • 85 Comments

    Let's see, Google Maps adds the world outside the United States, Canada and the UK, and people go ga-ga. Nevermind that Google's new "maps" have nothing beyond country boundaries. "Aww, look at Google, she's so cute and adorable!"

    I'm sure the people at the existing online map services like MapQuest and MSN MapPoint are sitting there like older siblings, wondering when exactly they turned into chopped liver. MSN MapPoint has actual maps of most of Europe, and MapQuest's library of maps is larger still. (Kathmandu anyone?) Both sites provide documentation on how to link directly to them. Yet they don't get drooled over.

    Somebody at MapQuest should take out a full page ad that goes something like this:

    Dear Google Maps,

    Welcome to the rest of the world! If you ever need driving directions, don't hesitate to ask.

    Love ever,
    MapQuest

  • The Old New Thing

    The Date/Time control panel is not a calendar

    • 85 Comments

    Although many people use the Date/Time control panel to flip through a calendar, that's not what it is for. In fact, if you use it that way, you can create all sorts of havoc!

    In its original incarnation in Windows 95, the Date/Time control panel changed your date and time. If you clicked through the calendar to see next month, you actually changed your system clock to next month. If you changed your mind and clicked "Cancel", the Date/Time control panel undid its changes and restored the date to the original date.

    In other words, here's what happened, step by step:

    • On April 1, you open the Date/Time control panel.
    • You change the month to May. The Date/Time control panel changes your system date to May 1. If you are running an appointment calendar program, all appointments from the month of April will fire. (For example, your April 15th alarm to remind you to file your income taxes.) You are annoyed by all these alerts and you cancel them.
    • You decide you didn't want to change the month to May after all and click Cancel.
    • The Date/Time control panel changes the date back to April 1.
    • On April 15th, your income tax alarm fails to fire because you cancelled it, remember?

    In other words, the Date/Time control panel was not designed for letting you flip through a calendar. It was designed for changing the system date and time.

    Unaware of its design, people have been using the Date/Time control panel as if it were a calendar, not realizing that it was doing all sorts of scary things behind the scenes. It's like using a cash register as an adding machine. Sure, it does a great job of adding numbers together, but you're also messing up the accounting back at the main office!

    For Windows 2000, in reluctant recognition of the way people had been mis-using the Date/Time control panel, it was rewritten so that it doesn't change the system time until you hit the Apply button.

    Aaron Margosis shows you how to grant a user permission to change the system date and time without having to make them a full administrator.

  • The Old New Thing

    Perhaps this is what airport security is worried about

    • 12 Comments

    As if there aren't enough things in the world to worry about. Now you have to watch out for exploding knitting needles.

  • The Old New Thing

    What's the difference between autocomplete and dropdown history?

    • 5 Comments

    One shows things that might be, the other shows things that were. Both of them try to help you type something, but they operate differently (and look confusingly similar).

    Let's take the second case first. Dropdown history, like you see in the Run dialog, common file dialogs, and the Internet Explorer address bar. The cue for dropdown history is a button with a downward-pointing arrow on it. When you click it, a list box with a scrollbar appears. Dropdown history shows you what you already typed into the dialog previously, and its contents are independent of what you've typed so far.

    Autocomplete tries to guess what you're typing based on an existing database, typically files on your hard drive or web pages you've visited. The autocomplete dropdown is a popup window that filters itself as you type.

    Since dropdown history remembers what you actually typed, the Run dialog history can remember command line arguments. On the other hand, autocomplete is based on what's on the system and what web sites you've visited, so it can suggest things you've never typed. Type "C:\" and an autocomplete window appears with everything in the root of your C drive. On the other hand, autocomplete can't remember command line arguments since that's not what it's drawing from.

  • The Old New Thing

    Is there ever such a thing as a good letter from the IRS?

    • 22 Comments

    I arrived home yesterday to find a letter from the IRS in my mailbox. Dare I open it?

    The only other interaction with the IRS I'd had previously was several years ago where they told me I had overpaid my taxes and sent me a refund check of a few hundred dollars. I went back and reviewed my return and concluded that my original return was correct and they were wrong to send me the refund check. I called the friendly IRS office and explained how I came to the numbers I did. The agent went through the same computations and agreed with me, and instructed me how to return the check with an explanatory letter. It's not worth committing tax fraud over just a few hundred dollars.

    With some trepidation, I opened the letter.

    This time, the IRS believed that in 2003, I failed to report income in the amount of over ten times my actual salary. What happened?

    There were a few errors that they picked up, on the order of a few thousand dollars, although enough of them were errors in my favor that I think I came out ahead on that part. (For example, I forgot to report my sales of WorldCom and Nortel stock. Like many other peop^H^H^H^Hsuckers, I took a bath on both, and those losses easily covered gains elsewhere.)

    But a few thousand dollars is nowhere near the tenfold alleged underreporting. Where did that come from?

    I sold a lot of stock that year as part of a larger "realignment" of my personal finances, and due to the weirdness of United States tax law, the way I sold some of the shares required the income to be reported in a special way. And that's how I reported it. The IRS happily accepted that income but simultaneously claimed that I failed to report it! Not only do they want to double-count the income/loss from those stock sales, but since they don't have cost basis information, they assumed that the sales were pure profit.

    Now I get to spend the weekend taking a few deep breaths, doing a lot of photocopying of supporting documents, and writing a friendly letter back to the IRS, explaining why I believe they over-over-overcounted my income. I hope they accept it.

  • The Old New Thing

    Why do NTFS and Explorer disagree on filename sorting?

    • 11 Comments

    Some people have noticed that NTFS automatically sorts filenames, but does so in a manner different from Explorer. Why is that?

    For illustration purposes, I created files with the following names:

    Name Code point Description
    aU+0061Latin small letter A
    bU+0062Latin small letter B
    ×U+00D7Multiplication sign
    åU+00E5Latin small letter A with ring above
    øU+00F8Latin small letter O with stroke

    And here's the sort order for various scenarios, at least on my machine. (You'll later see why it's important whose machine you test on.)

    Plain "dir" command
    aU+0061Latin small letter A
    bU+0062Latin small letter B
    åU+00E5Latin small letter A with ring above
    ×U+00D7Multiplication sign
    øU+00F8Latin small letter O with stroke
     
    "dir /on"
    ×U+00D7Multiplication sign
    aU+0061Latin small letter A
    åU+00E5Latin small letter A with ring above
    bU+0062Latin small letter B
    øU+00F8Latin small letter O with stroke
     
    Explorer sorted by name
    ×U+00D7Multiplication sign
    aU+0061Latin small letter A
    åU+00E5Latin small letter A with ring above
    bU+0062Latin small letter B
    øU+00F8Latin small letter O with stroke

    First, notice that Explorer and "dir /on" agree on the alphabetic sort order. (Once you throw digits into the mix, things diverge.) This is not a coincidence. Both are using the default locale's word sort algorithm.

    Why does the raw NTFS sort order differ?

    Because NTFS's raw sort order has different goals.

    The "dir /on" and Explorer output are sorting the items for humans. When sorting for humans, you need to respect their locale. If my computer were in Sweden, Explorer and "dir /on" would have sorted the items in a different order:

    ×U+00D7Multiplication sign
    aU+0061Latin small letter A
    bU+0062Latin small letter B
    åU+00E5Latin small letter A with ring above
    øU+00F8Latin small letter O with stroke

    You can ask a Swede why this is the correct sort order if you're that curious. My point is that different locales have different sorting rules.

    NTFS's raw sort order, on the other hand, is not for humans. As we saw above, sorting for humans can result in different results depending on which human you ask. But there is only one order for files on the disk, and NTFS needs to apply a consistent rule so that it can find a file when asked for it later.

    In order to maintain this consistency, the NTFS raw sort order cannot be dependent upon such fickle properties as the current user's locale. It needs to lock in a sort algorithm and stick to it. As Michael Kaplan pointed out earlier, NTFS captures the case mapping table at the time the drive is formatted and continues to use that table, even if the OS's case mapping tables change subsequently. Once the string has been converted to uppercase, it then needs to be sorted. Since this is not for humans, there's no need to implement the complex rules regarding secondary and tertiary keys, the interaction between alphanumerics and punctuation, and all the other things that make sorting hard. It just compares the code points as binary values, also known as an ordinal sort.

    In summary, therefore, Explorer sorts the items so you (a human) can find them. NTFS sorts the items so it (the computer) can find them. If you're writing a program and you want the results of a directory listing to be sorted, then sort it yourself according to the criteria of your choice.

  • The Old New Thing

    What is the difference between "Unpin from Start menu" and "Remove from this list"?

    • 34 Comments

    The list of programs on the left hand side of the Start menu is really two lists. (You can see the separator line between them.) The top list is the so-called "pin list". This is the list of programs you picked to be "locked" to the top of the Start menu. You can "pin" a program by right-clicking it and selecting "Pin to Start menu", or you can just drag it directly into the pin area.

    The bottom list on the left hand side of the Start menu is the "most frequently used" section of the Start menu, which selects the programs you have used the most in the past month or so.

    If you right-click an item that happens to be in the Start menu's pin list (either by right-clicking it from the pin list itself, or by right-clicking the original), one of the options is "Unpin from Start menu". If you select this option, then the item is removed from the Pin list.

    If you right-click an item on the "most frequently used" section of the Start menu, one of the options is "Remove from this list". If you select this option, then the item is removed from the "most frequently used" section of the Start menu. As far as the Start menu is concerned, you never ran that program. Of course, as you start running the program subsequently, it works its way up the popularity chain and might break into your "most frequently used" list based on your usage after you removed it originally.

    The difference, then, between the two, is that each removes the item you clicked from a different list. One removes it from the pin list, and the other removes it from the "most frequently used programs" list. There is a line separating the two lists, but most people don't realize that the line is there for a reason. It's not just a pretty face.

    To make things less (or perhaps more) confusing, if you select "Remove from this list" for an item from the pin list, it also removes it from the pin list as well as removing it from the "most frequently used programs" list.

  • The Old New Thing

    Displaying the dictionary, part 3: Using an owner-data listview

    • 26 Comments

    Owner-data listviews let you take over data management from the listview. This is useful in our case since we have over twenty thousand dictionary entries, and creating even that many blank listview items takes an unacceptably long amount of time.

    Let's convert our listview to an owner-data listview. Believe it or not, this is quite easy to do once we have the text callback technique from last time. Make the following changes:

    LRESULT RootWindow::OnCreate()
    {
      m_hwndLV = CreateWindow(WC_LISTVIEW, NULL,
                      WS_VISIBLE | WS_CHILD | WS_TABSTOP |
                      LVS_NOSORTHEADER | LVS_OWNERDATA |
                      LVS_SINGLESEL | LVS_REPORT,
                      0, 0, 0, 0,
                      m_hwnd,
                      (HMENU)IDC_LIST,
                      g_hinst,
                      NULL);
     ...
     // for (int i = 0; i < Length(); i++) {
     //  const DictionaryEntry& de = Item(i);
     //  LVITEM item;
     //  item.mask = LVIF_TEXT;
     //  item.iItem = i;
     //  item.iSubItem = COL_TRAD;
     //  item.pszText = const_cast<LPWSTR>(de.m_pszTrad);
     //  item.iItem = ListView_InsertItem(m_hwndLV, &item);
     //  if (item.iItem >= 0) {
     //   item.iSubItem = COL_PINYIN;
     //   item.pszText = const_cast<LPWSTR>(de.m_pszPinyin);
     //   ListView_SetItem(m_hwndLV, &item);
     //   item.iSubItem = COL_ENGLISH;
     //   item.pszText = const_cast<LPWSTR>(de.m_pszEnglish);
     //   ListView_SetItem(m_hwndLV, &item);
     //  }
     // }
     return 0;
    }
    

    That's right, we made things better by deleting code. Isn't that satisfying?

    Owner-data is like the text callback mechanism in the extreme: The listview doesn't record any information about the contents of your items. Whenever it needs something, it always asks. To create twenty thousand items, we just call ListView_SetItemCount and tell it that there are twenty thousand items. (There is also a ListView_SetItemCountEx macro which lets you pass flags, none of which are relevant here.)

    In many owner-data cases, the data comes from an external source, in which case the LVN_ODCACHEHINT notification can be helpful. The listview sends this notification to say, "I'm going to be asking a lot of questions about items in this range. You might want to go work on them." Note that the listview might ask questions about items outside the range, too. The notification is just a hint that most of the questions are likely to be in that range. In our case, we have all the data ahead of time, so we have no need for the hint.

    Notice that with this change to an owner-data listview, the program starts up almost instantly. Remember also the way we arranged the data in our string pool: All the strings for an item are adjacent, and strings for consecutive items follow one another. This means that all the data for one screenful of information resides in contiguous memory. Result: Better locality, fewer page faults. We'll see more benefits of the string pool later.

    That's all for this month. Next month, we'll come back to filling in the second column of data: the simplified Chinese characters.

Page 354 of 432 (4,312 items) «352353354355356»