The Old New Thing
Practical development throughout the evolution of Windows.
Latest posts
Extracting GPS coordinates from a photo and plotting it on a map
Today's Little Program extracts GPS coordinates from a photo and plots it on a map. Remember, Little Programs do little to no error checking, because that's how they roll. We start with a simple function that takes a latitude and longitude and opens a Web page that highlights that coordinate. In a real program, you probably would do something more interesting with the coordinates, but I'm opening a Web page just to do something. The class is an incredibly lame wrapper around for RAII purposes. The function is where the real work happens. GPS latitude and longitude are encoded in the shell property sy...
How do I get the effect of CW_USEDEFAULT positioning on a window I've already created?
A customer wanted to know how to get the effect of positioning on a window that already exists. In particular, they wanted to be able to reposition a dialog box to get the cascade effect, but since you can't actually pass in a dialog template, the repositioning has to be done after the fact. (Presumably in the handler, which runs before the dialog is visible, so that there is no visible flicker.) The solution here is simple: Create a temporary invisible window with as its position and the same height and width as your dialog box. See where the window manager puts that temporary window and move your dialog...
How do I get the path to the default user's profile?
A customer wanted to know how to get the path to the default user's profile. On older versions of Windows, the default location of the default user's profile was . Then it moved to . Now it's in . And the location may have been customized, so in principle it could be anywhere. The function to get the default user profile's directory is is the deviously-named . But the reason I'm writing this article is not to call your attention to the function, but rather to something in the function documentation. The documentation for the function includes the strings and , so all somebody had to do was type either of ...
Why don't all of my documents show up when I arrange my Documents library by Name?
A customer reported that when they opened their Documents library on Windows 7, some files were missing if they selected Arrange by: Name or Arrange by: Author or in fact any arrangement other than Arrange by: Folder. What's going on? When you arrange the Documents library by anything other than Folder, the Documents library uses the content indexer to obtain results quickly, rather than kicking off a recursive disk search (ugh). (The Folder arrangement does not require a recursive search, so it can use the traditional / loop to get the results. A member of the search indexer team suggested that a common ...
Why is the Program Files directory called Program Files instead of just Programs?
Some people suggest that one thing Microsoft Research could do with that time machine they're working on is to go back in time and change the name of the Program Files directory to simply Programs. No, it really should be Program Files. Program Files are not the same as Programs. Programs are things like Calc, Notepad, Excel, Photoshop. They are things you run. Program Files are things like and . They are files that make programs run. If the directory were named Programs, then people who wanted to run a program would start digging into that directory and seeing a page full of weird DLL names and wonder "W...
My friend lived in a tiny house with an enormous garage
One evening, I had a series of three dreams. In each one, I visited an unusual home. In the first dream, I visited the home of a friend of mine. But instead of living in his condominium in the city, he lived in a house built into the side of a cliff. The house commanded a breathtaking view of the valley below, but the living quarters weren't very large. This was to his liking. "Moving in didn't take long." The top floor was a single room the size of a typical bedroom. The bottom floor was half that size. There was a six-inch-square mesh of wire covering the downstairs walls. "That lets the dog roam freely down...
How can I launch an unelevated process from my elevated process and vice versa?
Going from an unelevated process to an elevated process is easy. You can run a process with elevation by passing the verb to or . Going the other way is trickier. For one thing, it's really hard to munge your token to remove the elevation nature properly. And for another thing, even if you could do it, it's not the right thing to do, because the unelevated user may be different from the elevated user. Let me expand on that last bit. Take a user who is not an administrator. When that user tries to run a program with elevation, the system will display a prompt that says, "Hey, like, since you're not an ad...
Restoring symbols to a stack trace originally generated without symbols
Has this ever happened to you? Ugh. A stack trace taken without working symbols. (There's no way that is a deeply recursive 60KB function. Just by casual inspection, you know that the symbols are wrong.) To see how to fix this, you just have to understand what the debugger does when it has no symbols to work from: It uses the symbols from the exported function table. For every address it wants to resolve, it looks for the nearest exported function whose address is less than or equal to the target value. For example, suppose has the following exported symbols: Look at it this way: The debugger is gi...
Why is my FormatMessage call crashing trying to read my insertion parameter?
A customer was looking for assistance in debugging a crash in their product. The stack trace looked like this: The string being formatted is , and the insertion is a long (but valid) string. A unit test which passes a similarly long object name to does not crash. What is the problem? There are clues in the stack trace. The natural place to start is the function that calls to see what parameters are being passed in. And that's where you see something strange: (The clue in the stack trace was the word fallback in the function name, which suggests that if the formatting attempt fails, it'll try again som...