The Old New Thing
Practical development throughout the evolution of Windows.
Latest posts

A brief history of the GetEnvironmentStrings functions

The GetEnvironmentStrings function has a long and troubled history. The first bit of confusion is that the day it was introduced in Windows NT 3.1, it was exported funny. The UNICODE version was exported under the name GetEnvironmentStringsW, but the ANSI version was exported under the name GetEnvironmentStrings without the usual A suffix. A mistake we have been living with for over two decades. This is why the winbase.h header file contains these confusing lines: WINBASEAPI LPCH WINAPI GetEnvironmentStrings( VOID ); WINBASEAPI LPWCH WINAPI GetEnvironment...

How do I create a TaskDialog with a progress bar but no cancel button?

A developer from another group within Microsoft wanted to create a with a progress bar, but they couldn't figure out how to get rid of the Cancel button. "Is there a way to remove all the buttons from a Task Dialog?" Um, users hate it when you give them a window that cannot be closed or cancelled. What should the user do if the reticulation server stops responding? Shut down the computer? (Hey, at least shutting down the computer will actually work.) "The process usually takes around two seconds, and we time out after ten. In the case of timeout, we replace the progress dialog with a failure dialog w...

If there were some sort of award for alternative commuting, we would’ve been eligible

A few projects ago, I worked on a team whose members came to work by a wide variety of modes. If there were some sort of award for alternative commuting, we would've been eligible. One of the full-time telecommuters was based in Spain, which was handy because he was available to deal with issues that cropped up while everybody in Redmond was sleeping. Perhaps to compensate for all the gasoline being saved by his employees, our manager drove an oversized pick-up truck to work.

State law requires you to watch this video of a singing hippo

I did it briefly a few years ago, but I'm going to make it a regular Monday feature, at least for this year: Blogging my dreams. I dreamed that I was back in my high school English class, and due to some new state law, everybody was required to watch this video of a singing hippo. The hard part was walking four miles to the nearest viewing location, seeing as we didn't even have a TCP/IP standard yet, much less YouTube. To think that this is the culmination of the technological advances of the last three decades: Being able to watch a singing hippo on demand.

How can I write a script that finds my top-rated photos?

I'm not sure if I'll be able to keep it up, but I'm going to see if I can make Monday "Little Programs" day, where I solve simple problems with little programs. Today's little program is a script that goes through your Pictures folder and picks out your top-rated photos. The key step here is extracting the rating, which goes by the name System.Rating in the shell property system. The method which does the extraction is ShellFolderItem.ExtendedProperty. var shell = new ActiveXObject("Shell.Application"); var picturesFolder = shell.Namespace(39); // CSIDL_MYPICTURES var items = picturesFolde...

Understanding errors in classical linking: The delay-load catch-22

Wrapping up our week of understanding the classical model for linking, we'll put together all the little pieces we've learned this week to puzzle out a linker problem: The delay-load catch-22. You do some code cleanup, then rebuild your project, and you get LNK4199: /DELAYLOAD:SHLWAPI ignored; no imports found from SHLWAPI What does this error mean? It means that you passed a DLL via the /DELAYLOAD command line switch which your program doesn't actually use, so the linker is saying, "Um, you said to treat this DLL special, but I don't see that DLL." "Oh, right," you say to yourself. "I got rid of a c...

Understanding the classical model for linking: Sometimes you don’t want a symbol to come along for a ride

Continuing our study of the classical model for linking, let's take another look at the trick of taking symbols along for the ride. The technique of taking symbols along for the ride is quite handy if that's what you want, but sometimes you don't actually want it. For example, a symbol taken along for the ride may create conflicts or create unwanted dependencies. Here's an example: Suppose you have a library called stuff.lib where you put functions that are used by various modules in different projects. One of the files in your library might look like this: // filedatestuff.cpp BOOL GetFileCreationTimeW(...

The enduring cultural fascination with Queen’s Bohemian Rhapsody

Bohemian Rhapsody was not part of my world growing up, so I view the continuing cultural fascination with the piece with detached confusion. The hallmark of cultural preoccupation is the fact that the Wikipedia entry deconstructs the piece moment by moment, clocking in at over 2000 words, far in excess of the Wikipedia recommendation of a 60-word summary for a 6-minute piece (10 words per minute). And longer than the entire Wikipedia page for Ruth Bader Ginsburg.

Understanding the classical model for linking: You can override an LIB with another LIB, and a LIB with an OBJ, but you can’t override an OBJ

If you study the classical model for linking, you'll see that OBJ files provided directly to the linker have a special property: They are added to the module even if nobody requests a symbol from them. OBJs bundled into a library are pulled into the module only if they are needed to resolve a needed symbol request. If nobody needs a symbol in the OBJ, then the OBJ doesn't get added to the module. On the other hand, OBJs handed directly to the linker get added to the module whether anybody wants them or not. Last time, we learned about the along for the ride technique which lets you pull components into a modu...