A fascinating aspect of Windows is that there can be multiple
program copies of an application running, or at least residing in memory,
instances concurrently.
After all, why not, since this is a multitasking environment? You can, for example, have two copies of your word processor executing simultaneously, and you can jump between them. In such a situation, each copy would be an instance of the program. The current instance refers to the one you are dealing with at this moment.
There are some interesting considerations from this ability to have multiple copies or instances. Windows is not wasteful and only loads one copy of the code into RAM. Windows will, upon entry to each instance, give it a unique handle, but the reality is that there is just the one copy of the code. For this to work, each instance needs to have its own copy of the data segment or segments.
The downside is that your program needs to have some extra statements to handle multiple instances. In this is fairly standardized, and you can use the supplied skeleton program as the basis for much more complicated projects, without having to worry about multiple instances.
With 32-bit applications running in Windows 95, multiple instances are treated as totally separate programs, so special instance-handling code is not required.
Event driven I introduced the basic concept of event driven back on page 7 1; intertwined with this is messages. I also said that Windows sends messages to an application, and the latter has to decipher them and act accordingly. Let us consider this in more detail, since it affects the very soul of our program.
Our program has to call Windows and wait for a message while waiting, it is in an idle state and other tasks can be executing. Windows does an incredible amount of housekeeping, including receiving all of the incoming messages and parcelling them to individual queues. Any mouse activity on your application’s window, for example, that Windows determines will affect your program will result in the generation of an appropriate message. Windows is always working, seeing everything that happens.
Structure Of Below is the application’s main function, entered from Windows when the program starts executing. It is called and I’ve used C syntax straight from the textbooks:
int PASCAL FAR
HANDLE //current instance HANDLE //previous inst. LPSTR //command line ptr
int //show-type
initialization... instance handling...
create and display a window... while
The above code is ok for a application as well as a application. One difference is the size of the parameters passed to WinMain() see Table 3.1. A 32-bit application does not have to worry about Also, a 32-bit application does not have to name its first entry point but we can continue to do this as a convention. Also, as explained below, and on page 3 14, the Pascal calling convention is only applicable to applications.
Pascal convention STDCALL calling convention Data label prefixes Translate/ Dispatch
The code sample should be readable, even if you don’t know C. Note that some of the Windows textbooks give the basic program structure in “classical” C, not ANSI C, and I have stuck with that. You will notice specified as a parameter, and this may need some clarification to those unfamiliar with C. It should become clear later on when you see it in assembly language. This function requires that an address, to which the returned message can be placed, be provided as a parameter. The means “address of’, in this case the address of a data area as
(not defined in listing).
You will also notice the PASCAL qualifier in the declaration of This is because Windows 3.x uses Pascal calling conventions, not C conventions. So the override is needed. This is explained in more detail later (see page 112, if the fancy takes you), and a note was made earlier, on page 72.
You might like to glance ahead to Chapter 13 to see a complete 32-bit application written in assembly language. There, you will see the procedures default to the STDCALL convention (as specified in the directive: see page 111). This is a mixture of C and Pascal, in which parameters are pushed onto the stack from right to left, and stack cleanup is performed by the called procedure.
I suppose this is as good a place as any in which to introduce the Windows labelling conventions. You have had a exposure to them in the above listing. What I’m talking about are the prefixes to the parameters. These are put there to clarify the type of data the parameter represents. It would be breaking the flow of the explanation to describe this in detail, but the prefixes used above are to signify type of “handle” and “lp” to signify “long pointer”. A more complete list of prefixes and data types is given on page 82.
Message Loop
The WinMain() function contains what we refer to as the “message loop”.
Looking at the above listing, it commences with declarations of the passed parameters and their data types. A little further down you’ll see This is the one I’ve been talking about it goes back to Windows and waits for a message.
Whenever a message is available on the queue, and also whenever Windows decides the time is appropriate, control will return to your program with the message.
Callback function long FAR HWND WORD LONG