Managing the Device Context

Windows NT provides a veritable sea of memory. Boy, this feels different compared to 16-bit Windows. Not only can our applications stretch their legs, the system itself no longer has to fit inside 16-bit-addressable blocks, and we have room for lots and lots of pens and brushes and fonts. In the 16-bit Windows programming environment, it was important to conserve the use of drawing objects. In the 32-bit world we have to have richer data structures to hold this new wealth of data. And that means it takes longer to look things up.

The old limitations gave rise to a coding style which created, selected, used, and destroyed objects (like pens and brushes) constantly. Create, select, use, destroy; create, select, use, destroy. This limited the number of objects in the system and kept the application from bouncing into the address space walls, or worse, forcing another application into them. Because of the client-server transition, object creation and destruction are much more expensive on Windows NT. Because of the new capacity for large numbers of objects, selecting objects is a bit slower too. So create all your objects when you first need them. Then try to get into the pattern of select, use, use, use; select, use, use, use. Don't destroy them at all until you really are done with them.

Let's take an example from real life. We had someone porting to Windows NT complaining that their graphics were slower than before. We had them use the API logger (which we'll cover in the next chapter) to see what was wrong. We found them using the following pattern: select(grey); patblt(...); select(black); patblt(...); select(grey); patblt(...); select(black); patblt(...).

We had them change this to select(grey); patblt(...); patblt(...); patblt(...); select(black); patblt(...); patblt(...); patblt(...). This solved the problem because it avoids the repeated lookups in the new data structures. This technique is applicable to pens, fonts, colors, palettes, and brushes.

While we're on the topic of graphical device contents (DCs), into which we've been selecting these objects, let's blow away another piece of lore. If you were a 16-bit Windows programmer, you were told to avoid the use of your own DC's because the system could only support a few. This is not true on Windows NT. Use the creation style CS_OWNDC as much as you can in your RegisterClass API call. This avoids repeated use of the relatively expensive GetDC and ReleaseDC calls every time you have to draw. It also preserves the selected objects in your own DC in between calls, eliminating the need to select them again after each call to GetDC.