Advertisment

Painting Windows

author-image
PCQ Bureau
New Update

In our previous issues, we’ve

covered quite a bit of API programming concepts, from basics like window classes,

instances, handles, etc, to creating our editor with basic functionality and menus. This

month, we take a break from the dull world of text, and see how to handle graphics (or

painting, as it is called) in Windows.

Advertisment

In the good old days of DOS, one would simply use the mem command to poke values in the

screen buffer. This was the fastest way of displaying images, and most serious graphics

programmers actually created their own libraries of high-speed graphics. All these methods

would basically rely on direct hardware access, which was okay, since there was only one

application accessing the entire computer at any point in time.

https://img-cdn.thepublive.com/filters:format(webp)/pcq/media/post_attachments/26190d03f7316340c214585db23eed791a57cab7d4c4571c2795d4b2f90c288a.jpg (18948 bytes) align="right" hspace="5" vspace="5">However, things got a little different, in Windows at

any time there may be any number of applications that may want to display information.

Information from each window has to be preserved, which would not happen in case of direct

hardware calls (they would overwrite the display under them). For this reason, all output

to the screen is handled by Windows and direct hardware access is usually not allowed.

Another reason for this is the wide number of hardware that Windows runs on. directly

handling hardware would mean writing a separate program for each different device.

However, if Windows were to handle it, it would route the actual functionality via a

display driver, which would be installed for specific display, and know how to work things

out.

In DOS, the entire screen area was available for use by the application. In Windows,

applications use windows as their primary output device instead of the screen. To identify

the displayable surface of each different window, Windows issues a device context (dc) to

each window. This dc is unique for every window, and applications can write to any window,

if they know the dc for that particular window. This way, any application can draw in any

window, without the fear of any information being lost.

Advertisment

When we talk about painting or drawing on a window, a message we discussed a long time

back should be recalled–the WM_PAINT message. This is the message Windows uses to

tell a window that it needs to be repainted. This would probably result in the window

repainting its contents. For example, if an overlapped window is suddenly brought to

front, it receives a WM_PAINT message, so that it can repaint itself. WM_PAINT is also

sent when a move or resize of the window happens. The actual window (the window border,

caption, etc), is repainted by a different message (WM_NCPAINT). In fact, one can write a

custom handler for this message and give the window a completely different look.

To draw in a window, the application must first retrieve the dc of that window. This is

done using the GetDC function. This retrieves a handle of a display device context for the

client area of the specified window. The display device context can be used in subsequent

GDI functions to draw in the client area of the window.

HDC GetDC(



HWND hWnd // handle of window


);

Advertisment

Here, hWnd identifies the window whose device context is to be retrieved.

Note that this function returns the HDC–the handle of the dc. This might

sound familiar, as windows also has handles (hwnd). Almost everything in windows is

referenced using handles, so one might as well get used to this method.

Once you’ve the dc, you can use the numerous powerful graphics operations that

Windows provides for painting. For example, to draw a rectangle on the dc, simply use the

following function:

Advertisment

rectangle(dc, x1, y1, x2, y2);

Here dc is the handle of the display context on which the rectangle is to be drawn.

After that are the coordinates of the top-left and bottom-right corners of the rectangle.

Note that these coordinates are relative to the top-left corner of the window in which

this is being drawn. The window’s top-left corner is (0,0), with the x

increasing from left to right, and the y increasing from top to bottom.

If you try drawing this rectangle, you’ll notice that Windows uses a specific

color to draw the rectangle. Also, it is filled with a specific color and pattern (could

be solid). These color and style values are actually derived from the window class (if you

remember we had filled in these values in the TWndClass structure before using the

RegisterClass function. The color and style of the rectangle is defined by the pen

of the dc, and the color and style of the "fill" is defined by the brush

of the dc. By changing these two before any drawing operation, all subsequent drawing

operations will be effected.

Next month, we’ll see how we actually handle the painting, pens, brushes etc, and

how we create graphics objects. We’ll also create a small "Paintbrush" like

program, but until then, happy coding!

Advertisment