December, 2006

  • The Old New Thing

    Stop the madness: Subdirectories of My Documents


    As a follow-up to the difference between My Documents and Application Data, I'd like to rant about all the subdirectories of My Documents that programs create because they think they're so cool.

    • Visual Studio Projects
    • My eBooks
    • My Received Files
    • Remote Desktops
    • My Scans
    • My Data Sources
    • My Virtual Machines
    • My Archives

    I'm sure there are more.

    Everything in the My Documents folder the user should be able to point to and say, "I remember creating that file on such-and-such date when I did a 'Save' from Program Q." If it doesn't pass that test, then don't put it into My Documents. Use Application Data.

    And don't create subdirectories off of My Documents. If the user wants to organize their documents into subdirectories, that's their business. You just ask them where they want their documents and let it go at that.

    (Yes, I'm not a fan of My Music, My Videos, and My Pictures, either.)

    Omar Shahine points out that Apple has similar guidelines for the Macintosh. I wonder how well people follow them.

  • The Old New Thing

    Okay, I changed my mind, I wrote a book after all


    Back in 2003, I wrote that I'm doing this instead of writing a book. That was true then, but last year I decided to give this book thing another go, only to find that publishers generally aren't interested in this stuff any more.

    "Does the world really need another book on Win32? Nobody buys Win32 books any more, that dinosaur!"

    "A conversational style book? People want books with step-by-step how-to's and comprehensive treatments, not water cooler anecdotes!"

    "Just 200 pages? There isn't enough of an audience for a book that small!"

    Luckily, I found a sympathetic ear from the folks at Addison-Wesley Professional who were willing to take a chance on my unorthodox proposal. But I caved on the length, bringing it up to 500 pages. Actually, I came up with more like 700 pages of stuff, and they cut it back to 500, because 700 pages would take the book into the next price tier, and "There isn't enough of an audience for a book that big!"

    Eighteen months later, we have The Old New Thing: Practical Development Throughout the Evolution of Windows, following in what appears to be the current fad of giving your book a title of the form Catchy Phrase: Longer Explanation of What the Catchy Phrase Means.

    It's a selection of entries from this blog, loosely organized, and with new material sprinkled in. There are also new chapters that go in depth into parts of Win32 you use every day but may not fully understand (the dialog manager, window messages), plus a chapter dedicated to Taxes. (For some reason, the Table of Contents on the book web site is incomplete.)

    Oh, and those 200 pages that got cut? They'll be made available for download as "bonus chapters". (The bonus chapters aren't up yet, so don't all rush over there looking for them.)

    The nominal release date for the book is January 2007, which is roughly in agreement with the book web site which proclaims availability on December 29th. Just in time for Christmas your favorite geek, if your favorite geek can't read a calendar.

    Now I get to see how many people were lying when they said, "If you wrote a book based on this blog, I'd buy it."

    (Update: The bonus chapters are now available.)

    (Update: Now available in Japanese! ISBN 978-4756150004.)

    (Update: Now available in Chinese! ISBN 7111219194.)

  • The Old New Thing

    The wisdom of seventh graders: What to do with a time machine (part 1)


    All the students at a local school were asked to composed an in-class essay on the following topic: "Your science teacher has invented a time machine. You have been selected to take the first trip. Explain in a multi-paragraph letter to your teacher where you will go and why." (Students were given two hours, plus one additional hour upon request. In practice, many students were finished early and almost nobody requested the third hour.)

    (Aside: Sometimes I think my readers believe in time machines. For example, one of them wondered why OLE/COM uses HRESULTs instead of Win32 error codes. Um, when OLE was invented, Win32 didn't exist.)

    The students really enjoyed this topic. Too much so, however, for more than a few of them turned their essays into a narrative rather than sticking to the assignment. One student was so excited that the essay consisted of a single five-page paragraph. Well, technically it was two paragraphs, thereby meeting the letter (if not the spirit) of the "multi-paragraph" requirement. About halfway down page three was this sentence: "The essay continues in the next paragraph."

    Roughly two thirds of the students opted to go into the past; one third chose to go into the future. One student didn't travel in time at all (!), choosing instead to visit Europe in the present day "to see castles and ruins". Psst, you've got a time machine. Why not go and see the ruins before they are ruined? (Actually, some friends pointed out to me that travelling to the present day is still handy. You can use your time machine as a teleporter. And you can even set the time machine to zip you backward, say, eight hours. That way, when you travel from Seattle to Europe, you arrive without any jet lag!)

    Boys were more likely to want to travel back in time to get rich, although their plans for doing so were not necessarily fully thought-out.

    • Go back in time, steal an invention, and then bring it back to the present.
    • Go back in time thirty years and invest all your money in Google, Amazon, and Microsoft.
    • Go back to the time of Jesus and sell a bag of candy to the king in exchange for gold and gemstones.
    • Go to the 1970's buy up land in California, and then return to the present and you'll be filthy rich.
    • Go back in time, bury some everyday objects, then return to the present and dig them up. Bingo, instant antiques! (This one had a chance of working.)

    (Good luck getting anybody in the past to accept today's money.)

    Girls were more likely to travel in time to meet themselves or close ancestors.

    • Go back in time to meet your grandparents who died when you were very young.
    • Go forward in time to see how you did. (These people were very susceptible to lapsing into speculative fiction.)

    A few students confused a time machine with regressive therapy, choosing to go back in time to re-live a cherished moment from a year or two ago. Psst, if you use a time machine to go into the past to visit yourself on that awesome vacation to Hawaii, you won't re-live the vacation. You'll be watching the other copy of yourself enjoy the vacation. (And that's assuming that the other copy of yourself doesn't see you and freak out.)

    Several students wanted to change world history.

    • Go back to Los Alamos and convince the scientists not to detonate the first atomic bomb.
    • Go back to New York City on September 11, 2001.
      • One student has a clever plan: Run into the World Trade Center buildings and pull the fire alarms eleven minutes before the planes collided with the buildings. By the student's calculations, that's enough time to get everybody out of the building but not so much time that the firemen will have arrived.
      • Another student wanted to prevent the planes from crashing into the Empire State Building. (I think he succeeded!)
    • Go back to Phuket in December, 2004 and warn everybody about the coming tsunami. (The student acknowledges that he will likely fail but he wants to try anyway.)

    Many students wanted to go back in time to observe and experience a historical period. One student wanted to ask Jesus to teach him how to walk on water. (Step one: Be the son of God.)

    Coming up in Part 2, selected sentences from student essays.

    Where would you go if you could take one trip in a time machine?

  • The Old New Thing

    I bet somebody is looking to get a really nice bonus for that feature: Attention


    "I bet somebody is looking to get a really nice bonus for that feature."

    A customer was having trouble with one of their features that scans for resources that their program can use, and, well, the details aren't important. What's important is that their feature ran in the Startup group, and as soon as it found a suitable resource, it displayed a balloon tip: "Resource XYZ has been found. Click here to add it to your resource portfolio."

    We interrupted them right there.

    — Why are you doing this?

    "Oh, it's a great feature. That way, when users run our program, they don't have to go looking for the resources they want to operate with. We already found the resources for them."

    — But why are you doing it even when your program isn't running? The user is busy editing a document or working on a spreadsheet or playing a game. The message you're displaying is out of context: You're telling users about a program they aren't even using.

    "Yeah, but this feature is really important to us. It's crucial in order to remain competitive in our market."

    — The message is not urgent. It's a disruption. Why don't you wait until they launch your program to tell them about the resources you found? That way, the information appears in context: They're using your program, and the program tells them about these new resources.

    "We can't do that! That would be annoying!"

  • The Old New Thing

    If you let people read a file, then they can copy it


    Here's a question that floated past my view:

    How do I set the ACLs on a file so users can read it but can't copy it? I can't find a "Copy" access mask that I can deny. If I can't deny copying, I'd at least like to audit it, so I can tell who made a copy of the file.

    There is no "Copy" access mask because copying is not a fundamental file operation. Copying a file is just reading it into memory and then writing it out. Once the bytes come off the disk, the file system has no control any more over what the user does with them.

  • The Old New Thing

    Nailing down what constitutes valuable consideration


    Last time, I introduced a friend I called "Bob" for the purposes of this story. At a party earlier this year, I learned second-hand what Bob had been up to more recently.

    The team Bob worked for immediately prior to his retirement gave him a call. "Hi, Bob. We're trying to ship version N+1 of Product X, and we really need your help. I know you're all retired and stuff, and you don't live in the area any more, but you're the only guy who can save us. Could you come out of retirement just for a few months?"

    Bob said, "Okay. This is a favor to you guys since I like you so much."

    When he sat down to sign the paperwork, he took the contract and crossed out the amount of money he would be paid and wrote in its place, "One dollar". Because he wasn't taking this job to get rich. He was doing it as a favor to his old team. He then signed it and returned the contract to the agency.

    The contracting agency was flabbergasted. "You can't do this for just one dollar! That's completely unheard of!" The real reason the agency was so upset is probably that their fee was a percentage of whatever Bob made, and if Bob made only one dollar, they would effectively be doing all the paperwork and getting paid a stick of chewing gum.

    Bob said, "Okay, then, if you want me to get paid 'for real', send me a contract with 'real money'."

    The agency sent him the original contract (before he changed it to "one dollar"), and Bob sent it back, indignant. "I said 'real money'. This amount is an insult."

  • The Old New Thing

    How do I find all files with at least one space in their name?


    You already know how to do this, you just don't realize it.

    How do you find files with an "x" in their name? That's right, you use dir *x*.

    Now you just have to change that x to a space. And since spaces are command line delimiters, you need to quote the sequence so it gets treated as a single parameter rather than two "*" parameters:

    dir "* *"

    Stick in a /s if you want to search recursively.

  • The Old New Thing

    Do not write in-process shell extensions in managed code


    Jesse Kaplan, one of the CLR program managers, explains why you shouldn't write in-process shell extensions in managed code. The short version is that doing so introduces a CLR version dependency which may conflict with the CLR version expected by the host process. Remember that shell extensions are injected into all processes that use the shell namespace, either explicitly by calling SHGetDesktopFolder or implicitly by calling a function like SHBrowseForFolder, ShellExecute, or even GetOpenFileName. Since only one version of the CLR can be loaded per process, it becomes a race to see who gets to load the CLR first and establish the version that the process runs, and everybody else who wanted some other version loses.

    Update 2013: Now that version 4 of the .NET Framework supports in-process side-by-side runtimes, is it now okay to write shell extensions in managed code? The answer is still no.

  • The Old New Thing

    Why do user interface actions tend to occur on the release, not on the press?


    If you pay close attention, you'll notice that most user interface actions tend to occur on the release, not on the press. When you click on a button, the action occurs when the mouse button is released. When you press the Windows key, the Start menu pops up when you release it. When you tap the Alt key, the menu becomes active when you release it. (There are exceptions to this general principle, of course, typing being the most notable one.) Why do most actions wait for the release?

    For one thing, waiting for the completion of a mouse action means that you create the opportunity for the user to cancel it. For example, if you click the mouse while it is over a button (a radio button, push button, or check box), then drag the mouse off the control, the click is cancelled.

    But a more important reason for waiting for the press is to ensure that the press won't get confused with the action itself. For example, suppose you are in mode where objects disappear when the user clicks on them. For example, it might be a customization dialog, with two columns, one showing available objects and another showing objects in use. Clicking on an available object moves it to the list of in-use objects and vice versa. Now, suppose you acted on the click rather than the release. When the mouse button goes down while the mouse is over on an item, you remove it from the list and add it to the opposite list. This moves the items the user clicked on, so that the item beneath the mouse is now some other item that moved into the original item's position. And then the mouse button is released, and you get a WM_LBUTTONUP message for the new item. Now you have two problems: First, the item the user clicked on got a WM_LBUTTONDOWN and no corresponding WM_LBUTTONUP, and second, the new item got a WM_LBUTTONUP with no corresponding WM_LBUTTONDOWN.

    You can also get into a similar situation with the keyboard, though it takes more work. For example, if you display a dialog box while the Alt key is still pressed rather than waiting for the release, the Alt key may autorepeat and end up delivered to the dialog box. This prevents the dialog box from appearing since it's stuck in menu mode that was initiated by the Alt key, and it's is waiting for you to finish your menu operation before it will display itself.

    Now, this type of mismatch situation is not often a problem, but when it does cause a problem, it's typically a pretty nasty one. This is particularly true if you're using some sort of windowless framework that tries to associate mouse and keyboard events with the corresponding windowless objects. When the ups and downs get out of sync, things can get mighty confusing.

    (This entry was posted late because a windstorm knocked out power to the entire Seattle area. My house still doesn't have electricity.)

  • The Old New Thing

    The wisdom of seventh graders: What to do with a time machine (part 2)


    (Make sure you've read Part 1 for background information.)

    On the subject of where they would go in a time machine, many students wrote well-thought-out essays, beautifully composed.

    These sentences below did not come from those essays.

    I've categorized the snippets roughly by theme, though I had to guess at some of them since the sentences are taken out of context. (In a futile attempt to assist non-native speakers, I have glossed some of the trickier parts. I've also added editorial comments in italics.)


    • I would be honored to trie the time machine
    • I am highly regarded to be selected to engorge this experimental journey.
    • At the crack of noon, we will begin our mission.

    Personal History: These are essays from students who would travel to their own past.

    • In 5th grade you are at the top of the school, and you feel the power over come you.
    • Now, if we fall asleep in class we get in trouble. But in kindergarten if we didn't fall asleep we would get in trouble.
    • She would work in little orchids picking fruit for her family.
    • I have 4 things in my life. Soccer, family, God, and school. In that order.
    • If I could find a way to impel paranormal powers to ignite in ones body enableing them to do incredible feats, I would be ecstatic to the point of bliss. (This same student wanted Jesus to teach him how to walk on water. This student also wanted control over magnetism. I think he needs to lay off the X-Men comics for a while.)

    The Middle Ages: The students recently studied the Middle Ages, which helps to explain why so many of them chose to go there.

    • And at that time in history, everything was changing either for the good or the bad. (Whoa there, let's not say anything too controversial now.)
    • In Europe during the 1700's there were 5 sections in the social class: 1=Monarchs, 2=Lords & Nobles, 3=knights, 4=pheasants. (What happened to number five?)
    • I find Middle Aged Europe very stimulating.
    • France is near water so I will feel more at home.
    • We have recently disgust the Middle Ages.
    • King Arthur may have won some battles without the use of fiction.
    • In 1550 I would choose to go to Spain because nobody really lived in N. American then.
    • I would learn a lot gong to the Midieval times. I would even come back and write and essay about it!
    • I'd have benefit in watching a mock battle between two knights on horseback with lances. (I may be wrong, but I think the battles in the Middle Ages were for real.)
    • It was sick and grusm but really a thing to remember.
    • And I would go to Britan because Britan was populare back in 1616.

    United States(?) History

    • Also, to investigate how the family worked [in Pilgrim times], to see if they fought less because they had no appliances to fight over.
    • If I could go anywhere I would choose Boston, England.
    • I want to see what happened when Ben Franklin flew his kite in the rain. For this reason I would go to England.
    • Though War is Hell, I still would be anxious to see a real one. (Try watching the evening news.)
    • I wish the great depression, but it did. (Even after you fill in the missing words, it's still funny.)
    • Because California is a very interesting and mindblowing city.
    • In 1961 everything including life was simple.
    • Hopefully the president at their time isn't an idiot and stops the first power plant ever built.
    • I want to se the Great Babino Babe Bruth.
    • Besides the Stealer fans nobody like the Stealers.
    • It was like a family runnun at disneyland.

    I'll stop here before I runnun too much. We'll learn more about seventh graders and time machines in the next installment.

Page 1 of 4 (32 items) 1234