Chapter 3
Getting a handle on Windows
This chapter will explain the way Windows deals with windows…that is, the way the operating system keeps track of, identifies, and communicates with its GUI programs. Now, I’d like to say right here: I do not work for Microsoft. What I’m describing here is the internals of the Win32 windowing system as best as I can figure it out, which definitely works for all intents and purposes, but perhaps not exactly as the creators of Windows would describe it. I hope this doesn’t detract from your learning experience, and with that out of the way, in we go!
Handles
In any windowing setup, the operating system (or window server if you’re an X nut) needs a method to keep track of and identify its windows. Windows uses identifiers called handles (hence the humor in the title of this chapter). A handle is nothing more than an , and each handle is unique. Handles can refer to windows (these handles are known as s), icons (s), menus (s), and a wide range of other objects and data types.
Handles are returned from functions that create objects or locate objects ( and , for instance) and passed to functions that perform operations on a certain object (such as ). For now, all that needs to be said is that each handle is unique, and that handles can refer to many different types of objects.
Messages and the message loop
So…you have a window, and you’re keeping track of it with a handle. So what? There’s very little good that can be done if Windows, other applications, or even *your* application can’t communicate with it. Thus are given to us messages. Messages are sent to windows to notify them of events; the message, for example, indicates that a user has clicked a button or selected an item from a menu. Messages are also sent to evoke a response from the window; the sends a message to the window that it is enabling.
Messages of any kind are received in the application’s message loop. One of the purposes of the function, discussed in chapter two and demonstrated in chapter four, is to enter the application into this loop. The two-fold purpose of this loop is to retrieve messages one at a time from the application’s event queue (which is automagically created and maintained by Windows for each application) and to dispatch the retrieved messages to the application’s window procedure.
Window Procedures
A window procedure is a special type of function, defined in your application, that allows the programmer to act on the messages that are received. *Everything* that happens to a window (getting moved, getting resized, getting clicked on, etc.) results in a message being sent to that window, but in most cases the programmer won’t want to interfere with the “expected” action of the window…when a user clicks the “minimize” button, the programmer usually won’t pop up a window to ask if this is really what the user wants to do!
For everything that the programmer doesn’t act on, Windows itself will act on the message via the function. This function provides a default window procedure that performs the “expected” window behaviors, such as minimizing normally when the minimize button is clicked. The interaction between the application-defined window procedure and is demonstrated clearly in chapter four, but as a quick and practical example:
The user clicks the “X” button on the title bar of your application, with the intention of closing the window. This sends a message to the application. For this application (let’s say some data needs to be saved), the programmer wishes to verify that the user really wants to close the window. In the window procedure, the programmer intercepts the message and brings up a confirmation dialog asking “Do you really want to close the window? Yes/No”. After that dialog is displayed and the user has selected either Yes or No, the programmer signals that the application has processed the message and that should *not* process it. If the user selects “Yes”, the programmer calls , a function that begins to shut down an application. In turn, sends the message to the window, but because this time the programmer does not signal that the application is going to handle it, so the task falls to . causes the window to disappear and the message loop to exit, allowing to return and the application to end cleanly.
Window Classes
Before a window can be created, before you can get a handle to it and send messages to it, Windows needs to know certain things about that window in order to draw it. Things such as the window’s icon and menu (if any), how Windows should redraw it after it has been updated, where the window procedure is, and other various bits of information are all specified by the window class. All windows belonging to your application must register their own class, or the window cannot be created. There are some predefined window classes that can be used to create specialized windows, we’ll cover those starting in chapter five.
Hopefully, you’ve now got a bit of insight as to how windows are maintained and interacted with. If it’s not totally clear yet, don’t worry; it’s my experience that practical examples are helpful in understanding things like this. So with that, let’s create our first window!
