Programming for the OS/2 PM in C:Introduction Continues

<< Introduction -- Index -- The window message processor >>

(Note: I was unable to find the original English piece of this section. This is an translation using Google Translate)

First I. Theoretical introduction
This last part I finished that created a program that is suitable for the system to join. Before I go any further, we have to stand up to a few words to say roughly the following steps, and try to explain the why. The mikéntekrôl later.

The Windows
What is meant by the window? PM on non-windows user the ability to communicate and perform tasks. The user's point of view in the window, a rectangular area of ​​the screen through which the application input (input) came to accept (mouse, keyboard) and output (output) values. The system automatically creates the Desktop window (the user's point of view, this worksheet) of Presentation Manager starts. This window is the "original" parent of all other windows, which is created during the operation of the system. Each application must have called the PM core (main) window, which is the parent of the Desktop window, the system communicates with the window when the application wants to achieve.

I wrote in the previous section, each window has a so-called. procedure window (window), which handles messages sent to the window, and if you have special needs, then this function must be modified. The amendment should be understood that the window can be specified when creating the address of a function, which is used as a window procedure will be used. In this we have defined the function you can manage the messages that we want to effect change. The rest shall be forwarded to the original, or by the system's default window procedure. From the default window procedure is necessary because the application of a single message can not leave unanswered, so if you can not understand what it means, you should forward the WinDefWindowProc has, or has WinDefDlgProc, to deal with it. Why do you have two default procedure? It is because these functions provide only minimal functionality, a window, but the dialog windows require more complex treatment than in the other windows. For more information see the creation of the windows and then it drops.

How to achieve the "original" window procedure used? Well, when the program creates a window, it must be that the new window which class (Class) belongs. The class is actually a set of attributes, that is, a class is stored, how has appearance of the window, what can be done with it (resize, move, minimize, etc), how it behaves, and each class has a window procedure. The system offers a number of pre-defined classes, but it is also possible to create custom classes for WinRegisterClass function.

Thus, each window to a class, and each class has a window procedure or not. When an application creates a window, it is more than one way you can do:
 * First The creation to specify a window procedure. Then the system will be used for this function. In this case, the message or by the system default Messaging can be passed on, or you can ask the class window procedure address WinQueryClassInfo function, and this function can be passed on the message.
 * Second The application the window to a specified class creates his own, and then replaces it in the window procedure's. This procedure is for subclassing (inheritance) is called. In this case, a window can be changed by the procedure-call WinSubclassWindow, which was originally used as a return value to the address of the procedure.

Second Theoretical Introduction II.
Before you begin migration to practical arrangements, on the one hand, I should mention, namely the relationship between the windows side. There are two types of connections between windows:

Parent-child relationship
This relationship determines whether a window to appear on the screen, and how (in what way) should be drawn. This relationship also governs what happens when one ceases to be covered windows or disappear (hide). This type of connection must always be specified and the connection can not be changed once created. All windows must have parental, no matter how many children can be.

The parent-child relationship is basically determined by plotting the relationship. This means that the child is the coordinate system that originates in the szülôjétôl, the parents of the child's upper left origin (and the coordinates increase to the right and down). The child windows are related to one another in the same way that, as the parent of the same (for each other, they may be), it is possible to define a third axis (z) according to order (z-order, z-order). This sequence determines the order of child windows in a row (as in a deck of cards).

Another important moment that a child and parents within the framework should remain, that is "hanging" parts do not seem to be (in the case of a child already larger than the parent, and is positioned so that some parts of "overhanging" the parent frame).

Ownership relations
This relationship means that any window can be (optionally) the owner. In this connection the windows appear to be a single unit. An example is the so-called. frame window (frame window is the window that contains the scaling framework of the standard buttons (System Menu, reducers, enlargers keys)) and the menu bar connection: both are separate windows, but the frame window owns the menu line, and together the two windows seen as an entity in the user's point of view. The ownership relations are not mandatory and can be changed at runtime.

Third Window creation parameters
Window for the following optional parameters:
 * Class: compulsory data, determines that the window class. Here you can enter any of the system is given by, or created by the application in its class.
 * Style: the appearance and behaviour of the window, please. Here, the values ​​must be given, which is not made clear in the window class. For example, if the window WC_FRAME class, then you should create a frame window, but the window style specifies that the window frame to which (FS_SIZEBORDER style frame using the frame will have a scalable window).
 * The name of the window: the window can be called, which is displayed depending on the grade and style. Eg, a dialog box displays the name of the header, but it is not a editable (since there is no header).
 * Parent window: mandatory reporting, the resulting window, this will be the parent.
 * Parent of the window relative position: the position of the upper left corner of the parent's coordinate system.
 * Location of the window in the z-order: here you can specify which window positioned behind the new window, or bottom respectively. get to the top. In the first case, the ID of the window to be provided, which is subject to, and if it should be placed to the top, then the HWND_TOP when completely lowered, the value must be HWND_BOTTOM.
 * The window size of the created window's width and height can be specified.
 * The owner window.
 * The window identifier of the window when you create an account, the system returns (window handle), which can be invoked later on this window. This value is unique within the system, and totally unpredictable, that is not possible to know what kind of value is received back, so it is unique, we have to be identified for the windows. This identifier can then refer to the window. The conclusion of a single identifier, that is a lot of parent-child relationship in the child window must be given a unique identifier. Where to use it? Creating a dialog often happens that dialog editor will design the window. When designing each element must be an identifier. The result is a resource file will be created automatically changes to the system of which can be designed to run at windows. In this case, not created by the application of the child windows (editor, push buttons, check boxes, etc), but the system, so that the window handle of giving is unknown, but the design is the identification is known, and on this basis are available for each child windows.
 * The window class-specific data: these data are passed to the window procedure ', which can process them.

4th WinCreateWindow function
The most common function WinCreateWindow, which receives all the parameters previously mentioned.

FOAM foam; BOOL rc; HMQ hmq;
 * 1) define INCL_WINMESSAGEMGR /* Message Window Functions */
 * 2) define INCL_WINWINDOWMGR /* Window Manager Functions */
 * 3) include
 * 1) include
 * 2) include

QMSG qmsgmsg; void main (void) { ULONG = flFrameControlFlags FCF_MINMAX | FCF_SIZEBORDER | FCF_SYSMENU | FCF_TASKLIST | FCF_TITLEBAR; FRAMECDATA fcdata; HwndFrame HWND; fcdata.cb = sizeof (FRAMECDATA); fcdata.flCreateFlags = flFrameControlFlags; fcdata.hmodResources = (HMODULE) NULL; fcdata.idResources = ID_RESOURCES; // Initiate registration Foam WinInitialize = (0); // Return Value Test if (NULLHANDLE Foam ==) { fprintf (stderr, "WinInitialize failed\n"); exit (1); }        // Create a message queue hmq WinCreateMsgQueue = (foam, 0); if (== hmq NULLHANDLE) {                fprintf (stderr, "WinCreateMsgQueue failed\n"); }        //         // Create the window! //        hwndFrame = WinCreateWindow (HWND_DESKTOP, WC_FRAME "first window"            0,0,0,0,0, NULLHANDLE,             HWND_TOP, 10, &fcdata, NULL); // Position and size settings WinSetWindowPos (hwndFrame, HWND_TOP, 100, 100,        300, 200, SWP_MOVE | SWP_SIZE); // Display WinShowWindow (hwndFrame, TRUE); //         // Message loop //        while (WinGetMsg (foam &qmsgmsg, 0,0,0)) WinDispatchMsg (foam &qmsgmsg); // Remove entry if (WinTerminate (Foam)) { fprintf (stderr, "WinTerminate failed\n"); } }
 * 1) Define one ID_RESOURCES
 * 2) Define one ID_FRAME

Huh. There are many things in this program, which may not be obvious at first glance: ULONG = flFrameControlFlags FCF_MINMAX | FCF_SIZEBORDER | FCF_SYSMENU | FCF_TASKLIST | FCF_TITLEBAR; FRAMECDATA fcdata;

As I wrote in history of the window can be specified when creating the class-specific data. This one - the data area pointer - pointer (pointer) can be done. The first two bytes of the data area of ​​the data area should be a length, followed by the actual data. This is the pointer to the window procedure of the window are passed to the window-creation. As a frame window is (WC_FRAME), I created this class of data structures to fill. Since the class system WC_FRAME predefined class, of course, the system is defined by the corresponding structure is: FRAMECDATA. It contains the following fields:

cb = size of the structure flCreateFlags = control on the frame (frame-controlling) the value of hmodResources = the file resource identifier. idResources = the resource ID.

The flCreateFlags value tells the system how to frame a window: FCF_MINMAX = min / max buttons = FCF_SIZEBORDER scalable framework FCF_SYSMENU = System Menu FCF_TASKLIST = the application appears in the "task" list (the Active Jobs list) FCF_TITLEBAR = header of the window will be.

HWND hwndFrame

As was discussed in the previous article about the system all the "stuff" unique identifier (handle) is identified. This is no different for any of the windows, so any window creation function window handle (HWND) returns. Consider this store because every action later this ID refers, that is, if we want to do something in windows (hide, move, scale), you need to enter this ID in the appropriate place. (Where, of which later.) hwndFrame WinCreateWindow = (HWND_DESKTOP, WC_FRAME "first window", 0,0,0,0,0,		 	    NULLHANDLE, HWND_TOP, 10, &fcdata, NULL);

The WinCreateWindow function expects the following parameters:

HwndParent HWND parent = ID. The main application (Main) window when HWND_DESKTOP PszClass HR = class name of the window HR = pszName the window "name" Window style = ULONG flStyle LONG x = x coordinate LONG y = y coordinate LONG cx = width LONG cy = height HwndOwner HWND window = owner, and if not, NULLHANDLE HwndInsertBehind = HWND of the window to the identifier of                             We want to do behind the new window (z-order) ULONG id = unique identifier of the window, where we PCtlData = PVOID pointer to the class-specific data PPresParams PVOID = display parameter hwnd = WinCreateWindow (hwndParent, pszClass, pszName, flStyle, x, y, cx, cy, 		       hwndOwner, hwndInsertBehind, time, pCtlData, pPresParams);

The example program window from 0.0 to position 0 and 0 high winds bring up, and then later I set the size of the WinSetWindowPos (hwndFrame, HWND_TOP, 100, 1000, 300, 200, SWP_MOVE | SWP_SIZE); Send for him. WinShowWindow (hwndFrame, TRUE); The window style 0 as I have, so the window is not visible once it is created (this is so good, it will only be visible when everything has been configured). // // Message loop // while (WinGetMsg (foam &qmsgmsg, 0,0,0)) WinDispatchMsg (foam &qmsgmsg);

All applications are called. Loop message (message handling) is performed during the operation. It consists of WinGetMsg function asks for a message from a message queue (message queue), and then forward it, as long as the function returns TRUE. It is possible to filter the messages for each, but this is not the subject of the article.

5th Completion
In the above example we can see the results when you run a program on the screen. Possible to experiment the effect of each parameter, such as the omission of certain elements flCreateFlags or add new values. Just can possibly try other classes, but you must take care that the class-specific data will be different. Either do not need to pass anything (NULL), or you can look in the documentation for each class structures and use them.

Foretaste of the system's pre-defined classes: WC_BUTTON WC_COMBOBOX WC_CONTAINER WC_ENTRYFIELD WC_FRAME WC_LISTBOX WC_MENU WC_NOTEBOOK WC_SCROLLBAR WC_SLIDER WC_SPINBUTTON WC_STATIC WC_TITLEBAR WC_VALUESET However, one thing to keep in mind: in most cases, the application will not be posted on the "task" list, so "kilövésükrôl" something must be provided. (Kill-9, WatchCat, etc).

<< Introduction -- Index -- The window message processor >>