• The Old New Thing

    Why do Microsoft code samples tend to use ZeroMemory instead of { 0 }?


    If you go browsing around MSDN, you'll find that code samples tend to call ZeroMemory explicitly rather than using "= { 0 }" notation. Why is that?

    To make it clearer for people who are used to other programming languages.

    Like it or not, a significant percentage of people who write programs for Windows do it in languages other than C and C++. Although those developers may have a basic understanding of C and C++, they don't have all the language subtleties memorized.

    Compare the situation of speaking in English to a group of people where not everyone speaks the language fluently. If you're considerate of your audience, you're going to avoid the more esoteric grammatical constructions, the rare words, and the obscure idioms. Instead of saying, "Were it to rain, we will see that umbrellas be available," you would use the simpler "If it rains, then we will make sure that umbrellas are available," thereby avoiding the grammatical complexity of the implied conditional by inversion ("if"), the subjunctive of condition ("were"), the implied conclusion ("then"), and the subjunction of intention ("be").

    Heck, even people who claim to know C and C++ don't have all the language subtleties memorized. Some of them have false impressions of what " = { 0 }" does. And who among us really has C/C++'s bizarre operator precedence rules committed to memory?

    Consequently, MSDN samples tend to use ZeroMemory to make it blindingly obvious what is being set to zero. One of the things we've learned over the years is that many people just copy/paste sample code without understanding it. If there are little things like ZeroMemory that can be done to make the intent of sample code clearer and reduce translation errors, then that's a good thing.

    If you prefer " = { 0 }", then go ahead and use it, secure in the knowledge that thousands of programmers aren't going to read your code and try to translate it into Visual Basic because that's the only language they know. But MSDN doesn't have that luxury.

  • The Old New Thing

    Why are there broadcast-based mechanisms in Windows?


    Many Windows information mechanisms are based on message broadcasts, among them DDE, WM_FONTCHANGE, and changes in system settings. Why do these mechanisms use broadcasts, when we know that broadcasts can result in the system grinding to a halt due to windows that have stopped processing messages?

    Because in 16-bit Windows, you didn't have this problem.

    Recall that 16-bit Windows was co-operatively multi-tasking. When a program received control of the CPU, it could do anything it wanted, knowing that no other programs could run until it explicitly yielded control by calling a function such as GetMessage or PeekMessage. The downside of this, of course, was that a single hung program caused the entire system to hang, because it wasn't releasing the CPU.

    The upside, however, was that if your program was running, then you knew, a priori, that there were no hung programs in the system. How do you know that? Because if there were a hung program, it would be running and not you.

    If there's only one thing, and you have it, then you know that nobody else is hogging it.

    Therefore, broadcasting messages was completely safe in 16-bit Windows. You didn't have to worry about non-responsive programs because you had proof that there weren't any.

    Of course, when the switch to pre-emptive multi-tasking occurred, this assumption no longer applied, but by then it was too late. The broadcast-based model was already in use, and consequently had to be preserved for compatibility reasons. (It would be bad if, for example, Lotus 1-2-3 stopped working on Windows NT because DDE broadcasts were no longer supported. If the Windows NT team had tried that gambit, nobody would have upgraded and Windows NT wouldn't have survived to make a second version.)

    On the other hand, given the risks involved in DDE broadcasts, you probably would be better off designing your program to not use dynamic data exchange as a data communication mechanism, thereby avoiding the pitfall of message broadcasts. No point contributing to the problem.

  • The Old New Thing

    Why can't I get the pixels of a window that isn't visible on screen?


    If the window isn't visible on the screen, then the pixels simply don't exist.

    The Windows painting model follows the principle of "Don't save anything you can recalculate". Consider: You have a 640x480 display in 16-color mode. That's 150KB of video memory. Take four copies of Notepad and maximize each one. If each of those copies of Notepad required an offscreen cached bitmap, you would be using 450KB of memory just to retain those bits. If your computer has only 640KB, that doesn't leave much memory for anything else.

    Think about what programs need to display. In the vast majority of cases, the programs already need to keep track of the information needed to generate the display anyway, and usually in a more compact form. Notepad, for example, has an edit control which in turn holds the text being edited. Displayed or not, the edit control needs to keep track of the text. (It's not like Notepad would use OCR to read the pixels from the screen and convert them back to text when it needs them!) Any program that has a scroll bar needs to manage information that is not visible on screen. It's hardly a stretch to make it manage information that is visible.

    If you do want to get the pixels from a window that isn't visible on screen, you can try sending it the WM_PRINT message, though this requires that the window you're sending it to even bothers to support the WM_PRINT message. (Many don't.) If you are using Windows XP or later, you can use the PrintWindow function.

  • The Old New Thing

    Why does the CreateProcess function do autocorrection?


    Programs that weren't designed to handle long file names would make mistakes like taking the path to the executable and writing it into the registry, unaware that the path might contain a space that needs quoting. (Spaces—while technically legal—were extremely rare in SFN paths.) The CreateProcess function had to decide whether to "autocorrect" these invalid paths or to let those programs simply stop working.

    This is the battle between pragmatism and purity.

    Purity says, "Let them suffer for their mistake. We're not going to sully our beautiful architecture to accomodate such stupidity." Of course, such an attitude comes with a cost: People aren't going to use your "pure" system if it can't run the programs that they require.

    Put another way, it doesn't matter how great your 1.0 version is if you don't survive long enough to make a 2.0.

    Your choice is between "being pure and unpopular" or "being pragmatic and popular". Look at all the wonderful technologies that died for lack of popularity despite technical superiority. Sony Betamax. Mattel Intellivision. (And, in the United States: The metric system.)

    Electric cars are another example. As great as electric cars are, they never reached any significant market success. Only after conceding to popularity and "sullying" their "purity" by adding a gasoline hybrid engine did they finally gain acceptance.

    I see this happening over and over again. A product team that, hypothetically, makes automated diagramming software, says, "I can't believe we're losing to Z. Sure, Z's diagrams may be fast and snazzy, but ours gets <subtle detail> right, and when you go to <extreme case> their diagrams come out a little distorted, and they're faster only because they don't try to prevent X and Y from overlapping each other in <scenario Q>. We're doing all those things; that's why we're slower, but that's also why we're better. Those people over at Z just don't 'get it'."

    Guess what. People are voting with their wallets, and right now their wallets are saying that Z is better in spite of all those "horrible flaws". Whatever part of "it" they don't get, it's certainly not the "make lots of people so happy that they send you money" part.

  • The Old New Thing

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


    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?


    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


    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,

  • The Old New Thing

    The Date/Time control panel is not a calendar


    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


    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?


    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.

Page 386 of 464 (4,636 items) «384385386387388»