The Program Structure

Now, investigate the entire program structure. As I have already mentioned, in this chapter I describe the classical structure of a Windows application. In every program of this type, there is the main window and, consequently, the main window procedure. Generally, the following sections can be distinguished in the program code:

  • Window class registration

  • Creation of the main window

  • Message-processing loop

  • Main window procedure

Naturally, the program might have other sections. However, the listed sections are always present, and they make up the main program skeleton. Consider them one by one.

The Window Class Registration

Window class registration is carried out using the RegisterClassA function, which accepts the only parameterthe pointer to the WNDCLASS structure containing all information about the window (see the example later in this chapter).

Creating a Window

Based on the registered window class, it is possible to create an instance of the window using the CreateWindowExA (or CreateWindowA ) function. As can be easily noticed, this is similar to the object-oriented programming paradigm.

The Message-Processing Loop

Being written in C, this loop might appear as follows :

 while (GetMessage (&msg, NULL, 0, 0))    {    // Allow keyboard use by translating virtual key messages    // into alphanumeric key messages    TranslateMessage(&msg);    // Return control to Windows and pass the message    //to the window procedure    DispatchMessage(&msg);    } 

The GetMessage() function "traps" the next message, pulling it from the message queue and placing it into the MSG structure. If there are no messages in the queue, the function waits for a message to arrive . Instead of the GetMessage function, the PostMessage with the same set of parameters is frequently used. The difference between GetMessage and PostMessage lies in that the latter does not wait for the message if there are no messages in the queue. The PostMessage function is often used to optimize program operation.

As relates to the TranslateMessage function, it covers the WM_KEYDOWN and WM_KEYUP messages, which are translated into WM_CHAR and WM_DEDCHAR and into WM_SYSKEYDOWN and WM_SYSKEYUP messages that are further converted into WM_SYSCHAR and WM_SYSDEADCHAR. The idea of translation isn't simple replacement. Rather, the function sends additional messages. For example, if you press and release an alphanumeric key, the window will first receive the WM_KEYDOWN message, the WM_KEYUP message will be the next, and the WM_CHAR message will be the last to arrive. As can be easily seen, the exit from the loop takes place only when the GetMessage function returns 0. This is possible only when the exit message arrives (the WM_QUIT message as shown in the example later in this chapter). Thus, the waiting loop plays a double role: First, the messages intended for a specific window are processed in a certain way, and second, the loop waits for the message instructing it to exit the program.

The Main Window Procedure

Here is the prototype of the window function [i] written in C:

 LRESULT CALLBACK WindowFunc(HWND hwnd, UINT message,                          WPARAM wParam, LPARAM lParam) 

Leaving alone the type of the function's return value, [ii] pay special attention to the parameters passed to it. Here they are with brief explanations :

  • hwnd window identifier

  • message message identifier

wParam and lParam parameters clarifying the message goal (for each message, different parameters may play different roles or play no role at all)

As you probably have guessed, all four parameters are of the DWORD type.

And now, consider the "skeleton" of this function written in Assembly language.

Listing 2.1: The "skeleton" of window procedure
image from book
 WNDPROC  PROC PUSH     EBP MOV      EBP, ESP ; Now EBP points to the top of the stack PUSH     EBX PUSH     ESI PUSH     EDI PUSH     DWORD PTR [EBP+14H] ; LPARAM (lParam) PUSH     DWORD PTR [EBP+10H] ; WPARAM (wParam) PUSH     DWORD PTR [EBP+0CH] ; MES (message) PUSH     DWORD PTR [EBP+08H] ; HWND (hwnd) CALL     DefWindowProcA@16 POP      EDI POP      ESI POP      EBX POP      EBP RET      16 WNDPROC  ENDP 
image from book
 

Now, let me comment the fragment provided in Listing 2.1:

RET 16 Exit and pop four parameters from the stack (16 = 4 — 4)

Access to parameters is carried out using the EBP register:

 DWORD PTR [EBP+14H] ; LPARAM (lParam) DWORD PTR [EBP+10H] ; WPARAM (wParam) DWORD PTR [EBP+0CH] ; MES (message) - Message code DWORD PTR [EBP+08H] ; -HWND (-hwnd) - Window descriptor 

The DefwindowProc function is called for the messages that are not handled in the window function. As you can see in this example, no messages arriving to the window function are processed. I have guaranteed that the contents of the following four registers have been preserved: EBX , EBP , ESI , and EDI. This is a requirement specified in the documentation, although I usually try to guarantee that no registers change.

[i] I'd like to point out once again that in this book, the terms "procedure" and "function" are synonyms.

[ii] You'll never need it.



The Assembly Programming Master Book
The Assembly Programming Master Book
ISBN: 8170088178
EAN: 2147483647
Year: 2004
Pages: 140
Authors: Vlad Pirogov

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net