Concurrent Programming on Windows

From the programmer's perspective, GDI consists of several hundred function calls and some associated data types, macros, and structures. But before we begin looking at some of these functions in detail, let's step back and get a feel for the overall structure of GDI.

The GDI Philosophy

Graphics in Windows 98 and Microsoft Windows NT is handled primarily by functions exported from the dynamic-link library GDI32.DLL. In Windows 98, this GDI32.DLL makes use of the 16-bit GDI.EXE dynamic-link library for the actual implementation of many of the functions. In Windows NT, GDI.EXE is used only for 16-bit programs.

These dynamic-link libraries call routines in device drivers for the video display and any printers you may have set up. The video driver accesses the hardware of the video display, and the printer driver converts GDI commands into codes or commands that the various printers understand. Obviously, different video display adapters and printers require different device drivers.

A wide variety of display devices can be attached to PC compatibles. One of the primary goals of GDI is to support device-independent graphics. Windows programs should be able to run without problems on any graphics output device that Windows supports. GDI accomplishes this goal by providing facilities to insulate your programs from the particular characteristics of different output devices.

The world of graphics output devices is divided into two broad groups: raster devices and vector devices. Most PC output devices are raster devices, which means that they represent images as a rectangular pattern of dots. This category includes video display adapters, dot-matrix printers, and laser printers. Vector devices, which draw images using lines, are generally limited these days to plotters.

Much of traditional computer graphics programming (the type you'll find in older books) is based solely on vectors. This means that a program using a vector graphics system is a level of abstraction away from the hardware. The output device uses pixels for a graphics representation, but the program doesn't talk to the interface in terms of pixels. While you can certainly use the Windows GDI as a high-level vector drawing system, you can also use it for relatively low-level pixel manipulation.

In this respect, Windows GDI is to traditional graphics interface languages what C is to other programming languages. C is well known for its high degree of portability among different operating systems and environments. Yet C is also well known for allowing a programmer to perform low-level system functions that are often impossible in other high-level languages. Just as C is sometimes thought of as a "high-level assembly language," you can think of GDI as a high-level interface to the hardware of the graphics device.

As you've seen, by default Windows uses a coordinate system based on pixels. Most traditional graphics languages use a "virtual" coordinate system with horizontal and vertical axes that range (for instance) from 0 to 32,767. Although some graphics languages don't let you use pixel coordinates, Windows GDI lets you use either system (as well as additional coordinate systems based on physical measurements). You can use a virtual coordinate system and keep your program distanced from the hardware, or you can use the device coordinate system and snuggle right up to the hardware.

Some programmers think that when you're working in terms of pixels, you've abandoned device independence. We've already seen in the last chapter that this is not necessarily the case. The trick is to use the pixels in a device-independent manner. This requires that the graphics interface language provide facilities for a program to determine the hardware characteristics of the device and make appropriate adjustments. For example, in the SYSMETS programs we used the pixel size of a standard system font character to space text on the screen. This approach allowed the programs to adjust to different display adapters with different resolutions, text sizes, and aspect ratios. You'll see other methods in this chapter for determining display sizes.

In the early days, many users ran Windows with a monochrome display. Even in more recent years, laptop users were restricted to gray shades. For this reason, GDI was constructed so that you can write a program without worrying much about color—that is, Windows can convert colors to gray shades. Even today, video displays used with Windows 98 have different color capabilities (16 color, 256 color, "high color," and "true color"). Although ink-jet printers have brought low-cost hard-copy color to the masses, many users still prefer their black-only laser printers for high-quality output. It is possible to use these devices blindly, but your program can also determine how many colors are available on the particular display device and take best advantage of the hardware.

Of course, just as you can write C programs that have subtle portability problems when they run on other computers, you can also inadvertently let device dependencies creep into your Windows programs. That's part of the price of not being fully insulated from the hardware. You should also be aware of the limitations of Windows GDI. Although you can certainly move graphics objects around the display, GDI is generally a static display system with only limited animation support. If you need to write sophisticated animations for games, you should explore Microsoft DirectX, which provides the support you'll need.

The GDI Function Calls

The several hundred function calls that comprise GDI can be classified in several broad groups:

The GDI Primitives

The types of graphics you display on the screen or the printer can themselves be divided into several categories, which are called "primitives." These are:

Other Stuff

Other aspects of GDI are not so easily classifiable. These are:

Категории