═══ 1. Keyboard Accelerators ═══ A keyboard accelerator (shortcut key to the user) is a keystroke that generates a command message for an application. This chapter describes how to use keyboard accelerators in your PM applications. ═══ 1.1. About Keyboard Accelerators ═══ Using a keyboard accelerator has the same effect as choosing a menu item. While menus provide an easy way to learn an application's command set, accelerators provide quick access to those commands. Without accelerators, a user might generate commands by pressing the Alt key to access the menu bar, using the Arrow keys to select an item, then pressing the Enter key to choose the item. In contrast, accelerators allow the user to generate commands with a single keystroke. Like menu items, accelerators can generate WM_COMMAND, WM_HELP, and WM_SYSCOMMAND messages. Although, normally, accelerators are used to generate existing commands as menu items, they also can send commands that have no menu-item equivalent. ═══ 1.1.1. Accelerator Tables ═══ An accelerator table contains an array of accelerators. Accelerator tables exist at two levels within the operating system: a single accelerator table for the system queue and individual accelerator tables for application windows. Accelerators in the system queue apply to all applications-for example, the F1 key always generates a WM_HELP message. Having accelerators for individual application windows ensures that an application can define its own accelerators without interfering with other applications. An accelerator for an application window can override the accelerator in the system queue. An application can modify both its own accelerator table and the system's accelerator table. The application can set and query the accelerator table for a specific window or for the entire system. For example, an application can query the system accelerator table, copy it, modify the copied data structures; and then, use the modified copy to set the system accelerator table. An application also can modify its window's accelerator table at run time to respond more appropriately to the current environment. Note: An application that modifies any accelerator table other than its own should maintain the original accelerator table; and, before terminating, restore that table. ═══ 1.1.2. Accelerator-Table Resources ═══ You can use accelerators in an application by creating an accelerator-table resource in a resource-definition file. Then, when the application creates a standard frame window, the application can associate that window with the resource. As specified in a resource-definition file, an accelerator table consists of a list of accelerator items, each defining the keystroke that triggers the accelerator, the command the accelerator generates, and the accelerator's style. The style specifies whether the keystroke is a virtual key, a character, or a scan code, and whether the generated message is WM_COMMAND, WM_SYSCOMMAND, or WM_HELP; WM_COMMAND is the default. ═══ 1.1.3. Accelerator-Table Handles ═══ Applications that use accelerator tables refer to them with a 32-bit handle. An application using this handle, by default, can make most API function calls for accelerators without having to account for the internal structures that define the accelerator table. When an application needs to dynamically create or change an accelerator table, it must use the ACCEL and ACCELTABLE data structures. ═══ 1.1.4. Accelerator-Table Data Structures ═══ An accelerator table consists of individual accelerator items. Each item in the table is represented by an ACCEL structure that defines the accelerator's style, keystroke, and command identifier. Typically, an application defines these aspects of an accelerator in a resource-definition file, but the ACCEL structure also can be built in memory at run time. An accelerator table is represented by an ACCELTABLE structure that specifies the number of accelerator items in the table, the code page used for the keystrokes in the accelerator items, and an array of ACCEL structures (one for each item in the table). Applications that use ACCELTABLE structures directly must allocate sufficient memory to hold all the items in the table. ═══ 1.1.5. Accelerator-Item Styles ═══ An accelerator item has a style that determines what combination of keys produces the accelerator and what command message is generated by the accelerator. An application can specify the following accelerator-item styles in the fs field of the ACCEL structure: ┌───────────────┬─────────────────────────────────────────────┐ │Style │Description │ ├───────────────┼─────────────────────────────────────────────┤ │AF_ALT │Specifies that the user must hold down the │ │ │Alt key while pressing the accelerator key. │ ├───────────────┼─────────────────────────────────────────────┤ │AF_CHAR │Specifies that the keystroke is a character │ │ │that is translated using the code page for │ │ │the accelerator table. (This is the default │ │ │style.) │ ├───────────────┼─────────────────────────────────────────────┤ │AF_CONTROL │Specifies that the user must hold down the │ │ │Ctrl key while pressing the accelerator key. │ ├───────────────┼─────────────────────────────────────────────┤ │AF_HELP │Specifies that the accelerator generates a │ │ │WM_HELP message instead of a WM_COMMAND │ │ │message. │ ├───────────────┼─────────────────────────────────────────────┤ │AF_LONEKEY │Specifies that the user need not press │ │ │another key while the accelerator key is │ │ │down. Typically, this style is used with the│ │ │Alt key to specify that simply pressing and │ │ │releasing that key triggers the accelerator. │ ├───────────────┼─────────────────────────────────────────────┤ │AF_SCANCODE │Specifies that the keystroke is an │ │ │untranslated scan code from the keyboard. │ ├───────────────┼─────────────────────────────────────────────┤ │AF_SHIFT │Specifies that the user must hold down the │ │ │Shift key when pressing the accelerator key. │ ├───────────────┼─────────────────────────────────────────────┤ │AF_SYSCOMMAND │Specifies that the accelerator generates a │ │ │WM_SYSCOMMAND message instead of a WM_COMMAND│ │ │message. │ ├───────────────┼─────────────────────────────────────────────┤ │AF_VIRTUALKEY │Specifies that the keystroke is a virtual │ │ │key-for example, the F1 function key. │ └───────────────┴─────────────────────────────────────────────┘ ═══ 1.2. Using Keyboard Accelerators ═══ This section explains how to perform the following tasks:  Create an accelerator-table resource  Include an accelerator table in a frame window  Modify an accelerator table ═══ 1.2.1. Creating an Accelerator-Table Resource ═══ The following code fragment shows a typical accelerator-table resource: ACCELTABLE ID_ACCEL_RESOURCE BEGIN VK_ESC, IDM_ED_UNDO, AF_VIRTUALKEY Or AF_SHIFT VK_DELETE, IDM_ED_CUT, AF_VIRTUALKEY VK_F2, IDM_ED_COPY, AF_VIRTUALKEY VK_INSERT, IDM_ED_PASTE, AF_VIRTUALKEY END This accelerator table has four accelerator items. The first one is triggered when the user presses Shift+Esc, which sends a WM_COMMAND message (the default). An accelerator table in a resource-definition file has an identifier (ID_ACCEL_RESOURCE in the previous example). You can associate an accelerator-table resource with a standard frame window by specifying the table's resource identifier as the idResources parameter of the WinCreateStdWindow function. An application can load an accelerator table resource-definition file automatically when creating a standard frame window, or it can load the resource independently and associate it with a window or with the entire system. ═══ 1.2.2. Including an Accelerator Table in a Frame Window ═══ You can add an accelerator table to a frame window either by using the WinSetAccelTable function or by defining an accelerator-table resource (as shown in the previous section) and creating a frame window with the FCF_ACCELTABLE frame style. The second method is shown in the following code fragment: Uses Os2Def,Os2Base,Os2PmApi; Var HwndFrame,hwndClient : HWND; (* Сsken var tom!! *) SzClassName : PCHAR; (* Сsken var tom!! *) SzTitle : PCHAR; (* Сsken var tom!! *) FlControlStyle : ULONG; (* Сsken var tom!! *) Begin SzClassName := 'MyClass'; SzTitle := 'MyWindow'; FlControlStyle := FCF_MINMAX Or (* Min and max buttons *) FCF_SHELLPOSITION Or (* System size and position *) FCF_SIZEBORDER Or (* Size border *) FCF_TITLEBAR Or (* Title bar *) FCF_TASKLIST Or (* Task list *) FCF_ACCELTABLE Or (* Accelerator table *) FCF_SYSMENU Or (* System menu *) FCF_MENU; (* Menu *) hwndFrame := WinCreateStdWindow(HWND_DESKTOP, WS_VISIBLE, &flControlStyle, szClassName, szTitle, 0, nil, ID_MENU_RESOURCE, &hwndClient); Notice that if you set the flControlStyle parameter to the FCF_STANDARD flag, you must define an accelerator-table resource, because FCF_STANDARD includes the FCF_ACCELTABLE flag. If the window being created also has a menu, the menu resource and accelerator resource must have the same resource identifier; this is because the WinCreateStdWindow function has only one input parameter to specify the resource identifiers for menus, accelerator tables, and icons. If an application creates an accelerator table resource-definition file; then, opens a standard frame window (as shown in the preceding example), the accelerator table is installed automatically in the window's message queue, and keyboard events are translated during the normal processing of events. The application simply responds to WM_COMMAND, WM_SYSCOMMAND, and WM_HELP messages; it does not matter whether these messages come from a menu or an accelerator. An application also can add an accelerator table to a window by calling the WinSetAccelTable function with an accelerator-table handle and a frame-window handle. The application can call either the WinLoadAccelTable function to retrieve an accelerator table from a resource file or the WinCreateAccelTable function to create an accelerator table from an accelerator-table data structure in memory. ═══ 1.2.3. Modifying an Accelerator Table ═══ You can modify an accelerator table, for either your application windows or the system, by doing the following: 1. Retrieve the handle of the accelerator table. 2. Use that handle to copy the accelerator-table data to an application-supplied buffer. 3. Change the data in the buffer. 4. Use the changed data to create a new accelerator table. Then you can use the new accelerator-table handle to set the accelerator table, as outlined in the following list: 1. Call WinQueryAccelTable to retrieve an accelerator-table handle. 2. Call WinCopyAccelTable with a NULL buffer handle to determine how many bytes are in the table. 3. Allocate sufficient memory for the accelerator-table data. 4. Call WinCopyAccelTable, with a pointer to the allocated memory. 5. Modify the data in the buffer (assuming it has the form of an ACCELTABLE structure). 6. Call WinCreateAccelTable, passing a pointer to the buffer with the modified accelerator-table data. 7. Call WinSetAccelTable with the handle returned by WinCreateAccelTable. ═══ 2. List-Box Controls ═══ A list box is a control window that displays several text items at a time, one or more of which can be selected by the user. This chapter explains how to create and use list-box controls in PM applications. ═══ 2.1. About List Boxes ═══ An application uses a list box when it requires a list of selectable fields that is too large for the display area or a list of choices that can change dynamically. Each list item contains a text string and a handle. Usually, the text string is displayed in the list-box window; but the handle is available to the application to reference other data associated with each of the items in the list. A list box always is owned by another window that receives messages from the list box when events occur, such as when a user selects an item from the list box. Typically, the owner is a dialog window (as shown in the following figure,) or the client window of an application frame window. The client- or dialog-window procedure defined by the application responds to messages sent from the list box. A list box always contains a scroll bar for use when the list box contains more items than can be displayed in the list-box window. The list box responds to mouse clicks in the scroll bar by scrolling the list; otherwise, the scroll bar is disabled. The maximum number of items permitted in a list box is 32767. ═══ 2.2. Using List Boxes ═══ An application uses a list-box control to display a list in a window. List boxes can be displayed in standard application windows, although they are more commonly used in dialog windows. In either case, notification messages are sent from the list box to its owner window, enabling the application to respond to user actions in the list. Once a list box is created, the application controls the insertion and deletion of list items. Items can be inserted at the end of the list, automatically sorted into the list, or inserted at a specified index position. Applications can turn list drawing on and off to speed up the process of inserting numerous items into a list. The owner-window procedure of the list box receives messages when a user manipulates the list-box data. Most default list actions (for example, highlighting selections and scrolling) are handled automatically by the list box itself. The application controls the responses when the user chooses an item in the list, either by double-clicking the item or by pressing Enter after an item is highlighted. The list box also notifies the application when the user changes the selection or scrolls the list. Normally, list items are text strings drawn by a list box. An application also can draw and highlight the items in a list. This enables the application to create customized lists that contain graphics. When an application creates a list box with the LS_OWNERDRAW style, the owner of the list box receives a WM_DRAWITEM message for each item that should be drawn or highlighted. This is similar to the owner-drawn style for menus, except that the owner-drawn style applies to the entire list rather than to individual items. ═══ 2.2.1. Creating a List-Box Window ═══ List boxes are WC_LISTBOX class windows and are predefined by the system. Applications can create list boxes by calling WinCreateWindow, using WC_LISTBOX as the window-class parameter. A list box passes notification messages to its owner window, so an application uses its client window, rather than the frame window, as the owner of the list. The client-window procedure receives the messages sent from the list box. For example, to create a list box that completely fills the client area of a frame window, an application would make the client window the owner and parent of the list-box window, and make the list-box window the same size as the client window. This is shown in the following code fragment. Uses Os2Def,Os2Base,Os2PmApi; Var HwndClient,hwndList : HWND; (* Сsken var tom!! *) Rcl : RECTL; (* Сsken var tom!! *) Begin (* How big is the client window? *) WinQueryWindowRect(hwndClient, &rcl); (* Make a list-box window. *) hwndList := WinCreateWindow(hwndClient, (* Parent *) WC_LISTBOX, (* Class *) '', (* Name *) WS_VISIBLE Or LS_NOADJUSTPOS, (* Style *) 0, 0, (* x, y *) rcl.xRight, rcl.yTop, (* cx, cy *) hwndClient, (* Owner *) HWND_TOP, (* Behind *) ID_LISTWINDOW, (* ID *) nil, (* Control data *) nil); (* parameters *) Because the list box draws its own border, and a frame-window border already surrounds the client area of a frame window due to the adjacent frame controls, the effect is a double-thick border around the list box. You can change this effect by calling WinInflateRect to overlap the list-box border with the surrounding frame-window border, resulting in only one list-box border. Notice that the code specifies the list-box window style LS_NOADJUSTPOS. This ensures that the list box is created exactly the specified size. If the LS_NOADJUSTPOS style is not specified, the list-box height is rounded down, if necessary, to make it a multiple of the item height. Enabling a list box to adjust its height automatically is useful for preventing partial items being displayed at the bottom of a list box. ═══ 2.2.2. Using a List Box in a Dialog Window ═══ List boxes most commonly are used in dialog windows. A list box in a dialog box is a control window, like a push button or an entry field. Typically, the application defines a list box as one item in a dialog template in the resource-definition file, as shown in the following resource compiler source-code fragment. DLGTEMPLATE IDD_OPEN BEGIN DIALOG "Open...", IDD_OPEN, 35, 35, 150, 135, FS_DLGBORDER, FCF_TITLEBAR BEGIN LISTBOX IDD_FILELIST, 15, 15, 90, 90 PUSHBUTTON "Drive", IDD_DRIVEBUTTON, 115, 70, 30, 14 DEFPUSHBUTTON "Open", IDD_OPENBUTTON, 115, 40, 30, 14 PUSHBUTTON "Cancel", IDD_CANCELBUTTON, 115, 15, 30, 14 END END Once the dialog resource is defined, the application loads and displays the dialog box as it would normally. The application inserts items into the list when processing the WM_INITDLG message. A dialog window with a list box usually has an OK button. The user can select items in the list, and then indicate a final selection by double-clicking, pressing Enter, or clicking the OK button. When the dialog-window procedure receives a message indicating that the user has clicked the OK button, it queries the list box to determine the current selection (or selections, if the list allows multiple selections), and then responds as though it had received a WM_CONTROL message with the LN_ENTER notification code. ═══ 2.2.3. Adding or Deleting an Item in a List Box ═══ Applications can add items to a list box by sending an LM_INSERTITEM or LM_INSERTMULTITEMS message to the list-box window; items are deleted using the LM_DELETEITEM message. Items in a list are specified with a 0-based index (beginning at the top of the list). A new list is created empty; the application initializes the list by inserting items. LM_INSERTMULTITEMS allows up to 32767 items to be inserted as a group, while LM_INSERTITEM adds items one-by-one to a list. The application specifies the text and position for each new item. It can specify an absolute-position index or one of the following predefined index values: ┌────────────────────┬────────────────────────────────────────┐ │Value │Meaning │ ├────────────────────┼────────────────────────────────────────┤ │LIT_END │Insert item at end of list. │ ├────────────────────┼────────────────────────────────────────┤ │LIT_SORTASCENDING │Insert item alphabetically ascending │ │ │into list. │ ├────────────────────┼────────────────────────────────────────┤ │LIT_SORTDESCENDING │Insert item alphabetically descending │ │ │into list. │ └────────────────────┴────────────────────────────────────────┘ If a large number of items are to be inserted into a list box at one time, use of LM_INSERTMULTITEMS is more efficient than use of LM_INSERTITEM. The same positioning flags are used. When LIT_SORTASCENDING or LIT_SORTDESCENDING is specified with LM_INSERTMULTITEMS, new items are inserted before the updated list is sorted. If items are being added using several LM_INSERTMULTITEMS messages, LIT_END should be specified for all messages except the last; this will avoid unnecessary multiple sorts of the list. If no text array is specified, empty items are inserted into the list. This is very useful for list boxes created with LS_OWNERDRAW style, which do not use text strings. The application must send an LM_DELETEITEM message and supply the absolute-position index of the item when deleting items from a list. The LM_DELETEALL message deletes all items in a list. One way an application can speed up the insertion of list items is to suspend drawing until it has finished inserting items. This is a particularly valuable approach when using a sorted insertion process (when inserting one item can cause rearrangement of the entire list). You can turn off list drawing by calling WinEnableWindowUpdate, specifying FALSE for the enable parameter, and then calling WinShowWindow. This forces a total update when insertion is complete. The following code fragment illustrates this concept: Uses Os2Def,Os2Base,Os2PmApi; Var HwndFileList : HWND; (* Сsken var tom!! *) Begin (* Disable updates while filling the list. *) WinEnableWindowUpdate(hwndFileList, Ord(False)); . . (* Send LM_INSERTITEM messages to insert all new items. *) . (* Now cause the window to update and show the new information. *) WinShowWindow(hwndFileList, Ord(True)); Notice that this optimization is unnecessary if an application is adding list items while processing a WM_INITDLG message, because the list box is not visible, and the list-box routines are internally optimized. ═══ 2.2.4. Responding to a User Selection in a List Box ═══ When a user chooses an item in a list, the primary notification an application receives is a WM_CONTROL message, with the LN_ENTER control code sent to the owner window of the list. Within the window procedure for the owner window, the application responds to the LN_ENTER control code by querying the list box for the current selection (or selections, in the case of an LS_MULTIPLESEL or LS_EXTENDEDSEL list box). The LN_ENTER control code notifies the application that the user has selected a list item. A WM_CONTROL message with an LN_SELECT control code is sent to the list-box owner whenever a selection in a list changes, such as when a user moves the mouse pointer up and down a list while pressing the mouse button. In this case, items are selected but not yet chosen. An application can ignore LN_SELECT control codes when the selection changes, responding only when the item is actually chosen. Or an application can use LN_SELECT to display context-dependent information that changes rapidly with each selection made by the user. ═══ 2.2.5. Handling Multiple Selections ═══ When a list box has the style LS_MULTIPLESEL or LS_EXTENDEDSEL, the user can select more than one item at a time. An application must use different strategies when working with these types of lists. For example, when responding to an LN_ENTER control code, it is not sufficient to send a single LM_QUERYSELECTION message, because that message will find only the first selection. To find all current selections, an application must continue sending LM_QUERYSELECTION messages, using the return index of the previous message as the starting index of the next message, until no items are returned. ═══ 2.2.6. Creating an Owner-Drawn List Item ═══ To draw its own list items, an application must create a list that has the style LS_OWNERDRAW: the owner window of the list box must respond to the WM_MEASUREITEM and WM_DRAWITEM messages. When the owner window receives a WM_MEASUREITEM message, it must return the height of the list item. All items in a list must have the same height (greater than or equal to 1). The WM_MEASUREITEM message is sent when the list box is created, and every time an item is added. You can change the item height by sending an LM_SETITEMHEIGHT message to the list-box window. The maximum width of a list box created with the LM_HORZSCROLL style can be set using an LM_SETITEMWIDTH message. The owner window receives a WM_DRAWITEM message whenever an item in an owner-drawn list should be drawn or highlighted. Although it is quite common for an owner-drawn list to draw items, it is less common to override the system-default method of highlighting. (This method inverts the rectangle that contains the item.) Do not create your own highlighting unless, for some reason, the system-default method is unacceptable to you. The WM_DRAWITEM message contains a pointer to an OWNERITEM data structure. The OWNERITEM structure contains the window identifier for the list box, a presentation-space handle, a bounding rectangle for the item, the position index for the item, and the application-defined item handle. This structure also contains two fields that determine whether a message draws, highlights, or removes the highlighting from an item. The OWNERITEM structure has the following form: Type OWNERITEM = Record Hwnd : HWND; (* Сsken var tom!! *) Hps : HPS; (* Сsken var tom!! *) FsState : ULONG; (* Сsken var tom!! *) FsAttribute : ULONG; (* Сsken var tom!! *) FsStateOld : ULONG; (* Сsken var tom!! *) FsAttributeOld : ULONG; (* Сsken var tom!! *) RclItem : RECTL; (* Сsken var tom!! *) IdItem : LONG; (* Сsken var tom!! *) HItem : ULONG; (* Сsken var tom!! *) End; When the item must be drawn, the owner window receives a WM_DRAWITEM message with the fsState field set differently from the fsStateOld field. If the owner window draws the item in response to this message, it returns TRUE, telling the system not to draw the item. If the owner window returns FALSE, the system draws the item, using the default list-item drawing method. You can get the text of a list item by sending an LM_QUERYITEMTEXT message to the list-box window. You should draw the item using the hps and rclItem arguments provided in the OWNERITEM structure. If the item being drawn is currently selected, the fsState and fsStateOld fields are both TRUE; they both will be FALSE if the item is not currently selected. The window receiving a WM_DRAWITEM message can use this information to highlight the selected item at the same time it draws the item. If the owner window highlights the item, it must leave the fsState and fsStateOld fields equal to each other. If the system provides default highlighting for the item (by inverting the item rectangle), the owner window must set the fsState field to 1 and the fsStateOld field to 0 before returning from the WM_DRAWITEM message. The owner window also receives a WM_DRAWITEM message when the highlight state of a list item changes. For example, when a user clicks an item, the highlighting must be removed from the currently selected item, and the new selection must be highlighted. If these items are owner-drawn, the owner window receives one WM_DRAWITEM message for each unhighlighted item and one message for the newly highlighted item. To highlight an item, the fsState field must equal TRUE, and the fsStateOld field must equal FALSE. In this case, the application should highlight the item and return the fsState and fsStateOld fields equal to FALSE, which tells the system not to highlight the item. The application also can return the fsState and fsStateOld fields with two different (unequal) values and the list box will highlight the item (the default action). To remove highlighting from an item, the fsState field must equal FALSE and the fsStateOld field must equal TRUE. In this case, the application removes the highlighting and returns both the fsState and the fsStateOld fields equal to FALSE. This tells the system not to attempt to remove the highlighting. The application also can return the fsState and fsStateOld fields with two different (unequal) values, and the list box will remove the highlighting (the default response). The following code fragment shows these selection processes: Uses Os2Def,Os2Base,Os2PmApi; Var poi : ^OWNERITEM; (* Сsken var tom!! *) (* Case Of *) WM_DRAWITEM: poi := mp2; (* Test to see If this is drawing or highlighting/unhighlighting. *) If (poi->.fsState <> poi->.fsStateOld) Then Begin (* This is either highlighting or unhighlighting. *) If (poi->.fsState) Then Begin . . (* Highlight the item. *) . End; Else Begin . . (* Remove the highlighting. *) . End; (* Set fsState := fsStateOld to tell system you did it. *) poi->.fsState := poi->.fsStateOld = 0; (* Return Ord(True) here, to tell list box you did the highlighting. *) Exit; End; Else Begin . . (* Draw the item. *) . If (poi->.fsState) Then Begin (* Checks to see if item is selected *) . . (* Highlight the item. *) . (* Set fsState := fsStateOld to tell system you did it. *) End; (* Return Ord(True) here, to tell list box you did the highlighting. *) Exit; (* End of case WM_DRAWITEM *) ═══ 2.2.7. Default List-Box Behavior ═══ The following table lists all the messages handled by the predefined list-box window-class procedure. ┌─────────────────────────┬───────────────────────────────────┐ │Message │Description │ ├─────────────────────────┼───────────────────────────────────┤ │LM_DELETEALL │Deletes all items in the list. │ ├─────────────────────────┼───────────────────────────────────┤ │LM_DELETEITEM │Removes the specified item from the│ │ │list, redrawing the list as │ │ │necessary. Returns the number of │ │ │items remaining in the list. │ ├─────────────────────────┼───────────────────────────────────┤ │LM_INSERTITEM │Inserts a new item into the list │ │ │according to the position │ │ │information passed with the │ │ │message. │ ├─────────────────────────┼───────────────────────────────────┤ │LM_INSERTMULTITEMS │Inserts one or more items into a │ │ │list box at one time. │ ├─────────────────────────┼───────────────────────────────────┤ │LM_QUERYITEMCOUNT │Returns the number of items in the │ │ │list. │ ├─────────────────────────┼───────────────────────────────────┤ │LM_QUERYITEMHANDLE │Returns the specified item handle. │ ├─────────────────────────┼───────────────────────────────────┤ │LM_QUERYITEMTEXT │Copies the text of the specified │ │ │item to a buffer supplied by the │ │ │message sender. │ ├─────────────────────────┼───────────────────────────────────┤ │LM_QUERYITEMTEXTLENGTH │Returns the text length of the │ │ │specified item. │ ├─────────────────────────┼───────────────────────────────────┤ │LM_QUERYSELECTION │For a single-selection list box, │ │ │returns the zero-based index of the│ │ │currently selected item. For a │ │ │multiple-selection list box, │ │ │returns the next selected item or │ │ │LIT_NONE if no more items are │ │ │selected. │ ├─────────────────────────┼───────────────────────────────────┤ │LM_QUERYTOPINDEX │Returns the zero-based index to the│ │ │item currently visible at the top │ │ │of the list. │ ├─────────────────────────┼───────────────────────────────────┤ │LM_SEARCHSTRING │Searches the list for a match to │ │ │the specified string. │ ├─────────────────────────┼───────────────────────────────────┤ │LM_SELECTITEM │Selects the specified item. If the│ │ │list is a single-selection list, │ │ │deselects the previous selection. │ │ │Sends a WM_CONTROL message (with │ │ │the LN_SELECT code) to the owner │ │ │window. │ ├─────────────────────────┼───────────────────────────────────┤ │LM_SETITEMHANDLE │Sets the specified item handle. │ ├─────────────────────────┼───────────────────────────────────┤ │LM_SETITEMHEIGHT │Sets the item height for the list. │ │ │All items in the list have the same│ │ │height. │ ├─────────────────────────┼───────────────────────────────────┤ │LM_SETITEMTEXT │Sets the text for the specified │ │ │item. │ ├─────────────────────────┼───────────────────────────────────┤ │LM_SETITEMWIDTH │Sets the maximum width of a list │ │ │box created with the LS_HORZSCROLL │ │ │style. │ ├─────────────────────────┼───────────────────────────────────┤ │LM_SETTOPINDEX │Shows the specified item as the top│ │ │item in the list window, scrolling │ │ │the list as necessary. │ ├─────────────────────────┼───────────────────────────────────┤ │WM_ADJUSTWINDOWPOS │If the list box has the style │ │ │LS_NOADJUSTPOS, makes no changes to│ │ │the SWP structure and returns │ │ │FALSE. Otherwise, adjusts the │ │ │height of the list box so that a │ │ │partial item is not shown at the │ │ │bottom of the list. Returns TRUE │ │ │if the SWP structure is changed. │ ├─────────────────────────┼───────────────────────────────────┤ │WM_BUTTON2DOWN │Returns TRUE; the message is │ │ │ignored. │ ├─────────────────────────┼───────────────────────────────────┤ │WM_BUTTON3DOWN │Returns TRUE; the message is │ │ │ignored. │ ├─────────────────────────┼───────────────────────────────────┤ │WM_CHAR │Processes virtual keys for line and│ │ │page scrolling. Sends an LN_ENTER │ │ │notification code for the Enter │ │ │key. Returns TRUE if the key is │ │ │processed; otherwise, passes the │ │ │message to the WinDefWindowProc │ │ │function. │ ├─────────────────────────┼───────────────────────────────────┤ │WM_CREATE │Creates an empty list box with a │ │ │scroll bar. │ ├─────────────────────────┼───────────────────────────────────┤ │WM_DESTROY │Destroys the list and deallocates │ │ │any memory allocated during its │ │ │existence. │ ├─────────────────────────┼───────────────────────────────────┤ │WM_ENABLE │Enables the scroll bar if there are│ │ │more items than can be displayed in│ │ │a list-box window. │ ├─────────────────────────┼───────────────────────────────────┤ │WM_MOUSEMOVE │Sets the mouse pointer to the arrow│ │ │shape and returns TRUE to show that│ │ │the message was processed. │ ├─────────────────────────┼───────────────────────────────────┤ │WM_PAINT │Draws the list box and its items. │ ├─────────────────────────┼───────────────────────────────────┤ │WM_HSCROLL │Handles scrolling indicated by the │ │ │list-box horizontal scroll bar. │ ├─────────────────────────┼───────────────────────────────────┤ │WM_VSCROLL │Handles scrolling indicated by the │ │ │list-box vertical scroll bar. │ ├─────────────────────────┼───────────────────────────────────┤ │WM_SETFOCUS │If the list box is gaining the │ │ │focus, creates a cursor and sends │ │ │an LN_SETFOCUS notification code to│ │ │the owner window. If the list box │ │ │is losing the focus, this message │ │ │destroys the cursor and sends an │ │ │LN_KILLFOCUS notification code to │ │ │the owner window. │ ├─────────────────────────┼───────────────────────────────────┤ │WM_TIMER │Uses timers to control automatic │ │ │scrolling that occurs when a user │ │ │drags the mouse pointer outside the│ │ │window. │ └─────────────────────────┴───────────────────────────────────┘ ═══ 3. Menus ═══ A menu is a window that contains a list of items-text strings, bit maps, or images drawn by the application-that enables the user, by mouse or keyboard, to choose from these predetermined choices. This chapter describes how to use menus in your PM applications. ═══ 3.1. About Menus ═══ A menu always is owned by another window, usually a frame window. When a user makes a choice from a menu, the menu posts a message containing the unique identifier for the menu item to its owner by way of the owner window's window procedure. An application typically defines its menus using Resource Compiler, and then associates the menus with a frame window when the frame window is created. Applications also can create menus by filling in menu-template data structures and creating windows with the WC_MENU class. Either way, applications can add, delete, or change menu items dynamically by issuing messages to menu windows. ═══ 3.1.1. Menu Bar and Pull-Down Menus ═══ A typical application uses a menu bar and several pull-down submenus. The pull-down submenus ordinarily are hidden, but become visible when the user makes selections in the menu bar. Pull-down submenus always are attached to the menu bar. The menu bar is a child of the frame window; the menu bar window handle is the key to communicating with the menu bar and its submenus. You can retrieve this handle by calling WinWindowFromID, with the handle of the parent window and the FID_MENU frame-control identifier. Most messages for the menu bar and its submenus can be issued to the menu-bar window. Flags in the messages tell the window whether to search submenus for requested menu items. ═══ 3.1.2. Pop-Up Menus ═══ A pop-up menu is like a pull-down submenu, except that it is not attached to the menu bar; it can appear anywhere in its parent window. A pop-up menu usually is associated with a portion of a window, such as the client window, or it is associated with a specific object, such as an icon. A pop-up menu remains hidden until the user selects it (either by moving the cursor to the appropriate location and pressing Enter or clicking on the location with the mouse). Typically, pop-up menus are displayed at the position of the cursor or mouse pointer; they provide a quick mechanism for selecting often-used menu items. To include a pop-up menu in an application, you first must define a menu resource in a resource-definition file, then load the resource using the WinLoadMenu or WinCreateMenu functions. You must call WinPopupMenu to create the pop-up menu and display it in the parent window. Applications typically call WinPopupMenu in a window procedure in response to a user-generated message, such as WM_BUTTON2DBLCLK or WM_CHAR. WinPopupMenu requires that you specify the pop-up menu's handle and also the handles of the parent and owner windows of the pop-up menu. WinLoadMenu and WinCreateMenu return the handle of the pop-up menu window, but you must obtain the handles of the parent and owner by using WinQueryWindow. You determine the position of the pop-up menu in relation to its parent by specifying coordinates and style flags in WinPopupMenu. The x and y coordinates determine the position of the lower-left corner of the menu relative to the lower-left corner of the parent. The system may adjust this position, however, if you include the PU_HCONSTRAIN or PU_VCONSTRAIN style flags in the call to WinPopupMenu. If necessary, PU_HCONSTRAIN adjusts the horizontal position of the menu so that its left and right edges are within the borders of the desktop window. PU_VCONSTRAIN makes the same adjustments vertically. Without these flags, a desktop-level pop-up menu can lie partially off the screen, with some items not visible nor selectable. The PU_POSITIONONITEM flag also can affect the position of the pop-up menu. This flag positions the pop-up menu so that, when the pop-up menu appears, the specified item lies directly under the mouse pointer. Also, PU_POSITIONONITEM automatically selects the item. PU_POSITIONONITEM is useful for placing the current menu selection under the pointer so that, if the user releases the mouse button without selecting a new item, the current selection remains unchanged. The PU_SELECTITEM flag is similar to PU_POSITIONONITEM except that it just selects the specified item; it does not affect the position of the menu. You can enable the user to choose an item from a pop-up menu by using the same mouse button that was used to display the menu. To do this, specify the PU_MOUSEBUTTONn flag, where n corresponds to the mouse button used to display the menu. This flag specifies the mouse buttons for the user to interact with a pop-up menu once it is displayed. By using the PU_MOUSEBUTTONn flag, you can enable the user to display the pop-up menu, select an item, and dismiss the menu, all in one operation. For example, if your window procedure displays the pop-up window when the user double-clicks mouse button 2, specify the PU_MOUSEBUTTON2DOWN flag in the WinPopupMenu function. Then, the user can display the menu with mouse button 2; and, while holding the button down, select an item. When the user releases the button, the item is chosen and the menu dismissed. ═══ 3.1.3. System Menu ═══ The system menu in the upper-left corner of a standard frame window is different from the menus defined by the application. The system menu is controlled and defined almost exclusively by the system; your only decision about it is whether to include it when creating a frame window. (It is unusual for a frame window not to include a system menu.) The system menu generates WM_SYSCOMMAND messages instead of WM_COMMAND messages. Most applications simply use the default behavior for WM_SYSCOMMAND messages, although applications can add, delete, and change system-menu entries. ═══ 3.1.4. Menu Items ═══ All menus can contain two main types of menu items: command items and submenu items. When the user chooses a command item, the menu immediately posts a message to the parent window. When the user selects a submenu item, the menu displays a submenu from which the user may choose another item. Since a submenu window also can contain a submenu item, submenus can originate from other submenus. When the user chooses a command item from a menu, the menu system posts a WM_COMMAND, WM_SYSCOMMAND, or WM_HELP message to the owner window, depending on the style bits of the menu item. Applications can change the attributes, style, and contents of menu items, and insert and delete items at run time, to reflect changes in the command environment. An application also can add items to or delete items from the menu bar, a pop-up menu, or a submenu. For example, an application might maintain a menu of the fonts currently available in the system. This application would use graphics programming interface (GPI) calls to determine which fonts were available and, then, insert a menu item for each font into a submenu. Furthermore, the application might set the check-mark attribute of the menu item for the currently chosen font. When the user chose a new font, the application would remove the check-mark attribute from the previous choice and add it to the new choice. ═══ 3.1.4.1. The Help Item ═══ To present a standard interface to the novice user, all applications must have a Help item in their menu bars. The Help item is defined with a particular style, attributes, and position in the menu. When the user chooses the Help item, the menu posts a WM_HELP message to the owner window, enabling the application to respond appropriately. The item should read Help, have an identifier of 0, and have the MIS_BUTTONSEPARATOR or MIS_HELP item styles. The Help menu item should be the last item in the menu template, so that it is displayed as the rightmost item in the menu bar. If an application uses the system default accelerator table, the user can select the Help item using either a mouse or the F1 key. ═══ 3.1.4.2. Menu-Item Styles ═══ All menu items have a combination of style bits that determine what kind of data the item contains and what kind of message it generates when the user selects it. For example, a menu item can have the MIS_TEXT, MIS_BITMAP, or other styles that specify the visual representation of the menu item on the screen. Other styles determine what kinds of messages the item sends to its owner and whether the owner draws the item. Menu-item styles typically do not change during program execution, but you can query and set them dynamically by sending MM_QUERYITEM and MM_SETITEM messages with the menu-item identifier to the menu-bar window. For text menu items (MIS_TEXT), an MM_SETITEMTEXT message sets the text. The MM_QUERYITEMTEXT message queries the text of the item. For non-text menu items, the hItem field of the MENUITEM structure typically contains the handle of a display object, such as a bit-map handle for MIS_BITMAP menu items. An application can draw a menu item by setting the style MIS_OWNERDRAW for the menu item. This usually is done by specifying the MIS_OWNERDRAW style for the menu item in the resource-definition file; but it also can be done at run time. When the application draws a menu item, it must respond to messages from the menu each time the item must be drawn. ═══ 3.1.4.3. Menu-Item Attributes ═══ Menu items have attributes that determine how the items are displayed and whether or not the user can choose them. An application can set and query menu-item attributes by sending MM_SETITEMATTR and MM_QUERYITEMATTR messages, with the menu-item identifier, to the menu-bar window. If the specified item is in a submenu, there are two methods of determining its attributes. The first is to send MM_SETITEMATTR and MM_QUERYITEMATTR messages to the top-level menu, specifying the identifier of the item and setting a flag so that the message searches all submenus for the item. Then, you can retrieve the handle of the menu-bar by calling WinWindowFromID, with the handle of the frame window and the FID_MENU frame-control identifier. The second method, which is more efficient if you want to either work with more than one submenu item or set the same item several times, involves two steps: 1. Send an MM_QUERYITEM message to the menu, with the identifier of the submenu. The updated MENUITEM structure contains the window handle of the submenu. 2. Send an MM_QUERYITEMATTR (or MM_SETITEMATTR) message to the submenu window, specifying the identifier of the item in the submenu. ═══ 3.1.4.4. Menu-Item Structure ═══ A single menu item is defined by the MENUITEM data structure. This structure is used with the MM_INSERTITEM message to insert items in a menu or to query and set item characteristics with the MM_QUERYITEM and MM_SETITEM messages. The MENUITEM structure has the following form: Type MENUITEM = Record (* mi *) IPosition : SHORT; (* Сsken var tom!! *) AfStyle : USHORT; (* Сsken var tom!! *) AfAttribute : USHORT; (* Сsken var tom!! *) Id : USHORT; (* Сsken var tom!! *) HwndSubMenu : HWND; (* Сsken var tom!! *) HItem : ULONG; (* Сsken var tom!! *) End; You can derive the values of most of the fields in this structure directly from the resource-definition file. However, the last field in the structure, hItem, depends on the style of the menu item. The iPosition field specifies the ordinal position of the item within its menu window. If the item is part of the menu bar, iPosition specifies its relative left-to-right position, with 0 being the leftmost item. If the item is part of a submenu, iPosition specifies its relative top-to-bottom and left-to-right positions, with 0 being the upper-left item. An item with the MIS_BREAKSEPARATOR style in a pull-down menu causes a new column to begin. The afStyle field contains the style bits of the item. The afAttribute field contains the attribute bits. The id field contains the menu-item identifier. The identifier should be unique but does not have to be. Just remember that, when multiple items have the same identifier, they post the same command number in the WM_COMMAND, WM_SYSCOMMAND, and WM_HELP messages. Also, any message that specifies a menu item with a non-unique identifier will find the first item that has that identifier. The hwndSubMenu field contains the window handle of a submenu window (if the item is a submenu item). The hwndSubMenu field is NULL for command items. The hItem field contains a handle to the display object for the item, unless the item has the MIS_TEXT style, in which case, hItem is 0. For example, a menu item with the MIS_BITMAP style has an hItem field that is equal to its bit-map handle. ═══ 3.1.5. Menu Access ═══ The OS/2 operating system is designed to work with or without a mouse or other pointing device. The system provides default behavior that enables a user to interact with menus without a mouse. Following are the keystrokes that produce this default behavior: ┌────────────────────┬────────────────────────────────────────┐ │Keystroke │Action │ ├────────────────────┼────────────────────────────────────────┤ │Alt │Toggles in and out of menu-bar mode. │ ├────────────────────┼────────────────────────────────────────┤ │Alt+Spacebar │Shows the system menu. │ ├────────────────────┼────────────────────────────────────────┤ │F10 │Backs up one level. If a submenu is │ │ │displayed, it is canceled. If no submenu│ │ │is displayed, this keystroke exits the │ │ │menu. │ ├────────────────────┼────────────────────────────────────────┤ │Shift+Esc │Shows the system menu. │ ├────────────────────┼────────────────────────────────────────┤ │Right Arrow │Cycles to the next top-level menu item. │ │ │If the selected item is at the far-left │ │ │side of the menu, the menu code sends a │ │ │WM_NEXTMENU message to the frame window.│ │ │The default processing by the frame │ │ │window is to cycle between the │ │ │application and system menus. (An │ │ │application can modify this behavior by │ │ │subclassing the frame window.) If the │ │ │selected item is in a submenu, the next │ │ │column in the submenu is selected, or │ │ │the next top-level menu item is │ │ │selected; this keystroke also can send │ │ │or process a WM_NEXTMENU message. │ ├────────────────────┼────────────────────────────────────────┤ │Left Arrow │Works like the Right Arrow key, except │ │ │in the opposite direction. In submenus, │ │ │this keystroke backs up one column, │ │ │except when the currently selected item │ │ │is in the far-left column, in which case│ │ │the previous submenu is selected. │ ├────────────────────┼────────────────────────────────────────┤ │Up Arrow or Down │When pressed in a top-level menu, │ │Arrow │activates a submenu. When pressed in a │ │ │submenu, this keystroke selects the │ │ │previous or next or item, respectively. │ ├────────────────────┼────────────────────────────────────────┤ │Enter │Activates a submenu, and highlights the │ │ │first item if an item has a submenu │ │ │associated with it; otherwise, this │ │ │keystroke chooses the item as though the│ │ │user released the mouse button while the│ │ │item was selected. │ ├────────────────────┼────────────────────────────────────────┤ │Alphabetic character│Selects the first menu item with the │ │ │specified character as its mnemonic key.│ │ │A mnemonic is defined for a menu item by│ │ │placing a tilde (~) before the character│ │ │in the menu text. If the selected item │ │ │has a submenu associated with it, the │ │ │menu is displayed, and the first item is│ │ │highlighted; otherwise, the item is │ │ │chosen. │ └────────────────────┴────────────────────────────────────────┘ An application does not support the default keyboard behavior with any unusual code; instead, the application receives a message when a menu item is chosen by the keyboard just as though it had been chosen by a mouse. ═══ 3.1.5.1. Mnemonics ═══ Adding mnemonics to menu items is one way of providing the user with keyboard access to menus. You can indicate a mnemonic keystroke for a menu item by preceding a character in the item text with a tilde, as in ~nFile. Then, the user can choose that item by pressing the mnemonic key when the menu is active. The menu bar is active when the user presses and releases the Alt key, and the first item in the menu bar is highlighted. A pop-up or pull-down menu is active when it is open. ═══ 3.1.5.2. Accelerators ═══ In addition to mnemonics, a menu item can have an associated keyboard accelerator. Accelerators are different from mnemonics in that the menu need not be active for the accelerator key to work. If you have associated a menu item with a keyboard accelerator, display the accelerator to the right of the menu item. Do this in the resource-definition file by placing a tab character (\t) in the menu text before the characters that will be displayed on the right. For example, if the Close item had the F3 function key as its keyboard accelerator, the text for the item would be Close\tF3. ═══ 3.2. Using Menus ═══ This section explains how to perform the following tasks:  Define menu items in a resource file  Include a menu bar in a standard window  Create a pop-up menu  Add a menu to a dialog window  Access the system menu  Respond to a the menu choice of a user  Set and query menu-item attributes  Add and delete menu items  Create a custom menu item ═══ 3.2.1. Defining Menu Items in a Resource File ═══ Typically, a menu resource represents the menu bar or pop-up menu and all the related submenus. A menu-item definition is organized as shown in the following code: MENUITEM item text, item identifier, item style, item attributes The menu resource-definition file specifies the text of each item in the menu, its unique identifier, its style and attributes, and whether it is a command item or a submenu item. A menu item that has no specification for style or attributes has the default style of MIS_TEXT and all attribute bits off, indicating that the item is enabled. The MIS_SEPARATOR style identifies nonselectable lines between menu items. The following figure is sample Resource Compiler source code that defines a menu resource. The code defines a menu with three submenu items in the menu bar (File, Edit, and Font) and a command item (Help). Each submenu has several command items, and the Font submenu has two other submenus within it. MENU ID_MENU_RESOURCE BEGIN SUBMENU "&tilde.File", IDM_FILE BEGIN MENUITEM "&tilde.Open...", IDM_FI_OPEN MENUITEM "&tilde.Close\tF3", IDM_FI_CLOSE, 0, MIA_DISABLED MENUITEM "&tilde.Quit", IDM_FI_QUIT MENUITEM "", IDM_FI_SEP1, MIS_SEPARATOR MENUITEM "&tilde.About Sample", IDM_FI_ABOUT END SUBMENU "&tilde.Edit", IDM_EDIT BEGIN MENUITEM "&tilde.Undo", IDM_ED_UNDO, 0, MIA_DISABLED MENUITEM "", IDM_ED_SEP1, MIS_SEPARATOR MENUITEM "&tilde.Cut", IDM_ED_CUT MENUITEM "C&tilde.opy", IDM_ED_COPY MENUITEM "&tilde.Paste", IDM_ED_PASTE MENUITEM "C&tilde.lear", IDM_ED_CLEAR END SUBMENU "Font", IDM_FONT BEGIN SUBMENU "Style", IDM_FONT_STYLE BEGIN MENUITEM "Plain", IDM_FONT_STYLE_PLAIN MENUITEM "Bold", IDM_FONT_STYLE_BOLD MENUITEM "Italic", IDM_FONT_STYLE_ITALIC END SUBMENU "Size", IDM_FONT_SIZE BEGIN MENUITEM "10", IDM_FONT_SIZE_10 MENUITEM "12", IDM_FONT_SIZE_12 MENUITEM "14", IDM_FONT_SIZE_14 END END MENUITEM "F1=Help", 0x00, MIS_TEXT Or MIS_BUTTONSEPARATOR Or MIS_HELP END To define a menu item with the MIS_BITMAP style, an application must use a tool such as Icon Editor to create a bit map, include the bit map in its resource-definition file, and define a menu in the file (as shown in the following figure). The text for the bit map menu items is an ASCII representation of the resource identifier of the bit map resource to be displayed for that item. (* Bring externally created bit maps into the resource file. *) BITMAP 101 button.bmp BITMAP 102 hirest.bmp BITMAP 103 hizoom.bmp BITMAP 104 hired.bmp (* Connect a menu item with a bit map. *) SUBMENU "&tilde.Bitmaps", IDM_BITMAP BEGIN MENUITEM "#101", IDM_BM_01, MIS_BITMAP MENUITEM "#102", IDM_BM_02, MIS_BITMAP MENUITEM "#103", IDM_BM_03, MIS_BITMAP MENUITEM "#104", IDM_BM_04, MIS_BITMAP END ═══ 3.2.2. Including a Menu Bar in a Standard Window ═══ If you have defined a menu resource in a resource-definition file, you can use the menu resource to create a menu bar in a standard window. You include the menu bar by using the FCF_MENU attribute flag and specifying the menu-resource identifier in a call to WinCreateStdWindow, as shown in the following code fragment: Uses Os2Def,Os2Base,Os2PmApi; Var HwndFrame : HWND; (* Сsken var tom!! *) SzClassName : PCHAR; (* Сsken var tom!! *) SzTitle : PCHAR; (* Сsken var tom!! *) FlControlStyle : ULONG; (* Сsken var tom!! *) Begin SzClassName := 'MyClass'; SzTitle := 'My Title'; FlControlStyle := FCF_MENU Or FCF_SIZEBORDER Or FCF_TITLEBAR Or FCF_ACCELTABLE; hwndFrame := WinCreateStdWindow(HWND_DESKTOP, WS_VISIBLE, &flControlStyle, szClassName, szTitle, 0, nil, ID_MENU_RESOURCE, nil); End. After you make this call, the operating system automatically includes the menu in the window, drawing the menu bar across the top of the window. When the user chooses an item from the menu, the menu posts the message to the frame window. The frame window passes any WM_COMMAND messages to the client window. (The frame window does not pass WM_SYSCOMMAND messages to the client window.) WM_HELP messages are posted to the focus window. The WinDefWindowProc function passes WM_HELP messages to the parent window. If a WM_HELP message is passed to a frame window, the frame window calls the HK_HELP hook. Your client window procedure must process these messages to respond to the user's actions. ═══ 3.2.3. Creating a Pop-up Menu ═══ The following code fragment shows how to make a pop-up menu appear when the user double-clicks mouse button 2 anywhere in the parent window. The menu is positioned with the mouse pointer located on the item having the IDM_OPEN identifier and is constrained horizontally and vertically. Then, the user can select an item from the pop-up menu using mouse button 2. Uses Os2Def,Os2Base,Os2PmApi; Var HwndFrame : HWND; (* Сsken var tom!! *) Function ClientWndProc( hwnd : HWND, msg : ULONG, mp1 : MPARAM, mp2 : MPARAM): MRESULT; Var HwndMenu : HWND; (* Сsken var tom!! *) FSuccess : BOOL; (* Сsken var tom!! *) Begin Case msg Of . . (* Process other messages. *) . WM_BUTTON2DBLCLK: hwndMenu := WinLoadMenu(hwnd, nil, ID_MENU_RESOURCE); fSuccess := WinPopupMenu(hwnd, hwndFrame, hwndMenu, 20, 50, IDM_OPEN, PU_POSITIONONITEM Or PU_HCONSTRAIN Or PU_VCONSTRAIN Or PU_MOUSEBUTTON2DOWN Or PU_MOUSEBUTTON2); . . . End. ═══ 3.2.4. Adding a Menu to a Dialog Window ═══ You might want to use menus in windows that were not created using the WinCreateStdWindow function. For these windows, you can load a menu resource by using the WinLoadMenu function and specifying the parent window for the menu. WinLoadMenu assigns the specified menu resource to the parent. To see the menu in the window, you must send a WM_UPDATEFRAME message to the parent after loading the menu resource. This strategy is especially useful for adding menus to a window created as a dialog window, but it can be used no matter what type of window is specified as the parent. ═══ 3.2.5. Accessing the System Menu ═══ Although most applications do not alter the system menu, you can obtain the handle of the system menu by calling WinWindowFromID with a frame-window handle (or dialog-window handle) and the identifier FID_SYSMENU. Once you have the handle of the system menu, you can access the individual menu items by using predefined constants. For example, the following code fragment shows how to disable the Close menu item in the system menu of a window: Uses Os2Def,Os2Base,Os2PmApi; Var HwndSysMenu : HWND; (* Сsken var tom!! *) HwndFrame : HWND; (* Сsken var tom!! *) Begin hwndSysMenu := WinWindowFromID(hwndFrame, FID_SYSMENU); WinSendMsg(hwndSysMenu, MM_SETITEMATTR, MPFROM2SHORT(SC_CLOSE, Ord(True)), MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED)); End. ═══ 3.2.6. Responding to a User's Menu Choice ═══ When a user chooses a menu item, the client window procedure receives a WM_COMMAND message with SHORT1FROMMP(mp1) equal to the menu identifier of the chosen item. Your application must use the menu identifier to guide its response to the choice. Typically, the code in the client window procedure resembles the following code fragment: (* Case Of *) WM_COMMAND: DoMenuCommand(hwnd, SHORT1FROMMP(mp1)); Halt(0); The function that translates the menu identifier into an action typically resembles the following code fragment: Uses Os2Def,Os2Base,Os2PmApi; Procedure DoMenuCommand( hwnd : HWND, usItemID : USHORT); Begin (* Test the menu item. *) Case usItemId Of IDM_FI_NEW: DoNew(hwnd); . . (* etc. *) . End; End. The menu window sends a WM_MENUSELECT message every time the menu selection changes. SHORT1FROMMP(mp1) contains the identifier of the item that is changing state, and SHORT2FROMMP(mp2) is a 16-bit Boolean value that describes whether or not the item is chosen; the mp2 parameter contains the handle of the menu. If the Boolean value is FALSE, the item is selected but not chosen; for example, the user may have moved the cursor or mouse pointer over the item while the button was down. An application can use this message to display Help information at the bottom of the application window. The return value is ignored. If the Boolean value is TRUE, the item is chosen-that is, the user pressed Enter or released the mouse button while an item was selected. If the application returns FALSE, the menu does not generate a WM_COMMAND, WM_SYSCOMMAND, or WM_HELP message, and the menu is not dismissed. ═══ 3.2.7. Setting and Querying Menu-Item Attributes ═══ Menu-item attributes are represented in the fAttribute field of the MENUITEM data structure. Typically, attributes are set in the resource-definition file of the menu and are changed at run time as required. Applications can use the MM_SETITEMATTR and MM_QUERYITEMATTR messages to set and query attributes for a particular menu item. One of the most common uses of these messages is to check and uncheck menu items to let the user know what option is selected currently. For example, if you have a menu item that should toggle between checked and unchecked each time the user selects it, you can use the following figure to change the checked attribute. In this example, you send an MM_QUERYITEMATTR message to the menu item to obtain its current checked attribute; then, you use the exclusive OR operator to toggle the state; and finally, you send the new attribute state back to the item using an MM_SETITEMATTR message. usAttrib := SHORT1FROMMR( WinSendMsg(hwndMenu, (* Submenu window *) MM_QUERYITEMATTR, (* Message *) itemID, (* Item identIfier *) MIA_CHECKED)); (* Attribute mask *) usAttrib := MIA_CHECKED; (* XOR to toggle checked attribute *) WinSendMsg(hwndMenu, (* Submenu window *) MM_SETITEMATTR, (* Message *) itemID, (* Item identIfier *) MPFROM2SHORT(MIA_CHECKED, usAttrib)); (* Attribute mask, value *) ═══ 3.2.8. Adding and Deleting Menu Items ═══ An application can add and delete items from its menus dynamically by sending MM_INSERTITEM and MM_DELETEITEM messages to the menu window. Any item, including those in submenus, can be deleted by sending a message to the menu window. Messages to insert items in submenus must be sent to the submenu's window (rather than to the window of the top-level menu). You can retrieve the handle of a submenu of the menu bar by sending an MM_QUERYITEM message to the menu-bar and specifying the identifier of the submenu item for the submenu, as shown in the following code fragment: (* IDM_MYMENUID is the identIfier of the submenu containing the item. *) Uses Os2Def,Os2Base,Os2PmApi; Var mi : MENUITEM; hwndMenu, hwndSubMenu, hwndPullDown,hwndFrame : HWND; Begin hwndMenu := WinWindowFromID(hwndFrame, FID_MENU); WinSendMsg(hwndMenu, (* Handle of menu bar *) MM_QUERYITEM, (* Message *) MPFROM2SHORT(IDM_MYMENUID, Ord(True)), (* Submenu identIfier *) &mi); (* Pointer to MENUITEM *) hwndPullDown := mi.hwndSubMenu; (* Handle to submenu *) Once the application has the handle of the submenu, it can insert an item by filling in a MENUITEM structure and sending an MM_INSERTITEM message to the submenu. For text-menu items, the application must send a pointer to the text string as well as to the MENUITEM structure, as shown in the following figure. Uses Os2Def,Os2Base,Os2PmApi; Var PszNewItemString : PSZ; (* Сsken var tom!! *) Begin mi.iPosition := MIT_END; mi.afStyle := MIS_TEXT; mi.afAttribute := 0; mi.id := IDM_MYMENU_FIRST; mi.hwndSubMenu := nil; mi.hItem := 0; WinSendMsg(hwndPullDown, MM_INSERTITEM, &mi, pszNewItemString); To delete an item, the application sends an MM_DELETEITEM message to the menu bar, specifying the identifier of the item to delete. For example, to clear all the items following IDM_MYMENU_FIRST in a submenu in which the items are numbered sequentially, use the following code: Uses Os2Def,Os2Base,Os2PmApi; Var UsItemNum : USHORT; (* Сsken var tom!! *) Begin (* Clear all the items in MYMENU. *) hwndMenu := WinWindowFromID(hwndFrame, FID_MENU); usItemNum := IDM_MYMENU_FIRST; While (WinSendMsg(hwndMenu, MM_DELETEITEM, MPFROM2SHORT(usItemNum, Ord(True)), nil) <> 0) Do Inc(usItemNum); Adding a complete submenu to the menu bar is a more complicated procedure than that shown in the previous examples. There are two strategies. The recommended technique is to define all possible submenus in your resource-definition file; and then, as your application runs, selectively remove and insert the submenus as needed. For example, assume that your application has a submenu that you want to be displayed only when a particular application tool is in use. You must first define the submenu as part of the main menu resource in your resource-definition file, so that the system reads in the resource menu template and creates the submenu window along with the rest of the menu. You then can remove the submenu from the menu bar, saving the title of the submenu and the MENUITEM structure that defines the submenu, as shown in the following figure: Uses Os2Def,Os2Base,Os2PmApi; Var HwndMenu, : HWND; (* Сsken var tom!! *) Mi : MENUITEM; (* Сsken var tom!! *) SzMenuTitle : Array[0..MAX_STRINGSIZE] of CHAR; (* Сsken var tom!! *) Begin (* Remove a submenu so that you can replace it later. *) (* Obtain the handle of a menu. *) hwndMenu := WinWindowFromID(WinQueryWindow(hwndClient, QW_PARENT), FID_MENU); (* Obtain information on the item to remove. *) WinSendMsg(hwndMenu, MM_QUERYITEM, MPFROM2SHORT(IDM_MENUID, Ord(True)), (* Ord(True) to search submenus *) &mi); (* Save the text for the submenu item. *) WinSendMsg(hwndMenu, MM_QUERYITEMTEXT, MPFROM2SHORT(IDM_FONT, MAX_STRINGSIZE), szMenuTitle); (* Remove the item, but retain mi and szMenuTitle. *) WinSendMsg(hwndMenu, MM_REMOVEITEM, MPFROM2SHORT(IDM_FONT, Ord(True)), nil); It is important to use the MM_REMOVEITEM message, rather than MM_DELETEITEM, to remove the item; deleting the item destroys the submenu window-removing it does not. The submenu should remain intact so that you can insert it later. To reinsert the submenu, send an MM_INSERTITEM message to the menu bar, passing the MENUITEM structure and menu title that you saved when you removed the item. The following code fragment shows how to insert a submenu that was removed by using the previous code example. (* Put the submenu back in and obtain the handle of the menu bar. *) hwndMenu := WinWindowFromID( WinQueryWindow(hwndClient, QW_PARENT), FID_MENU); (* Use the information that you saved when you removed the menu. *) WinSendMsg(hwndMenu, MM_INSERTITEM, &mi, szMenuTitle); The other technique that you can use to insert a submenu in the menu bar is to build up, in memory, a data structure as a menu template and use that template and WinCreateWindow to create a submenu. The resultant submenu window handle then is placed in the hwndSubMenu field of a MENUITEM structure, and the menu item is sent to the menu bar with an MM_INSERTITEM message. You also can create an empty submenu window by using WinCreateWindow. Pass NULL for the pCtlData and pPresParams parameters, instead of building the menu template in memory. Then insert a new menu item in the menu bar by using the MM_INSERTITEM message, setting the MIS_SUBMENU style, and putting the window handle of the created menu into the hwndSubMenu field. Then use the MM_INSERTITEM message to insert the items in the new pull-down menu. ═══ 3.2.9. Creating a Custom Menu Item ═══ Applications can customize the appearance of an individual menu item by setting the MIS_OWNERDRAW style bit for the item. The operating system sends two different messages to an application that include owner-drawn menu items: WM_MEASUREITEM and WM_DRAWITEM. Both messages include a pointer to an OWNERITEM data structure. WM_MEASUREITEM is sent only once for each owner-drawn item when the menu is initialized. The message is sent to the owner of the menu (typically, a frame window), which forwards the message to its client window. Typically, the client window procedure processes WM_MEASUREITEM by filling in the yTop and Right fields of the RECTL structure, specified by the rclItem field of this OWNERITEM structure; this specifies the size of the rectangle needed to enclose the item when it is drawn. The following code fragment responds to a WM_MEASUREITEM message. (* Case Of *) WM_MEASUREITEM: (mp2)->.rclItem.xRight := 26; (mp2)->.rclItem.yTop := 10; Halt(0); If a menu item has the MIS_OWNERDRAW style, the owner window receives a WM_DRAWITEM message every time the menu item needs to be drawn. You process this message by using the hps and rclItem fields of the OWNERITEM structure to draw the item. There are two situations in which the owner window receives a WM_DRAWITEM message:  When the item must be redrawn completely  When the item must be highlighted or have its highlight removed You can choose to handle one or both of these situations. Typically, you handle the drawing of the item. You may not want to handle the second situation, however, since the system-default behavior (inverting the bits in the item rectangle) often is acceptable. The two situations in which a WM_DRAWITEM message is received are detected by comparing the values of the fsState and fsStateOld fields of the OWNERITEM structure that is sent as part of the message. If the two fields are the same, draw the item. Before drawing the item, however, check its attributes to see whether it has the attributes MIA_CHECKED, MIA_FRAMED, or MIA_DISABLED. Then draw the item according to the attributes. For example, when the checked attribute of an owner-drawn menu item changes, the system sends a WM_DRAWITEM message to the item so that it can redraw itself and either draw or remove the check mark. If you want the system-default check mark, simply draw the item and leave the fsAttribute and fsAttributeOld fields unchanged; the system draws the check mark if necessary. If you draw the check mark yourself, clear the MIA_CHECKED bit in both fsAttribute and fsAttributeOld so that the system does not attempt to draw a check mark. In the same example, if fsAttribute and fsAttributeOld are not equal, the highlight showing that an item is selected needs to change. The MIA_HILITED bit of the fsAttribute field is set if the item needs to be highlighted and is not set if the highlight needs to be removed. If you do not want to provide your own highlighting, you should ignore any WM_DRAWITEM message in which fsAttribute and fsAttributeOld are not equal. If you do not alter these two fields, the system performs its default highlighting operation. If you want to provide your own visual cue that an item is selected, respond to a WM_DRAWITEM message in which the fsAttribute and fsAttributeOld fields are not equal by providing the cue and clearing the MIA_HILITED bit of both fields before returning from the message. Likewise, the MIA_CHECKED and MIA_FRAMED bits of fsAttribute and fsAttributeOld either can be used to perform the corresponding action or passed on, unchanged, so that the system performs the action. The following code fragment shows how to respond to a WM_DRAWITEM message when you want to draw the item and also be responsible for its highlighted state. Var Poi : POWNERITEM; (* Сsken var tom!! *) Rcl : RECTL; (* Сsken var tom!! *) Mp2 : MPARAM; (* Сsken var tom!! *) Begin (* Case Of *) WM_DRAWITEM: poi := mp2; (* * If the new attribute equals the old attribute, * redraw the entire item. *) If (poi->.fsAttribute = poi->.fsAttributeOld) Then Begin (* * Draw the item in poi->.hps and poi->.rclItem, and check the * attributes for check marks. If you produce your own check marks, * use this line of code: * * poi->.fsAttributeOld := (poi->.fsAttribute &= &tilde.MIA_CHECKED; *) End (* Else highlight the item or remove its highlight. *) Else If ((poi->.fsAttribute AND MIA_HILITED) <> (poi->.fsAttributeOld AND MIA_HILITED)) Then Begin (* * Set bits the same so that the menu window does not highlight * the item or remove its highlight. *) poi->.fsAttribute := poi->.fsAttribute AND &tilde.MIA_HILITED; poi->.fsAttributeOld := poi->.fsAttribute; End; Halt(Ord(True)); (* Ord(True) means the item is drawn. *) End; (* endcase *) Responding to WM_DRAWITEM Message ═══ 4. Messages and Message Queues ═══ The OS/2 operating system uses messages and message queues to communicate with applications and the windows belonging to those applications. This chapter explains how to create and use messages and message queues in PM applications. ═══ 4.1. About Messages and Message Queues ═══ Unlike traditional applications that take complete control of the computer's keyboard, mouse, and screen, PM applications must share these resources with other applications that are running at the same time. All applications run independently and rely on the operating system to help them manage shared resources. The operating system does this by controlling the operation of each application, communicating with each application when there is keyboard or mouse input or when an application must move and size its windows. ═══ 4.1.1. Messages ═══ A message is information, a request for information, or a request for an action to be carried out by a window in an application. The operating system, or an application, sends or posts a message to a window so that the window can use the information or respond to the request. There are three types of messages:  User-initiated  Application-initiated  System-initiated A user-initiated message is the direct result of a user action, such as selecting a menu item or pressing a key. An application-initiated message is generated by one window in the application to communicate with another window. System-initiated messages are generated by the interface as the indirect result of a user action (for example, resizing a window) or as the direct result of a system event (such as creating a window). A message that requires an immediate response from a window is sent directly to the window by passing the message data as arguments to the window procedure. The window procedure carries out the request or lets the operating system carry out default processing for the message. A message that does not require an immediate response from a window is posted (the message data is copied) to the application's message queue. The message queue is a storage area that the application creates to receive and hold its posted messages. Then, the application can retrieve a message at the appropriate time, sending it to the addressed window for processing. Every message contains a message identifier, which is a 16-bit integer that indicates the purpose of the message. When a window processes a message, it uses the message identifier to determine what to do. Every message contains a window handle, which identifies the window the message is for. The window handle is important because most message queues and window procedures serve more than one window. The window handle ensures that the application forwards the message to the proper window. A message contains two message parameters-32-bit values that specify data or the location of data that a window uses when processing the message. The meaning and value of a message parameter depend on the message. A message parameter can contain an integer, packed bit flags, a pointer to a structure that contains additional data, and so forth. Some messages do not use message parameters and, typically, set the parameters to NULL. An application always checks the message identifier to determine how to interpret the message parameters. A queue message is a QMSG data structure that contains six data items, representing the window handle, message identifier, two message parameters, message time, and mouse-pointer position. The time and position are included because most queue messages are input messages, representing keyboard or mouse input from the user. The time and position also help the application identify the context of the message. The operating system posts a queue message by filling the QMSG structure and copying it to a message queue. A window message consists of the window handle, the message identifier, and two message parameters. A window message does not include the message time and mouse-pointer position, because most window messages are requests to perform a task that is not related to the current time or mouse-pointer position. The operating system sends a window message by passing these values, as individual arguments, to a window procedure. ═══ 4.1.2. Message Queues ═══ Every PM application must have a message queue. A message queue is the only means an application has to receive input from the keyboard or mouse. Only applications that create message queues can create windows. An application creates a message queue by using the WinCreateMsgQueue function. This function returns a handle that the application can use to access the message queue. After an application creates a message queue, the system posts messages intended for windows in the application to that queue. The application can retrieve queue messages by specifying the message-queue handle in the WinGetMsg function. It also can examine messages, without retrieving them, by using the WinPeekMsg function. When an application no longer needs the message queue, it can destroy the queue by using the WinDestroyMsgQueue function. One message queue serves all the windows in a thread. This means a queue can hold messages for several windows. A message specifies the handle of the window to which it belongs so the application can forward a message easily to the appropriate window. The message loop recognizes a NULL window handle and the message is processed within the message loop rather than passed to WinDispatchMessage. See the following figure for an example of an input-message processing loop. An application that has more than one thread can create more than one message queue. The system allows one message queue for each thread. A message queue created by a thread belongs to that thread and has no connection to other queues in the application. When an application creates a window in a given thread, the system associates the window with the message queue in that thread. The system then posts all subsequent messages intended for that window to that queue. Note: The recommended way to structure PM applications is to have at least two threads and two message queues. The first thread and message queue control all the user-interface windows, and the second thread and message queue control all the object windows. Several windows can use one message queue; it is important that the message queue be large enough to hold all messages that possibly can be posted to it. An application can set the size of the message queue when it creates the queue by specifying the maximum number of messages the queue can hold. The default maximum number of messages is 10. To minimize queue size, several types of posted messages are not actually stored in a message queue. Instead, the operating system keeps a record in the queue of the message being posted and combines any information contained in the message with information from previous messages. Timer, semaphore, and paint messages are handled this way. For example, if more than one WM_PAINT message is posted, the operating system combines the update regions for each into a single update region. Although there is no actual WM_PAINT message in the queue, the operating system constructs one WM_PAINT message with the single update region when an application uses the WinGetMsg function. The operating system handles mouse and keyboard input messages differently from the way it handles other types of messages. The operating system receives all keyboard and mouse events, such as keystrokes and mouse movements, into the system message queue. The operating system converts these events into messages and posts them, one at a time, to the appropriate application message queue. The application retrieves the messages from its queue and dispatches them to the appropriate window, which processes the messages. The operating system message queue usually is large enough to hold all input messages, even if the user types or moves the mouse very quickly. If the operating system message queue does run out of space, the system ignores the most recent keyboard input (usually by beeping to indicate the input is ignored) and collects mouse motions into a WM_MOUSEMOVE message. Every message queue has a corresponding MQINFO data structure that specifies the identifiers of the process and thread that own the message queue and gives a count of the maximum number of messages the queue can receive. An application can retrieve the structure by using the WinQueryQueueInfo function. A message queue also has a current status that indicates the types of messages currently in the queue. An application can retrieve the queue status by using the WinQueryQueueStatus function. An application also can use the WinPeekMsg function to examine the contents of a message queue. WinPeekMsg checks for a specific message or range of messages in the queue and gives the application the option of removing messages from the queue. An application can call the WinQueryQueueStatus function to determine the contents of the queue before calling the WinPeekMsg or WinGetMsg function to remove a message from the queue. ═══ 4.1.3. Message Handling ═══ To handle and process messages, an application can use a message loop and the window procedure. These terms are explained in the following two sections. ═══ 4.1.3.1. Message Loops ═══ Every application with a message queue is responsible for retrieving the messages from that queue. An application can do this by using a message loop, usually in the application's main function, that retrieves messages from the message queue and dispatches them to the appropriate windows. The message loop consists of two calls: one to the WinGetMsg function; the other to the WinDispatchMsg function. The message loop has the following form: Uses Os2Def,Os2Base,Os2PmApi; Var Hab : HAB; (* Сsken var tom!! *) Qmsg : QMSG; (* Сsken var tom!! *) Begin While (WinGetMsg(hab, &qmsg, nil, 0, 0)<>0) Do WinDispatchMsg(hab, &qmsg); An application starts the message loop after creating the message queue and at least one application window. Once started, the message loop continues to retrieve messages from the message queue and to dispatch (send) them to the appropriate windows. WinDispatchMsg sends each message to the window specified by the window handle in the message. The following figure illustrates the typical routing of an input message through the operating system's and application's message loops. Mouse ───┐ ┌─── Keystrokes   ┌─├───├─┐ ├─────── System ├─────── Event (time ordered) ├─────── Queue └───├───┘ │  ┌────├───┐ │ Input │ Scancode ┌───── Router │ Translation │ └────────┘  ┌───────├──────┐ │ Message │ Accelerator │ Preprocessor │ Key Translation └───────├──────┘ ┌─ ── ─  ── ── ── ── ── ── ── ─┐ ┌───├───┐ │ ├─────── Appl Priority │ ├─────── MssgQ Ordered │ ├─────── │ └───├───┘ │ └────────┐ │  │ ┌──────├─WinGetMsgQ │  WinDispatchMsg │ │ │ │ App's │  │ Message │ Window Procedure │ Loop │ │ │ │  │ └───────────return; └─ ── ── ── ── ── ── ── ── ── ─┘ Input Message Processing Loop Only one message loop is needed for a message queue, even if the queue contains messages for more than one window. Each queue message is a QMSG structure that contains the handle of the window to which the message belongs. WinDispatchMsg always dispatches the message to the proper window. WinGetMsg retrieves messages from the queue in first-in, first-out (FIFO) order, so the messages are dispatched to windows in the same order they are received. If there are no messages in the queue, the operating system temporarily stops processing the WinGetMsg function until a message arrives. This means that processor time that, otherwise, would be spent waiting for a message can be given to the applications (or threads) that do have messages in their queues. The message loop continues to retrieve and dispatch messages until WinGetMsg retrieves a WM_QUIT message. This message causes the function to return FALSE, terminating the loop. In most cases, terminating the message loop is the first step in terminating the application. An application can terminate its own loop by posting the WM_QUIT message in its own queue. An application can modify its message loop in a variety of ways. For example, it can retrieve messages from the queue without dispatching them to a window. This is useful for applications that post messages without specifying a window. (These messages apply to the application rather than a specific window; they have NULL window handles.) Also, an application can direct the WinGetMsg function to search for specific messages, leaving other messages in the queue. This is useful for applications that temporarily need to bypass the usual FIFO order of the message queue. ═══ 4.1.3.2. Window Procedures ═══ A window procedure is a function that receives and processes all input and requests for action sent to the windows. Every window class has a window procedure; every window created using that class uses that window procedure to respond to messages. The system sends a message to the window procedure by passing the message data as arguments. The window procedure takes the appropriate action for the given message. Most window procedures check the message identifier, then use the information specified by the message parameters to carry out the request. When it has completed processing the message, the window procedure returns a message result. Each message has a particular set of possible return values. The window procedure must return the appropriate value for the processing it performed. A window procedure cannot ignore a message. If it does not process a message, it must pass the message back to the operating system for default processing. The window procedure does this by calling the WinDefWindowProc function to carry out a default action and return the message result. Then, the window procedure must return this value as its own message result. A window procedure commonly processes messages for several windows. It uses the window handle specified in the message to identify the appropriate window. Most window procedures process just a few types of messages and pass the others on to the operating system by calling WinDefWindowProc. ═══ 4.1.4. Posting and Sending Messages ═══ Any application can post and send messages. Like the operating system, an application posts a message by copying it to a message queue. It sends a message by passing the message data as arguments to a window procedure. To post and send messages, an application uses the WinPostMsg and WinSendMsg functions. An application posts a message to notify a specific window to perform a task. The WinPostMsg function creates a QMSG structure for the message and copies the message to the message queue corresponding to the given window. The application's message loop eventually retrieves the message and dispatches it to the appropriate window procedure. For example, one message commonly posted is WM_QUIT. This message terminates the application by terminating the message loop. An application sends a message to cause a specific window procedure to carry out a task immediately. The WinSendMsg function passes the message to the window procedure corresponding to the given window. The function waits until the window procedure completes processing and then returns the message result. Parent and child windows often communicate by sending messages to each other. For example, a parent window that has an entry-field control as its child window can set the text of the control by sending a message to the child window. The control can notify the parent window of changes to the text (carried out by the user) by sending messages back to the parent window. Occasionally, an application might need to send or post a message to all windows in the system. For example, if the application changes a system value, it must notify all windows about the change by sending a WM_SYSVALUECHANGED message. An application can send or post messages to any number of windows by using the WinBroadcastMsg function. The options in WinBroadcastMsg determine whether the message is sent or posted and specify the windows that will receive the message. Any thread in the application can post a message to a message queue, even if the thread has no message queue of its own. However, only a thread that has a message queue can send a message. Sending a message between threads is relatively uncommon. For one reason, sending a message is costly in terms of system performance. If an application posts a message between threads, it is likely to be a semaphore message, which permits window procedures to manage a shared resource jointly. An application can post a message without specifying a window. If the application supplies a NULL window handle when it calls the WinPostMsg function, the function posts the message to the queue associated with the current thread. The application must process the message in the message loop. This is one way to create a message that applies to the entire application instead of to a specific window. A window procedure can determine whether it is processing a message sent by another thread by using the WinInSendMsg function. This is useful when message processing depends on the origin of the message. A common programming error is to assume that the WinPostMsg function always succeeds. It fails when the message queue is full. An application should check the return value of the WinPostMsg function to see whether the message was posted. In general, if an application intends to post many messages to the queue, it should set the message queue to an appropriate size when it creates the queue. The default message-queue size is 10 messages. ═══ 4.1.5. Message Types ═══ This section describes the three types of OS/2 messages:  System-defined  Application-defined  Semaphore ═══ 4.1.5.1. System-Defined Messages ═══ There are many system-defined messages that are used to control the operations of applications and to provide input and other information for applications to process. The system sends or posts a system-defined message when it communicates with an application. An application also can send or post system-defined messages. Usually, applications use these messages to control the operation of control windows created by using preregistered window classes. Each system message has a unique message identifier and a corresponding symbolic constant. The symbolic constant, defined in the system header files, states the purpose of the message. For example, the WM_PAINT constant represents the paint message, which requests that a window paint its contents. The symbolic constants also specify the message category. System-defined messages can belong to several categories; the prefix identifies the type of window that can interpret and process the messages. The following table lists the prefixes and their related message categories: ┌───────────────┬─────────────────────────────────────────────┐ │Prefix │Message category │ ├───────────────┼─────────────────────────────────────────────┤ │BKM_ │Notebook control │ ├───────────────┼─────────────────────────────────────────────┤ │BM_ │Button control │ ├───────────────┼─────────────────────────────────────────────┤ │CBM_ │Combination-box control │ ├───────────────┼─────────────────────────────────────────────┤ │CM_ │Container control │ ├───────────────┼─────────────────────────────────────────────┤ │EM_ │Entry-field control │ ├───────────────┼─────────────────────────────────────────────┤ │LM_ │List-box control │ ├───────────────┼─────────────────────────────────────────────┤ │MLM_ │Multiple-line entry field control │ ├───────────────┼─────────────────────────────────────────────┤ │MM_ │Menu control │ ├───────────────┼─────────────────────────────────────────────┤ │SBM_ │Scroll-bar control │ ├───────────────┼─────────────────────────────────────────────┤ │SLM_ │Slider control │ ├───────────────┼─────────────────────────────────────────────┤ │SM_ │Static control │ ├───────────────┼─────────────────────────────────────────────┤ │TBM_ │Title-bar control │ ├───────────────┼─────────────────────────────────────────────┤ │VM_ │Value set control │ ├───────────────┼─────────────────────────────────────────────┤ │WM_ │General window │ └───────────────┴─────────────────────────────────────────────┘ General window messages cover a wide range of information and requests, including:  Mouse and keyboard-input  Menu- and dialog-input  Window creation and management  Dynamic data exchange (DDE) ═══ 4.1.5.2. Application-Defined Messages ═══ An application can create messages to use in its own windows. If an application does create messages, the window procedure that receives the messages must interpret them and provide the appropriate processing. The operating system reserves the message-identifier values in the range 0x0000 through 0x0FFF (the value of WM_USER - 1) for system-defined messages. Applications cannot use these values for their private messages. In addition, the operating system uses certain message values higher than WM_USER. Applications should not use these message values. A partial listing of these messages is in the following figure: From PMSTDDLG.H: Const FDM_FILTER = WM_USER+40; FDM_VALIDATE = WM_USER+41; FDM_ERROR = WM_USER+42; FNTM_FACENAMECHANGED = WM_USER+50; FNTM_POINTSIZECHANGED = WM_USER+51; FNTM_STYLECHANGED = WM_USER+52; FNTM_COLORCHANGED = WM_USER+53; FNTM_UPDATEPREVIEW = WM_USER+54; FNTM_FILTERLIST = WM_USER+55; You should scan your header files to see if other messages have been defined with values higher than WM_USER. Aside from the message values used by the operating system, values in the range $1000 (the value of WM_USER) through $BFFF are available for message identifiers, defined by an application, for use in that application. Warning: It is very important that applications do not broadcast messages in the $1000 through $BFFF range due to the risk of misinterpretation by other applications. Values in the range $C000 through $FFFF are reserved for message identifiers that an application defines and registers with the system atom table; these can be used in any application. Values above $FFFF ($00010000 through $FFFFFFFF) are reserved for future use; applications must not use messages in this range. ═══ 4.1.5.3. Semaphore Messages ═══ A semaphore message provides a way of signaling, through the message queue, the end of an event. An application uses a semaphore message the same way it uses system semaphore functions-to coordinate events by passing signals. A semaphore message often is used in conjunction with system semaphores. There are four semaphore messages: WM_SEM1 WM_SEM2 WM_SEM3 WM_SEM4. An application posts one of these messages to signal the end of a given event. The window that is waiting for the given event receives the semaphore message when the message loop retrieves and dispatches the message. Each semaphore message includes a bit flag that an application can use to uniquely identify the 32 possible semaphores for each semaphore message. The application passes the bit flag (with the appropriate bit set) as a message parameter with the message. The window procedure that receives the message then uses the bit flag to identify the semaphore. To save space, the system does not store semaphore messages in the message queue. Instead, it sets a record in the queue, indicating that the semaphore message has been received, and then combines the bit flag for the message with the bit flags from previous messages. When the window procedure eventually receives the message, the bit flag specifies each semaphore message posted since the last message was retrieved. ═══ 4.1.6. Message Priorities ═══ The WinGetMsg function retrieves messages from the message queue based on message priority. WinGetMsg retrieves messages with higher priority first. If it finds more than one message at a particular priority level, it retrieves the oldest message first. Messages have the following priorities: ┌───────────────┬─────────────────────────────────────────────┐ │Priority │Message │ ├───────────────┼─────────────────────────────────────────────┤ │1 │WM_SEM1 │ ├───────────────┼─────────────────────────────────────────────┤ │2 │Messages posted using WinPostMsg │ ├───────────────┼─────────────────────────────────────────────┤ │3 │Input messages from the keyboard or mouse │ ├───────────────┼─────────────────────────────────────────────┤ │4 │WM_SEM2 │ ├───────────────┼─────────────────────────────────────────────┤ │5 │WM_PAINT │ ├───────────────┼─────────────────────────────────────────────┤ │6 │WM_SEM3 │ ├───────────────┼─────────────────────────────────────────────┤ │7 │WM_TIMER │ ├───────────────┼─────────────────────────────────────────────┤ │8 │WM_SEM4 │ └───────────────┴─────────────────────────────────────────────┘ ═══ 4.1.7. Message Filtering ═══ An application can choose specific messages to retrieve from the message queue (and ignore other messages) by specifying a message filter with the WinGetMsg or WinPeekMsg functions. The message filter is a range of message identifiers (specified by a first and last identifier), a window handle, or both. The WinGetMsg and WinPeekMsg functions use the message filter to select the messages to retrieve from the queue. Message filtering is useful if an application needs to search ahead in the message queue for messages that have a lower priority or that arrived in the queue later than other less important messages. Any application that filters messages must ensure that a message satisfying the message filter can be posted. For example, filtering for a WM_CHAR message in a window that does not receive keyboard input prevents the WinGetMsg function from returning. Some messages, such as WM_COMMAND, are generated from other messages; filtering for them also can prevent WinGetMsg from returning. To filter for mouse, button, and DDE messages, an application can use the following constants: WM_MOUSEFIRST and WM_MOUSELAST WM_BUTTONCLICKFIRST and WM_BUTTONCLICKLAST WM_DDE_FIRST and WM_DDE_LAST. ═══ 4.2. Using Messages ═══ This section explains how to perform the following tasks:  Create a message queue and message loop  Examine the message queue  Post and send messages between windows  Broadcast a message to multiple windows  Use message macros ═══ 4.2.1. Creating a Message Queue and Message Loop ═══ An application needs a message queue and message loop to process messages for its windows. An application creates a message queue by using the WinCreateMsgQueue function. An application creates a message loop by using the WinGetMsg and WinDispatchMsg functions. The application must create and show at least one window after creating the queue but before starting the message loop. The following code fragment shows how to create a message queue and message loop: Uses Os2Def,Os2Base,Os2PmApi; Var Hab : HAB; (* Сsken var tom!! *) Var Hmq : HMQ; (* Сsken var tom!! *) Qmsg : QMSG; (* Сsken var tom!! *) HwndFrame, HwndClient : HWND; (* Сsken var tom!! *) FlFrameFlags : ULONG; (* Сsken var tom!! *) Begin FlFrameFlags := FCF_TITLEBAR Or FCF_SYSMENU Or FCF_SIZEBORDER Or FCF_MINMAX Or FCF_SHELLPOSITION Or FCF_TASKLIST; (* Initialize the application for Presentation Manager interface. *) hab = WinInitialize(0); (* Create the application message queue. *) hmq = WinCreateMsgQueue(hab, 0); (* Register the window class for your client window. *) WinRegisterClass(hab, (* Anchor block handle *) 'MyClientClass', (* Class name *) ClientWndProc, (* Window procedure *) CS_SIZEREDRAW, (* Class style *) 0); (* Extra bytes to reserve *) (* Create a main window. *) hwndFrame := WinCreateStdWindow( HWND_DESKTOP, (* Parent window handle *) WS_VISIBLE, (* Style of frame window *) &flFrameFlags, (* Frame controls *) 'MyClientClass', (* Window class for client *) nil, (* No title-bar text *) WS_VISIBLE, (* Style of client window *) nil, (* Module handle for resources *) 0, (* No resource identIfier *) &hwndClient); (* Pointer to client handle *) (* Start the message loop. *) While (WinGetMsg(hab, &qmsg, nil, 0, 0)<>0) Do WinDispatchMsg(hab, &qmsg); (*. Destroy the main window. *) WinDestroyWindow(hwndFrame); (* Destroy the message queue. *) WinDestroyMsgQueue(hmq); (* Terminate the application. *) WinTerminate(hab); End. Both the WinGetMsg and WinDispatchMsg functions take a pointer to a QMSG structure as a parameter. If a message is available, WinGetMsg copies it to the QMSG structure; WinDispatchMsg then uses the data in the structure as arguments for the window procedure. Occasionally, an application might need to process a message before dispatching it. For example, if a message is posted but the destination window is not specified (that is, the message contains a NULL window handle), the application must process the message to determine which window should receive the message. Then the WinDispatchMsg function can forward the message to the proper window. The following code fragment shows how the message loop can process messages that have NULL window handles: Uses Os2Def,Os2Base,Os2PmApi; Var Hab : HAB; (* Сsken var tom!! *) Qmsg : QMSG; (* Сsken var tom!! *) Begin While (WinGetMsg (hab, &qmsg, nil, 0, 0)<>0) Do If (qmsg.hwnd = nil) Then Begin . . (* Process the message. *) . End Else WinDispatchMsg (hab, &qmsg); End; End. ═══ 4.2.2. Examining the Message Queue ═══ An application can examine the contents of the message queue by using the WinPeekMsg or WinQueryQueueStatus function. It is useful to examine the queue if the application starts a lengthy operation that additional user input might affect, or if the application needs to look ahead in the queue to anticipate a response to user input. An application can use WinPeekMsg to check for specific messages in the message queue. This function is useful for extracting messages for a specific window from the queue. It returns immediately if there is no message in the queue. An application can use WinPeekMsg in a loop without requiring the loop to wait for a message to arrive. The following code fragment checks the queue for WM_CHAR messages: Uses Os2Def,Os2Base,Os2PmApi; Var Hab : HAB; (* Сsken var tom!! *) Qmsg : QMSG; (* Сsken var tom!! *) Begin If (WinPeekMsg(hab, &qmsg, nil, WM_CHAR, WM_CHAR, PM_NOREMOVE)) Then Begin . . (* Process the message. *) . End; An application also can use the WinQueryQueueStatus function to check for messages in the queue. This function is very fast and returns information about the kinds of messages available in the queue and which messages have been posted recently. Most applications use this function in message loops that need to be as fast as possible. ═══ 4.2.3. Posting a Message to a Window ═══ An application can use the WinPostMsg function to post a message to a window. The message goes to the window's message queue. The following code fragment posts the WM_QUIT message. Uses Os2Def,Os2Base,Os2PmApi; Var Hwnd : HWND; (* Сsken var tom!! *) Begin If (!WinPostMsg(hwnd, WM_QUIT, nil, nil)) Then Begin (* Message was not posted. *) End; The WinPostMsg function returns FALSE if the queue is full, and the message cannot be posted. ═══ 4.2.4. Sending a Message to a Window ═══ An application can use the WinSendMsg function to send a message directly to a window. An application uses this function to send messages to child windows. For example, the following code fragment sends an LM_INSERTITEM message to direct a list-box control to add an item to the end of its list: Uses Os2Def,Os2Base,Os2PmApi; Var HwndListBox : HWND; (* Сsken var tom!! *) Const szWeekday : Array[0..9] of CHAR = 'Tuesday'; Begin WinSendMsg(hwndListBox, LM_INSERTITEM, LIT_END, MPFROMP(szWeekday)); WinSendMsg calls the window's window procedure and waits for it to handle the message and return a result. An application can send a message to any window in the system, as long as the application has the handle of the target window. The message queue does not store the message; however, the thread making the call must have a message queue. ═══ 4.2.5. Broadcasting a Message ═══ An application can send a message to multiple windows by using the WinBroadcastMsg function. Often this function is used to broadcast the WM_SYSVALUECHANGED message after an application changes a system value. The following code fragment shows how to broadcast this message to all frame windows in all applications: Uses Os2Def,Os2Base,Os2PmApi; Var Hwnd : HWND; (* Сsken var tom!! *) Begin WinBroadcastMsg( hwnd, (* Window handle *) WM_SYSVALUECHANGED, (* Message identIfier *) nil, (* No message parameters *) nil, BMSG_FRAMEONLY Or BMSG_POSTQUEUE); (* All frame windows *) An application can broadcast messages to all windows, just frame windows, or just the windows in the application. ═══ 4.2.6. Using Message Macros ═══ The system header files define several macros that help create and interpret message parameters. One set of macros helps you construct message parameters. These macros are useful for sending and posting messages. For example, the following code fragment uses the MPFROMSHORT macro to convert a 16-bit integer into the 32-bit message parameter: Uses Os2Def,Os2Base,Os2PmApi; Var HwndButton : HWND; (* Сsken var tom!! *) Begin WinSendMsg(hwndButton, BM_SETCHECK, MPFROMSHORT(1), nil); End. A second set of macros helps you extract values from a message parameter. These macros are useful for handling messages in a window procedure. The following code fragment determines whether the window receiving the WM_FOCUSCHANGE message is gaining or losing the keyboard focus. The fragment uses the SHORT1FROMMP macro to extract the focus-change flag, the SHORT2FROMMP macro to extract the focus flag, and the HWNDFROMMP macro to extract the window handle. Uses Os2Def,Os2Base,Os2PmApi; Var FsFocusChange : USHORT; (* Сsken var tom!! *) Mp1, Mp2 : MPARAM; (* Сsken var tom!! *) HwndGainFocus : HWND; (* Сsken var tom!! *) Begin WM_FOCUSCHANGE: fsFocusChange := SHORT2FROMMP(mp2); (* Gets focus-change flags *) If (SHORT1FROMMP(mp2)<>0) (* Gaining or losing focus? *) hwndGainFocus := HWNDFROMMP(mp1); End. A third set of macros helps you construct a message result. These macros are useful for returning message results in a window procedure, as the following code fragment illustrates: Halt (MRFROM2SHORT(1, 2)); ═══ 5. Multiple-Line Entry Field Controls ═══ A multiple-line entry (MLE) field is a sophisticated control window that enables a user to view and edit multiple lines of text. This chapter describes how to create and use multiple-line entry field controls in PM applications. ═══ 5.1. About Multiple-Line Entry Field Controls ═══ An MLE field control gives an application the text-editing capabilities of a simple text editor. The application can create a multiple-line entry field by using WinCreateWindow or by specifying the MLE statement in a dialog-window template in a resource-definition file. ═══ 5.1.1. MLE Styles ═══ The style of an MLE field control determines how the MLE field appears and behaves. An application can specify a combination of the following styles for an MLE field: ┌────────────────────┬────────────────────────────────────────┐ │Style Name │Description │ ├────────────────────┼────────────────────────────────────────┤ │MLS_BORDER │Draws a border around the MLE field. │ ├────────────────────┼────────────────────────────────────────┤ │MLS_DISABLEUNDO │Directs the MLE control not to allow │ │ │undo actions. │ ├────────────────────┼────────────────────────────────────────┤ │MLS_HSCROLL │Adds a horizontal scroll bar to the MLE │ │ │field. The MLE control enables this │ │ │scroll bar whenever any line exceeds the│ │ │width of the MLE field. │ ├────────────────────┼────────────────────────────────────────┤ │MLS_IGNORETAB │Directs the MLE control to ignore the │ │ │Tab key. It passes the appropriate │ │ │WM_CHAR to its owner window. │ ├────────────────────┼────────────────────────────────────────┤ │MLS_LIMITVSCROLL │Displays the last MLE line at the bottom│ │ │of the screen page. When this style is │ │ │not used, the MLE control shows an empty│ │ │space between the last MLE line and the │ │ │bottom of the screen page. │ ├────────────────────┼────────────────────────────────────────┤ │MLS_READONLY │Prevents the MLE field from accepting │ │ │text from the user. This style is useful│ │ │for displaying lengthy static text in a │ │ │client or dialog window. │ ├────────────────────┼────────────────────────────────────────┤ │MLS_VSCROLL │Adds a vertical scroll bar to the MLE │ │ │field. The MLE control enables this │ │ │scroll bar whenever the number of lines │ │ │exceeds the height of the MLE field. │ ├────────────────────┼────────────────────────────────────────┤ │MLS_WORDWRAP │Automatically breaks lines that are │ │ │longer than the width of the MLE field. │ └────────────────────┴────────────────────────────────────────┘ ═══ 5.1.2. MLE Notification Codes ═══ An MLE field control sends WM_CONTROL messages containing notification codes to its owner whenever certain events occur, for example, when the user or application tries to insert too much text, or when the user uses the scroll bars. The owner window uses the notification codes either to carry out custom operations for the MLE field or to respond to errors. The MLE field control sends the MLN_HSCROLL or MLN_VSCROLL notification codes when the user enables the scroll bars so that the application can monitor the visible contents of the MLE field. The application also can monitor the contents of an MLE field by using the MLM_QUERYFIRSTCHAR message, which specifies the offset of the character in the upper-left corner of the MLE field. This represents the first MLE character that is visible to the user. To provide an alternative way of scrolling the contents of an MLE field, an application can move the character at the specified offset to the upper-left corner of an MLE field using the MLM_SETFIRSTCHAR message. The MLE field control sends an MLN_CHANGE notification code when the user changes the text in some way. This notification code is especially useful when the MLE field is in a dialog window, because the dialog procedure can use this code to determine whether it should process the contents of the MLE field. If an application does not process MLN_CHANGE notification codes, it can use the MLM_QUERYCHANGED message to determine whether the user has made changes to the MLE text. The MLM_SETCHANGED message makes the MLE field control send an MLN_CHANGE notification code with every event that occurs in the MLE field, regardless of whether the user has changed anything. This code also can be used to hide a change made by a user. ═══ 5.1.3. MLE Text Editing ═══ An MLE field contains one or more lines of text. Each line consists of one or more characters and ends with one or more characters that represent the end of the line. The end-of-line characters are determined by the format of the text. The user can type text in an MLE field when the MLE field has the focus. The application can insert text at any time by using the MLM_INSERT message and specifying the text as a null-terminated string. The MLE field control inserts the text at the cursor position or replaces the selected text. The MLE field control entry mode, insert or overstrike, determines what happens when the user inserts text. The user sets the entry mode by pressing the Insert key. The entry mode alternates each time the user presses Insert. When overstrike mode is enabled, at least one character is selected. This means that the MLM_INSERT message always replaces at least one character. If insert mode is enabled, the MLM_INSERT message replaces only those characters the user or application has selected. Otherwise, the MLE field makes room for the inserted characters by moving existing characters to the right, starting at the cursor position. The cursor position, identified by a blinking bar, is specified as a character offset relative to the beginning of the text. The user can set the cursor position by using the mouse or Arrow keys to move the blinking bar. An application can set the cursor position by using the MLM_SETSEL message, which directs the MLE field control to move the blinking bar to a given character position. The MLM_SETSEL message also can set the selection. The selection is one or more characters of text on which the MLE field control carries out an operation, such as deleting or copying. The user selects text by pressing the Shift key while moving the cursor or by pressing mouse button 1 while moving the mouse. The user also can select a word in a block of text by double-clicking on the word. An application selects text by using the MLM_SETSEL message to specify the cursor position and the anchor point. The selection is all the text between the cursor position and the anchor point. If the cursor position and anchor point are equal, there is no selection. An application can retrieve the cursor position, anchor point, or both, by using the MLM_QUERYSEL message. The user can delete characters, one at a time, by pressing the Delete key or the Backspace key. Pressing the Delete key deletes the character to the right of the cursor; pressing the Backspace key deletes the character to the left of the cursor and changes the cursor position. An application can delete one or more characters by using the MLM_DELETE message, which directs the MLE field control to delete a specified number of characters, starting at the given position. This message does not change the cursor position. An application can delete selected text by using the MLM_CLEAR message. An application can reverse the previous operation by using the MLM_UNDO message, which restores the MLE field to its previous state. This is a quick way to fix editing mistakes. However, not all operations can be undone. The application determines whether the previous operation can be undone by using the MLM_QUERYUNDO message, which returns TRUE and indicates the type of operation that can be undone. Using the MLM_RESETUNDO message, an application can prevent a subsequent MLM_UNDO message from changing the state of an MLE field. ═══ 5.1.4. MLE Text Formatting ═══ An application can retrieve the number of lines of text in an MLE field by using the MLM_QUERYLINECOUNT message and can retrieve the number of characters in the MLE field by using the MLM_QUERYTEXTLENGTH message. The amount of text and, subsequently, the number of lines to be entered in an MLE field depend on the text limit. An application sets the text limit by using the MLM_SETTEXTLIMIT message and determines the current limit by using the MLM_QUERYTEXTLIMIT message. The user cannot set the text limit. If the user types to the text limit, the MLE field control beeps and ignores any subsequent keystrokes. If the application attempts to add text beyond the limit, the MLE field control truncates the text. An application can control the length of each line in an MLE field by enabling word wrapping. When word wrapping is enabled, the MLE field control automatically breaks any line that is longer than the width of the MLE field. An application can set word wrapping by using the MLM_SETWRAP message, and it can determine whether the MLE field control is wrapping text by using the MLM_QUERYWRAP message. Word wrapping is disabled by default unless the application specifies the MLS_WORDWRAP style when creating the MLE field control. An application can set tab stops for an MLE control by using the MLM_SETTABSTOP message. Tab stops specify the maximum width of a tab character. When the user or an application inserts a tab character, the MLE field control expands the character so that it fills the space between the cursor position and the next tab stop. The MLM_SETTABSTOP message sets the distance (in pels) between tab stops, and the MLE field control provides as many tab stops as necessary, no matter how long the line gets. An application can retrieve the distance between tab stops using the MLM_QUERYTABSTOP message. An application can use the MLM_SETFORMATRECT message to set the format rectangle (MLE field). The format rectangle is used to set the horizontal and vertical limits for text. The MLE control sends a notification message to the parent window of the MLE field if text exceeds either of those limits. An application typically uses the format rectangle to provide its own word wrapping or other special text processing. An application can retrieve the current format rectangle by using the MLM_QUERYFORMATRECT message. An application can prevent the user's editing of the MLE field by setting the MLS_READONLY style in WinCreateWindow or in the MLE statement in the resource-definition file. The application also can set and query the read-only state by using the MLM_SETREADONLY and MLM_QUERYREADONLY messages, respectively. An application can set the colors and font for an MLE field by using the MLM_SETTEXTCOLOR, MLM_SETBACKCOLOR, and MLM_SETFONT messages. These messages affect all text in the MLE field. An MLE field cannot contain a mixture of fonts and colors. An application can retrieve the current values for the colors and font by using the MLM_QUERYTEXTCOLOR, MLM_QUERYBACKCOLOR, and MLM_QUERYFONT messages. To prevent scrolling within the MLE when the MLS_READONLY style bit is set, use the MLM_DISABLEREFRESH message. The keyboard and mouse input can be enabled using the MLM_ENABLEREFRESH message. ═══ 5.1.5. MLE Text Import and Export Operations ═══ An application can copy text to and from an MLE field by importing and exporting. To import text to an MLE field, an application can use the MLM_IMPORT message, which copies text from a buffer to the MLE field. To export text from an MLE field, the application can use the MLM_EXPORT message, which copies text from the MLE field to a buffer. The application uses the MLM_SETIMPORTEXPORT message to set the import and export buffers. An application can import and export text in a variety of formats. A text format, set with the MLM_FORMAT message, identifies which characters are used for the end-of-line characters. An MLE field can have the following text formats: ┌────────────────────┬────────────────────────────────────────┐ │Format Name │Description │ ├────────────────────┼────────────────────────────────────────┤ │MLFIE_CFTEXT │Exported lines end with a carriage │ │ │return/newline character pair (0x0D, │ │ │0x0A). Imported lines must end with a │ │ │newline character, carriage │ │ │return/newline character pair, or │ │ │newline/carriage return character pair. │ ├────────────────────┼────────────────────────────────────────┤ │MLFIE_NOTRANS │Imported and exported lines end with a │ │ │newline character (0x0A). │ ├────────────────────┼────────────────────────────────────────┤ │MLFIE_WINFMT │For exported lines, the carriage │ │ │return/newline character pair marks a │ │ │hard linebreak (a break entered by the │ │ │user). Two carriage-return characters │ │ │and a newline character (0x0D, 0x0D, │ │ │0x0A) mark a soft linebreak (a break │ │ │inserted during word wrapping and not │ │ │entered by the user). For imported │ │ │lines, the extra carriage-return in soft│ │ │linebreak characters is ignored. │ └────────────────────┴────────────────────────────────────────┘ The text format can affect the number of characters in a selection. To ensure that the export buffer is large enough to hold exported text, an application can send the MLM_QUERYFORMATLINELENGTH message. The application can send the MLM_QUERYFORMATTEXTLENGTH message to determine the number of bytes in the text to be exported. Each time an application inserts text in an MLE field, the MLE field control automatically refreshes (repaints) the display by drawing the new text. When an application copies large amounts of text to an MLE field, refreshing can be quite time-consuming, so the application should disable the refresh state. The application disables the refresh state by sending the MLM_DISABLEREFRESH message. After copying all the text, the application can restore the refresh state by sending the MLM_ENABLEREFRESH message. ═══ 5.1.6. MLE Cut, Copy, and Paste Operations ═══ The user can cut, copy, and paste text in an MLE field by using the Shift+Delete, Ctrl+Insert, and Shift+Insert key combinations, respectively. An application-either by itself or in response to the user-can cut, copy, and paste text by using the MLM_CUT, MLM_COPY, and MLM_PASTE messages. The MLM_CUT and MLM_COPY messages copy the selected text to the clipboard. The MLM_CUT message also deletes the text from the MLE field; MLM_COPY does not. The MLM_PASTE message copies the text from the clipboard to the current position in the MLE field, replacing any existing text with the copied text. An application can delete the selected text without copying it to the clipboard by using the MLM_CLEAR message. An application also can copy the selected text from an MLE field to a buffer by using the MLM_QUERYSELTEXT message. This message does not affect the contents of the clipboard. ═══ 5.1.7. MLE Search and Replace Operations ═══ An application can search for a specified string within MLE field text by using the MLM_SEARCH message, which searches for the string. The MLE field control returns TRUE if the string is found. The cursor does not move to the string unless the message specifies the MLFSEARCH_SELECTMATCH option. An application also can use the MLM_SEARCH message to replace one string with another. If the message specifies the MLFSEARCH_CHANGEALL option, the MLE field control replaces all occurrences of the search string with the replacement string. Both the search string and the replacement string must be specified in an MLE_SEARCHDATA data structure passed with the message. ═══ 5.1.8. MLE Colors ═══ For version 3, or lower, of the OS/2 operating system, MLE supports indexed (solid) colors only; it does not support dithered (RGB) colors. For versions, higher than version 3, of the OS/2 operating system, MLE supports RGB colors. Indexed colors are changed to the closest RGB color representation. ═══ 5.2. Using Multiple-Line Entry Field Controls ═══ This section explains how to create an MLE field control by using WinCreateWindow and by specifying the MLE statement in a dialog template in a resource-definition file. ═══ 5.2.1. Creating an MLE ═══ The following sample code fragment shows how to create an MLE by using WinCreateWindow: Uses Os2Def,Os2Base,Os2PmApi; Const MLE_WINDOW_ID = 2; Var HwndParent : HWND; (* Сsken var tom!! *) HwndMLE : HWND; (* Сsken var tom!! *) Begin hwndMLE := WinCreateWindow( hwndParent, (* Parent window *) WC_MLE, (* Window class *) 'Test', (* Initial text *) WS_VISIBLE Or (* Window style *) MLS_BORDER, (* Window style *) 100, 100, (* x and y positions *) 100, 100, (* Width and height *) hwndParent, (* Owner window *) HWND_TOP, (* Top of z-order *) MLE_WINDOW_ID, (* IdentIfier *) nil, (* Control data *) nil); (* Presparam *) End. It also is common to create an MLE field control by using an MLE statement in a dialog-window template in a resource file, as shown in the following code fragment: MLE "", IDD_MLETEXT, 110, 10, 50, 100, WS_VISIBLE &vbar. MLS_BORDER &vbar. MLS_WORDWRAP The predefined class for an MLE control is WC_MLE. If you do not specify a style for the MLE control, the default styles used are MLS_BORDER, WS_GROUP, and WS_TABSTOP. ═══ 5.2.2. Importing and Exporting MLE Text ═══ Importing and exporting MLE text takes place through a buffer. An import operation copies text from the buffer to the MLE field; an export operation copies text from the MLE to the buffer. Before an application can import or export MLE text, it must send an MLM_SETIMPORTEXPORT message to the MLE field control, specifying the address and size of the buffer. For version 3, or lower, of the OS/2 operating system the maximum size of import/export buffer is 64K. Once the data is into the buffer, the data is manipulated (verified for carriage returns, line feeds and so forth), and is finally placed in the MLE's memory. ═══ 5.2.2.1. Importing MLE Text ═══ To import text, an application sends the MLM_IMPORT message to the MLE field control. This message requires two parameters: plOffset and cbCopy. The plOffset parameter is a pointer to a variable that specifies the position in the MLE field where the text from the buffer is to be placed. The position is an offset from the beginning of the MLE text, that is, the number of characters from the beginning of the MLE text. If plOffset points to a variable that equals -1, the MLE field control places the text starting at the current cursor position. On return, this variable contains the offset to the first character beyond the imported text. The cbCopy parameter of the MLM_IMPORT message points to a variable that specifies the number of bytes to import. The following criterias apply when importing MLE text:  If the text ends by a line feed (LF), the import logic generates a blank line.  If the text ends by a carriage return (CR), MLE prevents a line break (LB) but flags the condition.  If the plOffset field points to the current cursor position (-1) and the import text contains a LF: - If the MLE text is imported before the text being edited, then the cursor does not move and the text being edited is shifted down to make room for the text being imported. - If the MLE text is imported after the text being edited, then the cursor does not move and the text being imported is inserted starting at the current cursor position.  If the plOffset field points to the current cursor position (-1) and the import text does not contain a LF: - If the MLE text is imported before the text being edited, then the cursor does not move and the text being edited is shifted to the right to make room for the text being imported. - If the MLE text is imported after the text being edited, then the cursor does not move and the text being imported is inserted starting at the current cursor position. ═══ 5.2.2.2. Exporting MLE Text ═══ Before using the MLM_EXPORT message the number of characters to export needs to be determined. The MLM_QUERYFORMATTEXTLENGTH message is used to determine the number of characters to be copied from the MLE to the buffer (including LF and CR) and to allocate the room in the buffer. MLM_EXPORT is then used to export the MLE text into the buffer. Note: The MLM_QUERYTEXTLENGTH message does not consider the CR and LF characters as the MLM_QUERYFORMATTEXTLENGTH message does. The following code fragment reads text from a file to a buffer, then imports the text to an MLE field: Uses Os2Def,Os2Base,Os2PmApi; Var HwndMle : HWND; (* Сsken var tom!! *) SzMleBuf : Array[0..511] of CHAR; (* Сsken var tom!! *) LOffset : IPT; (* Сsken var tom!! *) PszTextFile : PSZ; (* Сsken var tom!! *) Hf : HFILE; (* Сsken var tom!! *) CbCopied : ULONG; (* Сsken var tom!! *) UlAction : ULONG; (* Сsken var tom!! *) CbBytesRead : ULONG; (* Сsken var tom!! *) Begin LOffset := 0; (* Obtain a file name from the user *) (* Open the file *) DosOpen(pszTextFile, &hf, &ulAction, 0, FILE_NORMAL, FILE_OPEN Or FILE_CREATE, OPEN_ACCESS_READONLY Or OPEN_SHARE_DENYNONE, nil); (* Zero-fill the buffer using memset, a C run-time function *) memset(szMleBuf, 0, sizeof(szMleBuf)); (* Set the MLE import-export buffer *) WinSendMsg(hwndMle, MLM_SETIMPORTEXPORT, MPFROMP(szMleBuf), MPFROMSHORT( sizeof(szMleBuf))); (**********************************************************************) (* Read the text from the file to the buffer, *) (* then import it to the MLE. *) (**********************************************************************) Repeat DosRead(hf, szMleBuf, sizeof(szMleBuf), &cbBytesRead); cbCopied := WinSendMsg(hwndMle, MLM_IMPORT, MPFROMP( &lOffset), MPFROMP(&cbBytesRead)); Until cbCopied=0; (* Close the file *) DosClose(hf); End. To export MLE text, an application sends the MLM_EXPORT message to the MLE control. Like MLM_IMPORT, the MLM_EXPORT message takes the plOffset and cbCopy parameters. The plOffset parameter is a pointer to a variable that specifies the offset to the first character to export. A value of -1 specifies the current cursor position. On return, the variable contains the offset to the first character in the MLE field not copied to the buffer. The cbCopy parameter is a pointer to a variable that specifies the number of bytes to export. On return, this variable equals 0 if the number of characters actually copied does not exceed the number specified to be copied. The following code fragment shows how to export text from an MLE field, then store the text in a file: Uses Os2Def,Os2Base,Os2PmApi; Var HwndMle : HWND; (* Сsken var tom!! *) SzMleBuf : Array[0..511] of CHAR; (* Сsken var tom!! *) LOffset : IPT; (* Сsken var tom!! *) PszTextFile : PSZ; (* Сsken var tom!! *) Hf : HFILE; (* Сsken var tom!! *) CbCopied : ULONG; (* Сsken var tom!! *) UlAction : ULONG; (* Сsken var tom!! *) CbBytesWritten : ULONG; (* Сsken var tom!! *) CbCopy : ULONG; (* Сsken var tom!! *) Begin LOffset := 0; (* Zero-fill the buffer using memset, a C run-time function *) FilChar(szMleBuf, sizeof(szMleBuf),0); (* Set the MLE import-export buffer *) WinSendMsg(hwndMle, MLM_SETIMPORTEXPORT, MPFROMP(szMleBuf), MPFROMSHORT (sizeof(szMleBuf))); . . . (* Obtain a filename from the user *) . . . (* Open the file *) DosOpen(pszTextFile, &hf, &ulAction, 0, FILE_NORMAL, FILE_OPEN Or FILE_CREATE, OPEN_ACCESS_WRITEONLY Or OPEN_SHARE_DENYNONE, nil); (* Find out how much text is in the MLE *) cbCopy := WinSendMsg(hwndMle, MLM_QUERYFORMATTEXTLENGTH, MPFROMLONG(lOffset), MPFROMLONG((-1))); (* Copy the MLE text to the buffer *) cbCopied := WinSendMsg(hwndMle, MLM_EXPORT, MPFROMP(&lOffset), MPFROMP(&cbCopy)); (* Write the contents of the buffer to the file *) DosWrite(hf, szMleBuf, sizeof(szMleBuf), &cbBytesWritten); (* Close the file *) DosClose(hf); End. ═══ 5.2.3. Searching MLE Text ═══ An application uses the MLM_SEARCH message and the MLE_SEARCHDATA data structure to search for strings in MLE text. The first parameter of the MLM_SEARCH message is an array of flags that specify the style of the search. The application can set the MLFSEARCH_CASESENSITIVE flag if a case-sensitive search is required. If the application sets the MLFSEARCH_SELECTMATCH flag, the MLE field control highlights a matching string and, if necessary, scrolls the string into view. An application can use the MLFSEARCH_CHANGEALL flag to replace every occurrence of the string with the string specified in the pchReplace member of the MLE_SEARCHDATA data structure. The second parameter of the MLM_SEARCH message is a pointer to an MLE_SEARCHDATA data structure that contains information required to perform the search operation. This data structure includes a pointer to the string and, if the MLFSEARCH_CHANGEALL flag is set in the MLM_SEARCH message, a pointer to the replacement string. The iptStart and iptStop members specify the starting and ending positions of the search. These positions are specified as offsets from the beginning of the MLE field. A value of -1 in the iptStart member causes the search to start at the current cursor position. A negative value in the iptStop member causes the search to end at the end of the MLE field. If a matching string is found, the MLE field control returns the length of the string in the cchFound member. The following code fragment uses an entry field to obtain a search string from the user, then searches an MLE field for an occurrence of the string. The search begins at the current cursor position and ends at the end of the MLE text. When the MLFSEARCH_SELECTMATCH flag is specified, the MLE field control highlights a matching string and scrolls it into view. The following code fragment shows how to search MLE text: Uses Os2Def,Os2Base,Os2PmApi; Const IDD_SEARCHFIELD = 101; Var Hwnd : HWND; (* Сsken var tom!! *) HwndEntryFld : HWND; (* Сsken var tom!! *) HwndMle : HWND; (* Сsken var tom!! *) mlesrch : MLE_SEARCHDATA; SzSearchString : Array[0..63] of CHAR; (* Сsken var tom!! *) Begin (* Obtain the handle of the entry field containing the search string *) hwndEntryFld := WinWindowFromID(hwnd, IDD_SEARCHFIELD); (* Obtain the search string from the entry field *) WinQueryWindowText(hwndEntryFld, sizeof(szSearchString), szSearchString); (* Fill the MLE_SEARCHDATA data structure *) mlesrch.cb := sizeof(mlesrch); (* Structure size *) mlesrch.pchFind := szSearchString; (* Search string *) mlesrch.pchReplace := nil; (* No replacement string *) mlesrch.cchFind := 0; (* Not used *) mlesrch.cchReplace := 0; (* Not used *) mlesrch.iptStart := -1; (* Start at cursor position *) mlesrch.iptStop := -1; (* Stop at end of file *) (* Start the search operation *) WinSendMsg(hwndMle, MLM_SEARCH, MPFROMLONG(MLFSEARCH_SELECTMATCH), MPFROMP(&mlesrch)); End. ═══ 6. Mouse and Keyboard Input ═══ An OS/2 Presentation Manager application can accept input from both a mouse (or other pointing device) and the keyboard. This chapter explains how these input events should be received and processed. ═══ 6.1. About Mouse and Keyboard Input ═══ Only one window at a time can receive keyboard input, and only one window at a time can receive mouse input; but they do not have to be the same window. All keyboard input goes to the window with the input focus, and, normally, all mouse input goes to the window under the mouse pointer. ═══ 6.1.1. System Message Queue ═══ The operating system routes all keystrokes and mouse input to the system message queue, converting these input events into messages, and posts them, one at a time, to the proper application-defined message queues. An application retrieves messages from its queue and dispatches them to the appropriate window procedures, which process the messages. Mouse and keyboard input events in the system message queue are strictly ordered so that a new event cannot be processed until all previous events are fully processed: the system cannot determine the destination window of an input event until then. For example, if a user types a command in one window, clicks the mouse to activate another window, then types a command in the second window, the destination of the second command depends on how the application handles the mouse click. The second command would go to the second window only if that window became active as a result of the mouse click. It is important for an application to process all messages quickly to avoid slowing user interaction with the system. A message must be responded to immediately in the current thread, but the processing it initiates should be done asynchronously in another thread that has no windows in the desktop tree. The OS/2 operating system can display multiple windows belonging to several applications at the same time. To manage input among these windows, the system uses the concepts of window activation and keyboard focus. ═══ 6.1.2. Window Activation ═══ Although the operating system can display windows from many different applications simultaneously during a PM session, the user can interact with only one application at a time-the active application. The other applications continue to run, but they cannot receive user input until they become active. To enable the user to easily identify the active application, the system activates all frames in the tree between HWND_DESKTOP and the window with input focus. That is, the system positions the active frame window above all other top-level windows on the screen. If the active window is a standard frame window, the window's title bar and sizing border are highlighted. The user can control which application is active by clicking on a window or by pressing the Alt+Tab or Alt+Esc key combinations. An application can set the active frame window by calling WinSetActiveWindow; it also can obtain the handle of the active frame window by using WinQueryActiveWindow. When one window is deactivated and another activated, the system sends a WM_ACTIVATE message, first to the window being deactivated, then to the window being activated. The fActive parameter of the WM_ACTIVATE message is set to FALSE for the window being deactivated and set to TRUE for the window being activated. An application can use this message to track the activation state of a client window. ═══ 6.1.3. Keyboard Focus ═══ The keyboard focus is a temporary attribute of a window; the window that has the keyboard focus receives all keyboard input until the focus changes to a different window. The system converts keyboard input events into WM_CHAR messages and posts them to the message queue of the window that has the keyboard focus. An application can set the keyboard focus to a particular window by calling WinSetFocus. If the application does not use WinSetFocus to explicitly set the keyboard-focus window, the system sets the focus to the active frame window. The following events occur when an application uses WinSetFocus to shift the keyboard focus from one window (the original window) to another (the new window): 1. The system sends the original window a WM_SETFOCUS message (with the fFocus parameter set to FALSE), indicating that that window has lost the keyboard focus. 2. The system then sends the original window a WM_SETSELECTION message, indicating that the window should remove the highlight from the current selection. 3. If the original (frame) window is being deactivated, the system sends it a WM_ACTIVATE message (with the fActive parameter set to FALSE), indicating that the window is no longer active. 4. The system then sends the new application a WM_ACTIVATE message (with fActive set to TRUE), indicating that the new application is now active. 5. If the new (main) window is being activated, the system sends it a WM_ACTIVATE message (with fActive set to TRUE), indicating that the main window is now active. 6. The system sends the new window a WM_SETSELECTION message, indicating that the window should highlight the current selection. 7. Finally, the system sends the new window a WM_SETFOCUS message (with fFocus set to TRUE), indicating that the new window has the keyboard focus. If, while processing a WM_SETFOCUS message, an application calls WinQueryActiveWindow, that function returns the handle of the previously-active window until the application establishes a new active window. Similarly, if the application, while processing WM_SETFOCUS, calls WinQueryFocus, that function returns the handle of the previous keyboard-focus window until the application establishes a new keyboard-focus window. In other words, even though the system has sent WM_ACTIVATE and WM_SETFOCUS messages (with the fActive and fFocus parameters set to FALSE) to the previous windows, those windows are considered the active and focus windows until the system establishes new active and focus windows. If the application calls WinSetFocus while processing a WM_ACTIVATE message, the system does not send a WM_SETFOCUS message (with fFocus set to FALSE), because no window has the focus. A client window receives a WM_ACTIVATE message when its parent frame window is being activated or deactivated. The activation or deactivation message usually is followed by a WM_SETFOCUS message that specifies whether the client window is gaining or losing the keyboard focus. Therefore, if the client window needs to change the keyboard focus, it should do so during the WM_SETFOCUS message, not during the WM_ACTIVATE message. ═══ 6.1.4. Keyboard Messages ═══ The system sends keyboard input events as WM_CHAR messages to the message queue of the keyboard-focus window. If no window has the keyboard focus, the system posts WM_CHAR messages to the message queue of the active frame window. Following are two typical situations in which an application receives WM_CHAR messages: An application has a client window or custom control window, either of which can have the keyboard focus. If the window procedure for the client or control window does not process WM_CHAR messages, it should pass them to WinDefWindowProc, which will pass them to the owner. Dialog control windows, in particular, should pass unprocessed WM_CHAR messages to the WinDefDlgProc function, because this is how the user interface implements control processing for the Tab and Arrow keys. An application window owns a control window whose window procedure can handle some, but not all, WM_CHAR messages. This is common in dialog windows. If the window procedure of a control in a dialog window cannot process a WM_CHAR message, the procedure can pass the message to the WinDefDlgProc function. This function sends the message to the control window's owner, which usually is a dialog frame window. The application's dialog procedure then receives the WM_CHAR message. This also is the case when an application client window owns a control window. A WM_CHAR message can represent a key-down or key-up transition. It might contain a character code, virtual-key code, or scan code. This message also contains information about the state of the Shift, Ctrl, and Alt keys. Each time a user presses a key, at least two WM_CHAR messages are generated: one when the key is pressed, and one when the key is released. If the user holds down the key long enough to trigger the keyboard repeat, multiple WM_CHAR key-down messages are generated. If the keyboard repeats faster than the application can retrieve the input events from its message queue, the system combines repeating character events into one WM_CHAR message and increments a count byte that indicates the number of keystrokes represented by the message. Generally, this byte is set to 1, but an application should check each WM_CHAR message to avoid missing any keystrokes. An application can ignore the repeat count. For example, an application might ignore the repeat count on Arrow keys to prevent the cursor from skipping characters when the system is slow. ═══ 6.1.4.1. Message Flags ═══ Applications decode WM_CHAR messages by examining individual bits in the flag word contained in the first message parameter (mp1) that the system passes with every WM_CHAR message. The type of flag word indicates the nature of the message. The system can set the bits in the flag word in various combinations. For example, a WM_CHAR message can have the KC_CHAR, KC_SCANCODE, and KC_SHIFT attribute bits all set at the same time. An application can use the following list of flag values to test the flag word and determine the nature of a WM_CHAR message: ┌───────────────┬─────────────────────────────────────────────┐ │Flag Name │Description │ ├───────────────┼─────────────────────────────────────────────┤ │KC_ALT │Indicates that the Alt key was down when the │ │ │message was generated. │ ├───────────────┼─────────────────────────────────────────────┤ │KC_CHAR │Indicates that the message contains a valid │ │ │character code for a key, typically an ASCII │ │ │character code. │ ├───────────────┼─────────────────────────────────────────────┤ │KC_COMPOSITE │In combination with the KC_CHAR flag, this │ │ │flag indicates that the character code is a │ │ │combination of the key that was pressed and │ │ │the previous dead key. This flag is used to │ │ │create characters with diacritical marks. │ ├───────────────┼─────────────────────────────────────────────┤ │KC_CTRL │Indicates that the Ctrl key was down when the│ │ │message was generated. │ ├───────────────┼─────────────────────────────────────────────┤ │KC_DEADKEY │In combination with the KC_CHAR flag, this │ │ │flag indicates that the character code │ │ │represents a dead-key glyph (such as an │ │ │accent). An application displays the │ │ │dead-key glyph and does not advance the │ │ │cursor. Typically, the next WM_CHAR message │ │ │is a KC_COMPOSITE message, containing the │ │ │glyph associated with the dead key. │ ├───────────────┼─────────────────────────────────────────────┤ │KC_INVALIDCHAR │Indicates that the character is not valid for│ │ │the current translation tables. │ ├───────────────┼─────────────────────────────────────────────┤ │KC_INVALIDCOMP │Indicates that the character code is not │ │ │valid in combination with the previous dead │ │ │key. │ ├───────────────┼─────────────────────────────────────────────┤ │KC_KEYUP │Indicates that the message was generated when│ │ │the user released the key. If this flag is │ │ │clear, the message was generated when the │ │ │user pressed the key. An application can use│ │ │this flag to determine key-down and key-up │ │ │events. │ ├───────────────┼─────────────────────────────────────────────┤ │KC_LONEKEY │In combination with the KC_KEYUP flag, this │ │ │flag indicates that the user pressed no other│ │ │key while this key was down. │ ├───────────────┼─────────────────────────────────────────────┤ │KC_PREVDOWN │In combination with the KC_VIRTUALKEY flag, │ │ │this flag indicates that the virtual key was │ │ │pressed previously. If this flag is clear, │ │ │the virtual key was not previously pressed. │ ├───────────────┼─────────────────────────────────────────────┤ │KC_SCANCODE │Indicates that the message contains a valid │ │ │scan code generated by the keyboard when the │ │ │user pressed the key. The system uses the │ │ │scan code to identify the character code in │ │ │the current code page; therefore, most │ │ │applications do not need the scan code unless│ │ │they cannot identify the key that the user │ │ │pressed. WM_CHAR messages generated by user │ │ │keyboard input generally have a valid scan │ │ │code, but WM_CHAR messages posted to the │ │ │queue by other applications might not contain│ │ │a scan code. │ ├───────────────┼─────────────────────────────────────────────┤ │KC_SHIFT │Indicates that the Shift key was down when │ │ │the message was generated. │ ├───────────────┼─────────────────────────────────────────────┤ │KC_TOGGLE │Toggles on and off every time the user │ │ │presses a specified key. This is important │ │ │for keys like NumLock, which have an on or │ │ │off state. │ ├───────────────┼─────────────────────────────────────────────┤ │KC_VIRTUALKEY │Indicates that the message contains a valid │ │ │virtual-key code for a key. Virtual keys │ │ │typically correspond to function keys. │ │ │For those using hooks, when this bit is set, │ │ │KC_SCANCODE should usually be set as well. │ └───────────────┴─────────────────────────────────────────────┘ The mp1 and mp2 parameters of the WM_CHAR message contain information describing the nature of a keyboard input event, as follows:  SHORT1FROMMP (mp1) contains the flag word.  CHAR3FROMMP (mp1) contains the key-repeat count.  CHAR4FROMMP (mp1) contains the scan code.  SHORT1FROMMP (mp2) contains the character code.  SHORT2FROMMP (mp2) contains the virtual key code. An application window procedure should return TRUE if it processes a particular WM_CHAR message or FALSE if it does not. Typically, applications respond to key-down events and ignore key-up events. The following sections describe the different types of WM_CHAR messages. Generally, an application decodes these messages by creating layers of conditional statements that discriminate among the different combinations of flag and code attributes that can occur in a keyboard message. ═══ 6.1.4.2. Key-Down or Key-Up Events ═══ Typically, the first attribute that an application checks in a WM_CHAR message is the key-down or key-up event. If the KC_KEYUP bit of the flags word is set, the message is from a key-up event. If the flag is clear, the message is from a key-down event. ═══ 6.1.4.3. Repeat-Count Events ═══ An application can check the key-repeat count of a WM_CHAR message to determine whether the message represents more than 1 keystroke. The count is greater than 1 if the keyboard is sending characters to the system queue faster than the application can retrieve them. If the system queue fills up, the system combines consecutive keyboard input events for each key into a single WM_CHAR message, with the key-repeat count set to the number of combined events. ═══ 6.1.4.4. Character Codes ═══ The most typical use of WM_CHAR messages is to extract a character code from the message and display the character on the screen. When the KC_CHAR flag is set in the WM_CHAR message, the low word of mp2 contains a character code based on the current code page. Generally, this value is a character code (typically, an ASCII code) for the key that was pressed. ═══ 6.1.4.5. Virtual-Key Codes ═══ WM_CHAR messages often contain virtual-key codes that correspond to various function keys and direction keys on a typical keyboard. These keys do not correspond to any particular glyph code but are used to initiate operations. When the KC_VIRTUALKEY flag is set in the flag word of a WM_CHAR message, the high word of mp2 contains a virtual-key code for the key. Note: Some keys, such as the Enter key, have both a valid character code and a virtual-key code. WM_CHAR messages for these keys will contain character codes for both newline characters (ASCII 11) and virtual-key codes (VK_ENTER). ═══ 6.1.4.6. Scan Codes ═══ A third possible value in a WM_CHAR message is the scan code of the key that was pressed. The scan code represents the value that the keyboard hardware generates when the user presses a key. An application can use the scan code to identify the physical key pressed, as opposed to the character code represented by the same key. ═══ 6.1.4.7. Accelerator-Table Entries ═══ The system checks all incoming keyboard messages to see whether they match any existing accelerator-table entries (in either the system message queue or the application message queue). The system first checks the accelerator table associated with the active frame window; if it does not find a match, the system uses the accelerator table associated with the message queues. If the keyboard input event corresponds to an accelerator-table entry, the system changes the WM_CHAR message to a WM_COMMAND, WM_SYSCOMMAND, or WM_HELP message, depending on the attributes of the accelerator table. If the keyboard input event does not correspond to an accelerator-table entry, the system passes the WM_CHAR message to the keyboard-focus window. Applications should use accelerator tables to implement keyboard shortcuts rather than translate command keystrokes. For example, if an application uses the F2 key to save a document, the application should create a keyboard accelerator entry for the F2 virtual key so that, when pressed, the F2 key generates a WM_COMMAND message rather than a WM_CHAR message. ═══ 6.1.5. Mouse Messages ═══ Mouse messages occur when a user presses or releases one of the mouse buttons (a click) and when the mouse moves. All mouse messages contain the x and y coordinates of the mouse-pointer hot spot (relative to the coordinates of the window receiving the message) at the time the event occurs. The mouse-pointer hot spot is the location in the mouse-pointer bit map that the system tracks and recognizes as the position of the mouse pointer. If a window has the CS_HITTEST style, the system sends the window a WM_HITTEST message when the window is about to receive a mouse message. Most applications pass WM_HITTEST messages on to WinDefWindowProc by default, so disabled windows do not receive mouse messages. Windows that specifically respond to WM_HITTEST messages can change this default behavior. If the window is enabled and should receive the mouse message, the WinDefWindowProc function (using the default processing for WM_HITTEST) returns the value HT_NORMAL. If the window is disabled, WinDefWindowProc returns HT_ERROR, in which case the window does not receive the mouse message. The default window procedure processes the WM_HITTEST message and the usHit parameter in the WM_MOUSEMOVE message. Therefore, unless an application needs to return special values for the WM_HITTEST message or the usHit parameter, it can ignore them. One possible reason for processing the WM_HITTEST message is for the application to react differently to a mouse click in a disabled window. The contents of the mouse-message parameters (mp1 and mp2) are as follows:  SHORT1FROMMP (mp1) contains the x position.  SHORT2FROMMP (mp1) contains the y position.  SHORT1FROMMP (mp2) contains the hit-test parameter. ═══ 6.1.6. Capturing Mouse Input ═══ The operating system generally posts mouse messages to the window that is under the mouse pointer at the time the system reads the mouse input events from the system message queue. An application can change this by using the WinSetCapture function to route all mouse messages to a specific window or to the message queue associated with the current thread. If mouse messages are routed to a specific window, that window receives all mouse input until either the window releases the mouse or the application specifies another capture window. If mouse messages are routed to the current message queue, the system posts each mouse message to the queue with the hwnd member of the QMSG structure for each message set to NULL. Because no window handle is specified, the WinDispatchMsg function in the application's main message loop cannot pass these messages to a window procedure for processing. Therefore, the application must process these messages in the main loop. Capturing mouse input is useful if a window needs to receive all mouse input, even when the pointer moves outside the window. For example, applications commonly track the mouse-pointer position after a mouse "button down" event, following the pointer until a "button up" event is received from the system. If an application does not call WinSetCapture for a window and the user releases the mouse button, the application does not receive the button-up message. If the application sets a window to capture the mouse and tracks the mouse pointer, the application receives the button-up message even if the user moves the mouse pointer outside the window. Some applications are designed to require a button-up message to match a button-down message. When processing a button-down message, these applications call WinSetCapture to set the capture to their own window; then, when processing a matching button-up message, they call WinSetCapture, with a NULL window handle, to release the mouse. ═══ 6.1.6.1. Button Clicks ═══ An application window's response to a mouse click depends on whether the window is active. The first click in an inactive window should activate the window. Subsequent clicks in the active window produce an application-specific action. A common problem for an application that processes WM_BUTTON1DOWN or similar messages is failing to activate the window or set the keyboard focus. If the window processes WM_CHAR messages, the window procedure should call WinSetFocus to make sure the window receives the keyboard focus and is activated. If the window does not process WM_CHAR messages, the application should call WinSetActiveWindow to activate the window. ═══ 6.1.6.2. Mouse Movement ═══ The system sends WM_MOUSEMOVE messages to the window that is under the mouse pointer, or to the window that currently has captured the mouse, whenever the mouse pointer moves. This is useful for tracking the mouse pointer and changing its shape, based on its location in a window. For example, the mouse pointer changes shape when it passes over the size border of a standard frame window. All standard control windows use WM_MOUSEMOVE messages to set the mouse-pointer shape. If an application handles WM_MOUSEMOVE messages in some situations but not others, unused messages should be passed to the WinDefWindowProc function to change the mouse-pointer shape. ═══ 6.2. Using the Mouse and Keyboard ═══ This section explains how to perform the following tasks:  Determine the active status of a frame window  Check for a key-up or key-down event  Respond to a character message  Handle virtual-key codes  Handle a scan code ═══ 6.2.1. Determining the Active Status of a Frame Window ═══ The activated state of a window is a frame-window characteristic. The system does not provide an easy way to determine whether a client window is part of the active frame window. That is, the window handle returned by the WinQueryActiveWindow function identifies the active frame window rather than the client window owned by the frame window. Following are two methods for determining the activated state of a frame window that owns a particular client window:  Call WinQueryActiveWindow and compare the window handle it returns with the handle of the frame window that contains the client window, as shown in the following code fragment: Uses Os2Def,Os2Base,Os2PmApi; Var HwndClient : HWND; (* Сsken var tom!! *) FActivated : BOOL; (* Сsken var tom!! *) Begin @@@ fActivated := (WinQueryWindow(hwndClient, QW_PARENT) == WinQueryActiveWindow(HWND_DESKTOP));  Each time the frame window is activated, the client window receives a WM_ACTIVATE message with the low word of the mp2 equal to TRUE. When the frame window is deactivated, the client window receives a WM_ACTIVATE message with a FALSE activation indicator. ═══ 6.2.2. Checking for a Key-Up or Key-Down Event ═══ The following code fragment shows how to decode a WM_CHAR message to determine whether it indicates a key-up event or a key-down event: Uses Os2Def,Os2Base,Os2PmApi; Var FsKeyFlags : USHORT; (* Сsken var tom!! *) WM_CHAR: FsKeyFlags := SHORT1FROMMP(mp1); If ((fsKeyFlags<>0) AND (KC_KEYUP<>0)) Then Begin . . (* Perform key-up processing. *) . End Else Begin . . (* Perform key-down processing. *) . End; Halt; End; ═══ 6.2.3. Responding to a Character Message ═══ The following code fragment shows how to respond to a character message: Uses Os2Def,Os2Base,Os2PmApi; Var FsKeyFlags : USHORT; (* Сsken var tom!! *) UchChr1 : UCHAR; (* Сsken var tom!! *) Begin WM_CHAR: fsKeyFlags := SHORT1FROMMP(mp1); If ((fsKeyFlags<>0) AND (KC_CHAR<>0)) Then Begin (* Get the character code from mp2. *) uchChr1 := CHAR1FROMMP(mp2); . . (* Process the character. *) . Halt(Ord(True)); End; End. If the KC_CHAR flag is not set, the mp2 parameter from CHAR1FROMMP still might contain useful information. If either the Alt key or the Ctrl key, or both, are down, the KC_CHAR bit is not set when the user presses another key. For example, if the user presses the a key when the Alt key is down, the low word of mp2 contains the ASCII value for "a" (0x0061), the KC_ALT flag is set, and the KC_CHAR flag is clear. If the translation does not generate any valid characters, the char field is set to 0. ═══ 6.2.4. Handling Virtual-Key Codes ═══ The following code fragment shows how to decode a WM_CHAR message containing a valid virtual-key code: Uses Os2Def,Os2Base,Os2PmApi; Var FsKeyFlags : USHORT; (* Сsken var tom!! *) Begin case WM_CHAR: fsKeyFlags := SHORT1FROMMP(mp1); If ((fsKeyFlags) AND (KC_VIRTUALKEY)) Then Begin (* Get the virtual key from mp2. *) Case (SHORT2FROMMP(mp2)) Of VK_TAB: . . (* Process the TAB key. *) . Halt(Ord(True)); VK_LEFT: . . (* Process the LEFT key. *) . Halt(Ord(True)); VK_UP: . . (* Process the UP key. *) . Halt(Ord(True)); VK_RIGHT: . . (* Process the RIGHT key. *) . Halt(Ord(True)); VK_DOWN: . . (* Process the DOWN key. *) . Halt( Ord(True)); . . (* Etc... *) . Else Halt(Ord(False)); End; End; End. ═══ 6.2.5. Handling a Scan Code ═══ All WM_CHAR messages generated by keyboard input events have valid scan codes. WM_CHAR messages posted by other applications might or might not have valid scan codes. The following code fragment shows how to extract a scan code from a WM_CHAR message: Uses Os2Def,Os2Base,Os2PmApi; Var FsKeyFlags : USHORT; (* Сsken var tom!! *) UchScanCode : UCHAR; (* Сsken var tom!! *) Begin case WM_CHAR: fsKeyFlags := (USHORT) SHORT1FROMMP(mp1); If ((fsKeyFlags<>0) AND (KC_SCANCODE<>0)) Then Begin (* Get the scan code from mp1. *) uchScanCode := CHAR4FROMMP(mp1); . . (* Process the scan code. *) . Halt( Ord(True)); End; End. ═══ 7. Mouse Pointers and Icons ═══ A mouse pointer is a special bit map the operating system uses to show a user the current location of the mouse on the screen. When the user moves the mouse, the mouse pointer moves on the screen. This chapter describes how to create and use mouse pointers and icons in PM applications. ═══ 7.1. About Mouse Pointers and Icons ═══ Mouse pointers and icons are made up of bit maps that the operating system uses to paint images of the pointers or icons on the screen. A monochrome bit map is a series of bytes. Each bit corresponds to a single pel in the image. (The bit map representing the display typically has four bits for each pel.) A mouse pointer or icon bit map always is twice as tall as it is wide. The top half of the bit map is an AND mask, in which the bits are combined, using the AND operator, with the screen bits where the pointer is being drawn. The lower half of the bit map is an XOR mask, in which the bits are combined, using the XOR operator, with the destination screen bits. The combination of the AND and XOR masks results in four possible colors in the bit map. The pels of an icon or pointer can be black, white, transparent (the screen color beneath the pel), or inverted (inverting the screen color beneath the pel). The following figure shows the relationship of the bit values in the AND and XOR masks: AND mask 0 0 1 1 XOR mask 0 1 0 1 Result Black White Transparent Inverted ═══ 7.1.1. Mouse-Pointer Hot Spot ═══ Each mouse pointer has its own hot spot, which is the point that represents the exact location of the mouse pointer. This location is defined as an x and y offset from the lower-left corner of the mouse-pointer bit map. For the arrow-shaped pointer, the hot spot is at the tip of the arrow. For the I-beam pointer, the hot spot is at the middle of the vertical line. ═══ 7.1.2. Predefined Mouse Pointers ═══ Before an application can use a mouse pointer, it first must receive a handle to the pointer. Most applications load mouse pointers from the system or from their own resource file. The operating system maintains many predefined mouse pointers that an application can use by calling WinQuerySysPointer. System mouse pointers include all the standard mouse-pointer shapes and message-box icons. The following predefined mouse pointers are available: ┌────────────────────┬────────────────────────────────────────┐ │Mouse Pointer │Description │ ├────────────────────┼────────────────────────────────────────┤ │SPTR_APPICON │Square icon; used to represent a │ │ │minimized application window. │ ├────────────────────┼────────────────────────────────────────┤ │SPTR_ARROW │Arrow that points to the upper-left │ │ │corner of the screen. │ ├────────────────────┼────────────────────────────────────────┤ │SPTR_ICONERROR │Icon containing an exclamation point; │ │ │used in a warning message box. │ ├────────────────────┼────────────────────────────────────────┤ │SPTR_ICONINFORMATION│Octagon-shaped icon containing the image│ │ │of a human hand; used in a warning │ │ │message box. │ ├────────────────────┼────────────────────────────────────────┤ │SPTR_ICONQUESTION │Icon containing a question mark; used in│ │ │a query message box. │ ├────────────────────┼────────────────────────────────────────┤ │SPTR_ICONWARNING │Icon containing an asterisk; used in a │ │ │warning message box. │ ├────────────────────┼────────────────────────────────────────┤ │SPTR_MOVE │Four-headed arrow; used when dragging an│ │ │object or window around the screen. │ ├────────────────────┼────────────────────────────────────────┤ │SPTR_SIZE │Small box within a box; used when │ │ │resizing a window by dragging. │ ├────────────────────┼────────────────────────────────────────┤ │SPTR_SIZENS │Two-headed arrow that points up and down│ │ │(north and south); used when sizing a │ │ │window. │ ├────────────────────┼────────────────────────────────────────┤ │SPTR_SIZENESW │Two-headed diagonal arrow that points to│ │ │the upper-right (northeast) and │ │ │lower-left (southwest) window borders; │ │ │used when sizing a window. │ ├────────────────────┼────────────────────────────────────────┤ │SPTR_SIZENWSE │Two-headed diagonal arrow that points to│ │ │the upper-left (northwest) and │ │ │lower-right (southeast) window borders; │ │ │used when sizing a window. │ ├────────────────────┼────────────────────────────────────────┤ │SPTR_SIZEWE │Two-headed arrow that points left and │ │ │right (west to east); used when sizing a│ │ │window. │ ├────────────────────┼────────────────────────────────────────┤ │SPTR_TEXT │Text-insertion and selection pointer, │ │ │often called the I-beam pointer. │ ├────────────────────┼────────────────────────────────────────┤ │SPTR_WAIT │Hourglass; used to indicate that a │ │ │time-consuming operation is in progress.│ └────────────────────┴────────────────────────────────────────┘ The operating system contains a second set of predefined mouse pointers that are used as icons in PM applications. An application can use one of these icons by supplying one of the following constants in WinQuerySysPointer. If a copy of the system pointer is made using WinQuerySysPointer, the pointer copy must be destroyed using WinDestroyPointer before termination of the application. ┌───────────────┬─────────────────────────────────────────────┐ │Icon │Description │ ├───────────────┼─────────────────────────────────────────────┤ │SPTR_FILE │Represents a file (in the shape of a single │ │ │sheet of paper). │ ├───────────────┼─────────────────────────────────────────────┤ │SPTR_FOLDER │Represents a file folder. │ ├───────────────┼─────────────────────────────────────────────┤ │SPTR_ILLEGAL │Circular icon containing a slash; represents │ │ │an illegal operation. │ ├───────────────┼─────────────────────────────────────────────┤ │SPTR_MULTFILE │Represents multiple files. │ ├───────────────┼─────────────────────────────────────────────┤ │SPTR_PROGRAM │Represents an executable file. │ └───────────────┴─────────────────────────────────────────────┘ Applications can use mouse-pointer resources to draw icons. WinDrawPointer draws a specified mouse pointer in a specified presentation space. Many of the predefined system mouse pointers are standard icons displayed in message boxes. In addition to using the predefined pointer shapes, an application also can use pointers that have been defined in a resource file. Once the pointer or icon has been created (by Icon Editor or a similar application), the application includes it in the resource file, using the POINTER statement, a resource identifier, and a file name for the Icon Editor data. After including the mouse-pointer resource, the application can use the pointer or icon by calling WinLoadPointer, specifying the resource identifier and module handle. Typically, the resource is in the executable file of the application, so the application simply can specify NULL for the module handle to indicate the current application resource file. An application can create mouse pointers at run time by constructing a bit map for the pointer and calling WinCreatePointer. This function, if successful, returns the new pointer handle, which the application then can use to set or draw the pointer. The bit map must be twice as tall as it is wide, with the first half defining the AND mask and the second half defining the XOR mask. The application also must specify the hot spot when creating the mouse pointer. ═══ 7.1.3. System Bit Maps ═══ In addition to using the mouse pointers and icons defined by the system, applications can use standard system bit maps by calling WinGetSysBitmap. This function returns a bit map handle that is passed to WinDrawBitmap or to one of the GPI bit-map functions. The system uses standard bit maps to draw portions of control windows, such as the system menu, minimize/maximize box, and scroll-bar arrows. The following standard system bit maps are available: ┌─────────────────────────┬───────────────────────────────────┐ │Bit Map │Description │ ├─────────────────────────┼───────────────────────────────────┤ │SBMP_BTNCORNERS │Specifies the bit map for push │ │ │button corners. │ ├─────────────────────────┼───────────────────────────────────┤ │SBMP_CHECKBOXES │Specifies the bit map for the │ │ │check-box or radio-button check │ │ │mark. │ ├─────────────────────────┼───────────────────────────────────┤ │SBMP_CHILDSYSMENU │Specifies the bit map for the │ │ │smaller version of the system-menu │ │ │bit map; used in child windows. │ ├─────────────────────────┼───────────────────────────────────┤ │SBMP_CHILDSYSMENUDEP │Same as SBMP_CHILDSYSMENU but │ │ │indicates that the system menu is │ │ │selected. │ ├─────────────────────────┼───────────────────────────────────┤ │SBMP_COMBODOWN │Specifies the bit map for the │ │ │downward pointing arrow in a │ │ │drop-down combination box. │ ├─────────────────────────┼───────────────────────────────────┤ │SBMP_MAXBUTTON │Specifies the bit map for the │ │ │maximize button. │ ├─────────────────────────┼───────────────────────────────────┤ │SBMP_MENUATTACHED │Specifies the bit map for the │ │ │symbol used to indicate that a menu│ │ │item has an attached, hierarchical │ │ │menu. │ ├─────────────────────────┼───────────────────────────────────┤ │SBMP_MENUCHECK │Specifies the bit map for the menu │ │ │check mark. │ ├─────────────────────────┼───────────────────────────────────┤ │SBMP_MINBUTTON │Specifies the bit map for the │ │ │minimize button. │ ├─────────────────────────┼───────────────────────────────────┤ │SBMP_OLD_CHILDSYSMENU │Same as SBM_CHILDSYSMENU. (For │ │ │compatibility with previous │ │ │versions of the OS/2 operating │ │ │system.) │ ├─────────────────────────┼───────────────────────────────────┤ │SBMP_OLD_MAXBUTTON │Same as SBM_MAXBUTTON. (For │ │ │compatibility with previous │ │ │versions of the OS/2 operating │ │ │system.) │ ├─────────────────────────┼───────────────────────────────────┤ │SBMP_OLD_MINBUTTON │Same as SBM_MINBUTTON. (For │ │ │compatibility with previous │ │ │versions of the OS/2 operating │ │ │system.) │ ├─────────────────────────┼───────────────────────────────────┤ │SBMP_OLD_RESTOREBUTTON │Same as SBM_RESTOREBUTTON. (For │ │ │compatibility with previous │ │ │versions of the OS/2 operating │ │ │system.) │ ├─────────────────────────┼───────────────────────────────────┤ │SBMP_OLD_SBDNARROW │Same as SBM_SBDNARROW. (For │ │ │compatibility with previous │ │ │versions of the OS/2 operating │ │ │system.) │ ├─────────────────────────┼───────────────────────────────────┤ │SBMP_OLD_SBLFARROW │Same as SBM_SBLFARROW. (For │ │ │compatibility with previous │ │ │versions of the OS/2 operating │ │ │system.) │ ├─────────────────────────┼───────────────────────────────────┤ │SBMP_OLD_SBRGARROW │Same as SBM_SBRGARROW. (For │ │ │compatibility with previous │ │ │versions of the OS/2 operating │ │ │system.) │ ├─────────────────────────┼───────────────────────────────────┤ │SBMP_OLD_SBUPARROW │Same as SBM_SBUPARROW. (For │ │ │compatibility with previous │ │ │versions of the OS/2 operating │ │ │system.) │ ├─────────────────────────┼───────────────────────────────────┤ │SBMP_PROGRAM │Specifies the bit map for the │ │ │symbol that File Manager uses to │ │ │indicate that a file is an │ │ │executable program. │ ├─────────────────────────┼───────────────────────────────────┤ │SBMP_RESTOREBUTTON │Specifies the bit map for the │ │ │restore button. │ ├─────────────────────────┼───────────────────────────────────┤ │SBMP_RESTOREBUTTONDEP │Same as SBMP_RESTOREBUTTON but │ │ │indicates that the restore button │ │ │is pressed. │ ├─────────────────────────┼───────────────────────────────────┤ │SBMP_SBDNARROW │Specifies the bit map for the │ │ │scroll-bar down arrow. │ ├─────────────────────────┼───────────────────────────────────┤ │SBMP_SBDNARROWDEP │Same as SBMP_SBDNARROW but │ │ │indicates that the scroll-bar down │ │ │arrow is pressed. │ ├─────────────────────────┼───────────────────────────────────┤ │SBMP_SBDNARROWDIS │Same as SBMP_SBDNARROW but │ │ │indicates that the scroll-bar down │ │ │arrow is disabled. │ ├─────────────────────────┼───────────────────────────────────┤ │SBMP_SBLFARROW │Specifies the bit map for the │ │ │scroll-bar left arrow. │ ├─────────────────────────┼───────────────────────────────────┤ │SBMP_SBLFARROWDEP │Same as SBMP_SBLFARROW but │ │ │indicates that the scroll-bar left │ │ │arrow is pressed. │ ├─────────────────────────┼───────────────────────────────────┤ │SBMP_SBMFARROWDIS │Same as SBMP_SBLFARROW but │ │ │indicates that the scroll-bar left │ │ │arrow is disabled. │ ├─────────────────────────┼───────────────────────────────────┤ │SBMP_SBRGARROW │Specifies the bit map for the │ │ │scroll-bar right arrow. │ ├─────────────────────────┼───────────────────────────────────┤ │SBMP_SBRGARROWDEP │Same as SBMP_SBRGARROW but │ │ │indicates that the scroll-bar right│ │ │arrow is pressed. │ ├─────────────────────────┼───────────────────────────────────┤ │SBMP_SBRGARROWDIS │Same as SBMP_SBRGARROW but │ │ │indicates that the scroll-bar right│ │ │arrow is disabled. │ ├─────────────────────────┼───────────────────────────────────┤ │SBMP_SBUPARROW │Specifies the bit map for the │ │ │scroll-bar up arrow. │ ├─────────────────────────┼───────────────────────────────────┤ │SBMP_SBUPARROWDEP │Same as SBMP_SBUPARROW but │ │ │indicates that the scroll-bar up │ │ │arrow is pressed. │ ├─────────────────────────┼───────────────────────────────────┤ │SBMP_SBUPARROWDIS │Same as SBMP_SBUPARROW but │ │ │indicates that the scroll-bar up │ │ │arrow is disabled. │ ├─────────────────────────┼───────────────────────────────────┤ │SBMP_SIZEBOX │Specifies the bit map for the │ │ │symbol that indicates an area of a │ │ │window in which the user can click │ │ │to resize the window. │ ├─────────────────────────┼───────────────────────────────────┤ │SBMP_SYSMENU │Specifies the bit map for the │ │ │system menu. │ ├─────────────────────────┼───────────────────────────────────┤ │SBMP_TREEMINUS │Specifies the bit map for the │ │ │symbol that File Manager uses to │ │ │indicate an empty entry in the │ │ │directory tree. │ ├─────────────────────────┼───────────────────────────────────┤ │SBMP_TREEPLUS │Specifies the bit map for the │ │ │symbol that File Manager uses to │ │ │indicate that an entry in the │ │ │directory tree contains more files.│ └─────────────────────────┴───────────────────────────────────┘ ═══ 7.2. Using Mouse Pointers and Icons ═══ This section explains how to perform the following tasks:  Save the current mouse pointer  Change the mouse pointer  Restore the original mouse pointer ═══ 7.2.1. Changing the Mouse Pointer ═══ Once you create or load a mouse pointer, you can change its shape by calling WinSetPointer. Following are three typical situations in which an application changes the shape of the mouse pointer:  When an application receives a WM_MOUSEMOVE message, there is an opportunity to change the mouse pointer based on its location in the window. If you want the standard arrow pointer, pass this message on to WinDefWindowProc. If you want to change the mouse pointer on a standard dialog window, you need to capture the WM_CONTROLPOINTER message and return a pointing-device pointer handle.  When an application is about to start a time-consuming process during which it will not accept user input, the application displays the system-wait mouse pointer (SPTR_WAIT). Upon finishing the process, the application resets the mouse pointer to its former shape. The following code fragment shows how to save the current mouse pointer, set the hourglass pointer, and restore the original mouse pointer. Notice that the hourglass pointer also is saved in a global variable so that the application can return it when responding to a WM_MOUSEMOVE message during a time-consuming process. Uses Os2Def,Os2Base,Os2PmApi; Var hptrOld, hptrWait, hptrCurrent : HPOINTER; (* Сsken var tom!! *) Begin (* Get the current pointer. *) hptrOld := WinQueryPointer(HWND_DESKTOP); (* Get the wait mouse pointer. *) hptrWait := WinQuerySysPointer(HWND_DESKTOP, SPTR_WAIT, Ord(False)); (* Save the wait pointer to use in WM_MOUSEMOVE processing.*) hptrCurrent := hptrWait; (* Set the mouse pointer to the wait pointer. *) WinSetPointer(HWND_DESKTOP, hptrWait); (* * Do a time-consuming operation, then restore the * original mouse pointer. *) WinSetPointer(HWND_DESKTOP, hptrOld); End.  When an application needs to indicate its current operational mode, it changes the pointer shape. For example, a paint program with a palette of drawing tools should change the pointer shape to indicate which drawing tool is in use currently. ═══ 8. Notebook Controls ═══ A notebook control (WC_NOTEBOOK window class) is a visual component that organizes information on individual pages so that a user can find and display that information quickly and easily. This chapter explains how to use notebook controls in PM applications. ═══ 8.1. About Notebook Controls ═══ This notebook control component simulates a real notebook but improves on it by overcoming a notebook's natural limitations. A user can select and display pages by using a pointing device or the keyboard. The notebook can be customized to meet varying application requirements, while providing a user interface component that can be used easily to develop products that conform to the Common User Access (CUA) user interface guidelines. The application can specify different colors, sizes, and orientations for its notebooks, but the underlying function of the control remains the same. For a complete description of CUA notebooks, refer to the SAA CUA Guide to User Interface Design and the SAA CUA Advanced Interface Design Reference. ═══ 8.1.1. Notebook Styles ═══ This section describes the different notebook style components: o Page buttons o Status line o Binding o Intersection of back pages o Major and minor tabs o Tab shapes. ═══ 8.1.1.1. Page Buttons ═══ In the bottom-right corner of the notebook are the page buttons. These buttons let you bring one page of the notebook into view at a time. They are a standard component that is automatically provided with every notebook. However, the application can change the default width and height of the page buttons by using the BKM_SETDIMENSIONS message. The page buttons always are located in the corner where the recessed edges of the notebook intersect. Selecting the forward page button (the arrow pointing to the right) causes the next page to be displayed and selecting the backward page button (the arrow pointing to the left) causes the previous page to be displayed. Prior to inserting pages in the notebook, the page buttons are displayed with unavailable-state emphasis; therefore, selecting either page button would not bring a page into view. ═══ 8.1.1.2. Status Line ═══ To the left of the page buttons in the default notebook style setting is the status line, which enables the application to provide information to the user about the page currently displayed. The notebook does not supply any default text for the status line. The application is responsible for associating a text string with the status line of each page on which a text string is to be displayed. The status text is drawn left-justified by default, but it can be drawn centered or right-justified. The same status text justification applies to all pages in the notebook. This setting is specified by the BKS_STATUSTEXTLEFT style bit. The location of the back pages intersection and the major tabs has no effect on the specification of the status line position. This style bit can be set for the entire notebook. ═══ 8.1.1.3. Binding ═══ The notebook control resembles a real notebook in its general appearance. The default binding is solid and is placed on the left side. This binding is used if the BKS_SOLIDBIND style bit is specified or if no style bit is specified. Two styles are provided for the notebook binding: solid and spiral. The notebook is displayed with a solid binding by default, but the application can specify BKS_SPIRALBIND to display a spiral binding. The placement of the binding depends entirely on the placement of the back pages and major tabs, respectively. The binding always is located on the opposite side of the notebook from the major tabs. ═══ 8.1.1.4. Intersection of Back Pages ═══ The recessed edges that intersect near the page buttons are called the back pages. The default notebook's back pages intersect in the bottom-right corner, which means the recessed pages are on the bottom and right edges. This setting is specified by the BKS_BACKPAGESBR style bit. The back pages are important because their intersection determines where the major tabs can be placed, which in turn determines the placement of the binding and the minor tabs. ═══ 8.1.1.5. Major Tabs ═══ Major and minor tabs are used to organize related pages into sections. Minor tabs define subsections within major tab sections. The content of each section has a common theme, which is represented to the user by a tabbed divider that is similar to a tabbed page in a notebook. The BKS_MAJORTABRIGHT style bit specifies that major tabs, if used, are to be placed on the right side of the notebook. This is the default major tab placement when the back pages intersect at the bottom-right corner of the notebook. The binding is located on the left, because it is always located on the opposite side of the notebook from the major tabs. The placement of the major tabs is limited to one of the two edges on which there are recessed pages. For example, if the application specifies the back pages intersection at the bottom-right corner (BKS_BACKPAGESBR, the default), the major tabs can be placed on either the bottom edge (BKS_MAJORTABBOTTOM) or the right edge (BKS_MAJORTABRIGHT) of the notebook. In this situation, if the application specifies that major tabs are to be placed on the left or top edges of the notebook, the notebook control places them on the right edge anyway-the default placement for back pages intersecting at the bottom-right corner. When major tabs are defined at the creation of the notebook they are not displayed on screen. Major tab attributes only show at the time a page is inserted into the notebook. This is done by specifying the BKA_MAJOR attribute in the BKM_INSERTPAGE message. ═══ 8.1.1.6. Minor Tabs ═══ Minor tabs are specified using the BKA_MINOR attribute. Minor tabs always are placed perpendicular to the major tabs, based on the intersection of the back pages and the major tab placement. Only one major or minor tab attribute can be specified for each notebook page. Minor tabs are displayed only if the associated major tab page is selected or if the notebook has no major tab pages. The placement of the minor tabs depends entirely on the placement of the back pages and major tabs, respectively. The minor tabs always are located on the recessed page side that has no major tabs. The following table describes the available notebook control styles: ┌──────────────────────┬─────────────────┬─────────────┬────────┐ │Back Pages │Major Tabs │Minor Tabs │Binding │ ├──────────────────────┼─────────────────┼─────────────┼────────┤ │Bottom-right (default)│Bottom │Right │Top │ ├──────────────────────┼─────────────────┼─────────────┼────────┤ │Bottom-right (default)│Right (default) │Bottom │Left │ ├──────────────────────┼─────────────────┼─────────────┼────────┤ │Bottom-left │Bottom (default) │Left │Top │ ├──────────────────────┼─────────────────┼─────────────┼────────┤ │Bottom-left │Left │Bottom │Right │ ├──────────────────────┼─────────────────┼─────────────┼────────┤ │Top-right │Top (default) │Right │Bottom │ ├──────────────────────┼─────────────────┼─────────────┼────────┤ │Top-right │Right │Top │Left │ ├──────────────────────┼─────────────────┼─────────────┼────────┤ │Top-left │Top │Left │Bottom │ ├──────────────────────┼─────────────────┼─────────────┼────────┤ │Top-left │Left (default) │Top │Right │ └──────────────────────┴─────────────────┴─────────────┴────────┘ ═══ 8.1.1.7. Tab Shapes and Contents ═══ The default shape of the tabs used on notebook divider pages is square. This setting is specified by the BKS_SQUARETABS style bit. The shape of the tabs can be square, rounded, or polygonal. The tab text can be drawn left-justified, right-justified, or centered. Once set, these styles apply to the major and minor tabs for all pages in the notebook. The location of the back pages intersection and the major tabs has no effect on the specification of the tab-shape position. As with the page buttons, the application can change the default width and height of the major and minor tabs by using the BKM_SETDIMENSIONS message. A notebook tab can contain either text or a bit map. Text is associated with a tab page by using the BKM_SETTABTEXT message. Notebook tab text is centered by default or by specifying the BKS_TABTEXTCENTER style when creating the notebook window. A bit map is placed on a tab by using the BKM_SETTABBITMAP message. A bit map cannot be positioned on a tab because the bit map stretches to fill the rectangular area of the tab; therefore, no style bit is used. ═══ 8.1.1.8. Summary of Notebook Styles ═══ The notebook control provides style bits so that your application can specify or change the default style settings. One style bit from each of the following groups can be specified. If you specify more than one style bit, you must use an OR operator (Or) to combine them.  Type of binding BKS_SOLIDBIND Solid (default) BKS_SPIRALBIND Spiral  Intersection of back pages BKS_BACKPAGESBR Bottom-right corner (default) BKS_BACKPAGESBL Bottom-left corner BKS_BACKPAGESTR Top-right corner BKS_BACKPAGESTL Top-left corner  Location of major tabs BKS_MAJORTABRIGHT Right edge (default) BKS_MAJORTABLEFT Left edge BKS_MAJORTABTOP Top edge BKS_MAJORTABBOTTOM Bottom edge  Shape of tabs BKS_SQUARETABS Square (default) BKS_ROUNDEDTABS Rounded BKS_POLYGONTABS Polygonal  Alignment of text associated with tabs BKS_TABTEXTCENTER Centered (default) BKS_TABTEXTLEFT Left-justified BKS_TABTEXTRIGHT Right-justified  Alignment of status-line text BKS_STATUSTEXTLEFT Left-justified (default) BKS_STATUSTEXTRIGHT Right-justified BKS_STATUSTEXTCENTER Centered ═══ 8.2. Using Notebook Controls ═══ The following sections describe how to create pages, insert pages into, create and associate windows for, and delete pages from a notebook. ═══ 8.2.1. Notebook Creation ═══ You create a notebook by using the WC_NOTEBOOK window class name in the ClassName parameter of WinCreateWindow. The following sample code shows the creation of the notebook. The style set in the ulNotebookStyles variable (the BKS_* values) specifies that the notebook is to be created with a solid binding and the back pages intersecting at the bottom-right corner, major tabs placed on the right edge, shape tab square, tab text centered, and status-line text left-justified These are the default settings and are given here only to show how notebook styles are set. Uses Os2Def,Os2Base,Os2PmApi; Var HwndNotebook : HWND; (* Notebook window handle *) UlNotebookStyles : ULONG; (* Notebook window styles *) x, y, cx, cy : ULONG; (* Coordinates *) Begin (**********************************************************************) (* Set the BKS_style flags to customize the notebook. *) (**********************************************************************) ulNotebookStyles := BKS_SOLIDBIND Or (* Use solid binding *) BKS_BACKPAGESBR Or (* Set back pages to intersect at the *) (* bottom-right corner *) BKS_MAJORTABRIGHT Or (* Position major tabs on right side *) BKS_SQUARETABS Or (* Make tabs square *) BKS_TABTEXTCENTER Or (* Center tab text *) BKS_STATUSTEXTLEFT; (* Left-justIfied status-line text *) (**********************************************************************) (* Create the notebook control window. *) (**********************************************************************) hwndNotebook := WinCreateWindow( hwndParent, (* Parent window handle *) WC_NOTEBOOK, (* Notebook window class *) nil, (* No window text *) ulNotebookStyles, (* Notebook window styles *) x, y, cx, cy, (* Origin and size *) hwndOwner, (* Owner window handle *) HWND_TOP, (* Sibling window handle *) ID_BOOK, (* Notebook window ID *) nil, (* No control data *) nil); (* No presentation parameters *) (**********************************************************************) (* Make the notebook control visible. *) (**********************************************************************) WinShowWindow( hwndNotebook, (* Notebook window handle *) Ord(True)); (* Make the window visible *) End. ═══ 8.2.2. Changing Notebook Styles ═══ The following figure shows some sample code fragments for setting the notebook style to spiral binding, back pages intersecting at the bottom-left corner, major tabs placed on the bottom edge, tab shape rounded, tab text left-justified, and status-line text centered. (**********************************************************************) (* Query for the existing notebook window style settings. *) (**********************************************************************) ulNotebookStyles := WinQueryWindowULong(hwndNotebook, (* Notebook window handle *) QWL_STYLE); (* Set notebook style *) (**********************************************************************) (* Reset notebook window style flags, leaving window flags unchanged. *) (**********************************************************************) ulNotebookStyles := ulNotebookStyles AND $FFFF0000; (**********************************************************************) (* Setup the new notebook window style flags. *) (**********************************************************************) ulNotebookStyles := ulNotebookStyles Or BKS_SPIRALBIND Or (* Use spiral binding *) BKS_BACKPAGESBL Or (* Set back pages to intersect at the *) (* bottom-left corner *) BKS_MAJORTABBOTTOM Or (* Position major tabs on bottom edge *) BKS_ROUNDEDTABS Or (* Make tabs rounded *) BKS_TABTEXTLEFT Or (* Left-justIfied tab text *) BKS_STATUSTEXTCENTER; (* Center status-line text *) (**********************************************************************) (* Set the new notebook style. *) (**********************************************************************) WinSetWindowULong( hwndNotebook, (* Notebook window handle *) QWL_STYLE, (* Window style *) ulNotebookStyles); (* Set notebook style *) (**********************************************************************) (* Invalidate to force a repaint. *) (**********************************************************************) WinInvalidateRect( hwndNotebook, (* Notebook window handle *) nil, (* Invalidate entire window, *) Ord(True)); (* including children *) End. ═══ 8.2.3. Inserting Notebook Pages ═══ After a notebook is created, pages can be inserted into the notebook by using the BKM_INSERTPAGE message. BKM_INSERTPAGE provides several attributes that can affect the inserted pages. When inserting pages into either a new notebook or an existing one, consider carefully how the user expects those pages to be organized. ═══ 8.2.3.1. Major and Minor Tabs ═══ The two attributes that have the most impact on how notebook pages are organized are BKA_MAJOR and BKA_MINOR, which specify major and minor tabs, respectively. Major tab pages define the beginning of major sections in the notebook, while minor tab pages define the beginning of subsections within a major section. Major sections should begin with a page that has a BKA_MAJOR attribute. Within major sections, information can be organized into minor sections, each of which should begin with a page that has a BKA_MINOR attribute. For an existing notebook, the underlying hierarchy, if one exists, must be observed when inserting new pages, to provide efficient organization and navigation of the information in the notebook. For example, if the notebook has minor sections but no major sections, you could confuse the user if you inserted a page with a major tab attribute between related minor sections or at the end of the notebook. If you insert pages without specifying tab attributes, those pages become part of the section in which they are inserted. For example, if page 7 of your notebook has a minor tab and you insert a new page 8 without specifying a tab attribute, page 8 becomes part of the section that begins with the minor tab on page 7. Because tab pages are not mandatory, the application can create a notebook that contains no major or minor tab pages. That style would be similar to that of a composition notebook. Another group of attributes that can affect the organization of pages being inserted into a notebook consists of BKA_FIRST, BKA_LAST, BKA_NEXT, and BKA_PREV. These attributes cause pages to be inserted at the end, at the beginning, after a specified page, and before a specified page of a notebook, respectively. ═══ 8.2.3.2. Status Line ═══ Each page has an optional status line that can be used to display information for the user. To include this status line, the application must specify the BKA_STATUSTEXTON attribute when inserting the page. If the application inserts the page without specifying this attribute, the status line is not available for that page. To display text on the status line of the specified page, the application must use the BKM_SETSTATUSLINETEXT message to associate a text string with the page. A separate message must be sent for each page that is to display status-line text. If the application does not send a BKM_SETSTATUSLINETEXT message for a page, no text is displayed in the status line of that page. The application can send this message to the notebook at any time to change the status-line text. The status line can be cleared by setting the text to NULL. The following sample code shows how to insert a page into a notebook, where the inserted page has a major tab attribute, the status line is available, and the page is inserted after the last page in the notebook. This sample code also shows how to associate a text string with the status line of the inserted page. Uses Os2Def,Os2Base,Os2PmApi; Var HwndNotebook : HWND; (* Notebook window handle *) UlPageId : ULONG; (* Page identifier *) Begin (***********************************************************************) (* Insert a new page into a notebook. *) (***********************************************************************) ulPageId := WinSendMsg( hwndNotebook, (* Notebook window handle *) BKM_INSERTPAGE, (* Message for inserting a page *) nil, (* nil for page ID *) MPFROM2SHORT( BKA_MAJOR Or (* Insert page with a major tab *) (* attribute *) BKA_STATUSTEXTON), (* Make status-line text visible *) BKA_LAST)); (* Insert this page at end of notebook *) (***********************************************************************) (* Set the status-line text. *) (***********************************************************************) WinSendMsg( hwndNotebook, (* Notebook window handle *) BKM_SETSTATUSLINETEXT, (* Message for setting status-line *) (* text *) ulPageId, (* ID of page to receive status-line *) (* text *) MPFROMP('Page 1 of 2')); (* Text string to put on status line *) End. ═══ 8.2.4. Setting and Querying Page Information ═══ The information for a page in the notebook can be set and queried with BKM_SETPAGEINFO and BKM_QUERYPAGEINFO respectively. By using these messages, all the information associated with a page can be accessed at once. In addition, BKM_SETPAGEINFO can be used to delay the loading of a page until it is turned to, by setting the bLoadDlg field to FALSE. By doing this for all pages in a notebook, the notebook is created much more quickly. ═══ 8.2.5. Associating Application Page Windows with Notebook Pages ═══ After a page is inserted into a notebook, you must facilitate the display of information for this page when it is brought to the top of the book. The notebook provides a top page area in which the application can display windows or dialogs for the topmost page. For each inserted page, the application must associate the handle of a window or dialog that is to be invalidated when the page is brought to the top of the book. The application can associate the same handle with different pages, if desired. The application must send a BKM_SETPAGEWINDOWHWND message to the notebook in order to associate the application page window or dialog handle with the notebook page being inserted. Once done, the notebook invalidates this window or dialog whenever the notebook page is brought to the top of the book. If no application page window handle is specified for an inserted page, no invalidation can be done by the notebook for that page. However, the application receives a BKN_PAGESELECTED notification code when a new page is brought to the top of the notebook, at which time the application can invalidate the page. The notebook also sends a BKN_PAGESELECTEDPENDING notification code to the application before the new page is selected. The application can use this message to prevent the page from being turned to. This is useful when the application wants to validate a page's contents. The following sections describe how to associate either a window handle or a dialog handle with an inserted page. ═══ 8.2.5.1. Associating a Window with a Notebook Page ═══ A calendar example is used to show how a page can be implemented as a window. A calendar is divided into four years (major tabs). Within each year are months (minor tabs) grouped into quarters. The top page has a window associated with it. The window paint processing displays the days for the currently selected month and year. The sample code in the following figure shows how the window procedure for the calendar is registered with the application. Also, it shows how the window is created and associated with the notebook page. The example ends by showing the window procedure for the associated window. (*********************************************************************) (* Registration of window procedure for calendar. *) (*********************************************************************) WinRegisterClass(hab, (* Register a page window class *) 'Calendar Page', (* Class name *) PageWndProc, (* Window procedure *) CS_SIZEREDRAW, (* Class style *) 0); (* No extra bytes reserved *) (*********************************************************************) (* Create the window. *) (*********************************************************************) hwndPage := WinCreateWindow(hwndNotebook, (* Parent *) 'Calendar Page', (* Class *) nil, (* Title text *) 0, (* Style *) 0, 0, 0, 0, (* Origin and size *) hwndNotebook, (* Owner *) HWND_TOP, (* Z-order *) ID_WIN_CALENDAR_PAGE,(* ID *) nil, (* Control data *) nil); (* Presparams *) (*********************************************************************) (* Associate window with the inserted notebook page. *) (*********************************************************************) WinSendMsg(hwndBook, BKM_SETPAGEWINDOWHWND, MPFROMLONG(ulPageId), MPFROMHWND(hwndPage)); (*********************************************************************) (* Window procedure. *) (*********************************************************************) Function PageWndProc( hwnd : HWND, msg : ULONG, mp1 : MPARAM, mp2 : MPARAM):MRESULT; cdecl; Var Hps : HPS; (* Сsken var tom!! *) Begin Case msg Of (*******************************************************************) (* WM_CREATE is sent when the window is created. *) (*******************************************************************) WM_CREATE: (*****************************************************************) (* Place window initialization code here. *) (*****************************************************************) WM_PAINT: (*****************************************************************) (* Draw the calendar for the selected year and month. *) (*****************************************************************) . . . WinEndPaint(hps); break; Else Begin PageWndProc := WinDefWindowProc(hwnd, msg, mp1, mp2); Exit; End; PageWndProc := (Ord(False)); End; ═══ 8.2.5.2. Associating a Dialog with a Notebook Page ═══ To understand the notebook implemented as a dialog, a Properties Notebook is used. The various objects whose properties can be changed or updated are displayed as major tabs. Included are sections that represent a folder, printer, and display (major tabs). The printer object is currently selected. Within the printer object, the user can choose to &odq.View&cdq. or &odq.Update&cdq. (minor tabs) the printer settings. The topmost page is a printer dialog from which the user can update the printer name, type, and device information. The following sample code shows how the printer dialog is created and associated with a notebook page. The example ends by showing the dialog procedure for the associated dialog. Uses Os2Def,Os2Base,Os2PmApi; Var Dlgret : APIRET; (* Сsken var tom!! *) hwndPage, hwndNotebook : HWND; (* Сsken var tom!! *) PDlgt : PDLGTEMPLATE; (* Сsken var tom!! *) Sel : SEL; (* Сsken var tom!! *) Begin Sel := nil; (**********************************************************************) (* Allocate memory. *) (**********************************************************************) DosAllocMem(&pDlgt, sizeof(DLGTEMPLATE), PAG_COMMIT Or PAG_READ Or PAG_WRITE); (**********************************************************************) (* Retrieve the dialog resource. *) (**********************************************************************) dlgret := DosGetResource(0, (* Resource *) (* (Obtain from executable) *) RT_DIALOG, (* Resource type *) ID_DLG_PRINTDRV, (* Resource ID *) &pDlgt); (* Dialog template address *) (**********************************************************************) (* Create a dialog. *) (**********************************************************************) hwndPage := WinCreateDlg(HWND_DESKTOP, (* Parent window handle *) hwndBook, (* Owner window handle *) fnwpPrint, (* Dialog procedure *) (* address *) pDlgt, (* Dialog data structure *) (* address *) nil); (* Application data *) DosFreeMem(pDlgt); (* Free memory *) (**********************************************************************) (* Associate dialog with the inserted notebook page. *) (**********************************************************************) WinSendMsg(hwndBook, BKM_SETPAGEWINDOWHWND, MPFROMLONG(ulPageId), MPFROMHWND(hwndPage)); (**********************************************************************) (* Dialog procedure. *) (**********************************************************************) Function fnwpPrint( hwndDlg : HWND, msg : ULONG, mp1 : MPARAM, mp2 : MPARAM): MRESULT; cdecl; Begin Case msg Of WM_INITDLG: (****************************************************************) (* Place dialog initialization code here. *) (****************************************************************) WM_COMMAND: fnwpPrint := Ord(False); Exit; Else Begin fnwpPrint := WinDefDlgProc (hwndDlg,msg,mp1,mp2); Exit End; fnwPrint := WinDefDlgProc (hwndDlg,msg,mp1,mp2); End; ═══ 8.2.6. Deleting Notebook Pages ═══ The BKM_DELETEPAGE message is used to delete one or more pages from the notebook. The application can delete one page (BKA_SINGLE attribute), all pages within a major or minor tab section (BKA_TAB attribute), or all of the pages in the notebook (BKA_ALL attribute). The default, if no attributes are specified, is to delete no pages. The following sample code shows how the BKM_QUERYPAGEID message is used to get the ID of the top page and how the BKM_DELETEPAGE message is then used to delete that page: (**********************************************************************) (* Set the range of pages to be deleted. *) (**********************************************************************) (* Set attribute to delete a single page. *) usDeleteFlag := BKA_SINGLE (**********************************************************************) (* Get the ID of the notebook's top page. *) (**********************************************************************) ulPageId := WinSendMsg( hwndNotebook, (* Notebook window handle *) BKM_QUERYPAGEID, (* Message to query a page ID *) nil, (* nil for page ID *) BKA_TOP); (* Get ID of top page *) (**********************************************************************) (* Delete the notebook's top page. *) (**********************************************************************) WinSendMsg( hwndNotebook, (* Notebook window handle *) BKM_DELETEPAGE, (* Message to delete the page *) MPFROMLONG(ulPageId), (* ID of page to be deleted *) usDeleteFlag); (* Range of pages to be deleted *) End. ═══ 8.2.7. Notebook Colors ═══ The application can change the color of any part of the notebook. The colors of some parts can be changed by specifying presentation parameter attributes in WinSetPresParam. Other colors can be changed by specifying notebook attributes in the BKM_SETNOTEBOOKCOLORS message. The following sections define which parts of the notebook can have their colors changed by each of these two methods. ═══ 8.2.7.1. Changing Colors Using WinSetPresParam ═══ WinSetPresParam is used to change the color of the notebook outline, window background, selection cursor, and status-line text. The following list shows the mapping between the various notebook parts and their associated presentation parameter attributes. Notebook outline PP_BORDERCOLOR or PP_BORDERCOLORINDEX. This color is set initially to SYSCLR_WINDOWFRAME. Notebook window background PP_BACKGROUNDCOLOR or PP_BACKGROUNDCOLORINDEX. This color is set initially to SYSCLR_FIELDBACKGROUND. Selection cursor PP_HILITEBACKGROUNDCOLOR or PP_HILITEBACKGROUNDCOLORINDEX. This color is set initially to SYSCLR_HILITEBACKGROUND. Status-line text PP_FOREGROUNDCOLOR or PP_FOREGROUNDCOLORINDEX. This color is initially set to SYSCLR_WINDOWTEXT. If a presentation parameter attribute is set, all parts of the notebook that are mapped to this color are changed. The following sample code shows how to change the color of the notebook outline: (* Set number of bytes to be passed in usColorIdx *) (* for color index table value *) usColorLen := 4; (* Set color index table value to be assigned *) ulColorIdx := 3; (**********************************************************************) (* Set the notebook outline color. *) (**********************************************************************) WinSetPresParam( hwndNotebook, (* Notebook window handle *) PP_BORDERCOLOR, (* Border color attribute *) usColorLen, (* Number of bytes in color index *) (* table value *) &ulColorIdx); (* Color index table value *) ═══ 8.2.7.2. Changing Colors Using BKM_SETNOTEBOOKCOLORS ═══ The BKM_SETNOTEBOOKCOLORS message is used to change the color of the major tab background and text, the minor tab background and text, and the notebook page background. The following list shows the mapping between the various notebook parts and their associated notebook attributes. Major tab background BKA_BACKGROUNDMAJORCOLOR or BKA_BACKGROUNDMAJORCOLORINDEX. This color is set initially to SYSCLR_PAGEBACKGROUND. The currently selected major tab has the same background color as the notebook page background. Major tab text BKA_FOREGROUNDMAJORCOLOR or BKA_FOREGROUNDMAJORCOLORINDEX. This color is set initially to SYSCLR_WINDOWTEXT. Minor tab background BKA_BACKGROUNDMINORCOLOR or BKA_BACKGROUNDMINORCOLORINDEX. This color is set initially to SYSCLR_PAGEBACKGROUND. The currently selected minor tab has the same background color as the notebook page background. Minor tab text BKA_FOREGROUNDMINORCOLOR or BKA_FOREGROUNDMINORCOLORINDEX. This color is set initially to SYSCLR_WINDOWTEXT. Notebook page background BKA_BACKGROUNDPAGECOLOR or BKA_BACKGROUNDPAGECOLORINDEX. This color is set initially to SYSCLR_PAGEBACKGROUND. If a notebook attribute is set, all parts of the notebook that are mapped to this color are changed. The following sample code shows how to change the color of the major tab background: (* Color index value *) ulColorIdx := SYSCLR_WINDOW; (* Major tab background *) ulColorRegion := BKA_BACKGROUNDMAJORCOLORINDEX; WinSendMsg(hwndBook, BKM_SETNOTEBOOKCOLORS, MPFROMLONG(ulColorIdx), MPFROMLONG(ulColorRegion)); ═══ 8.3. Graphical User Interface Support for Notebook Controls ═══ The following section describes the support for graphical user interfaces (GUIs) provided by the notebook control. Except where noted, this support conforms to the guidelines in the SAA CUA Advanced Interface Design Reference. The GUI support provided by the notebook control consists of the notebook navigation techniques. ═══ 8.3.1. Notebook Navigation Techniques ═══ The notebook control supports the use of a pointing device and the keyboard for displaying notebook pages and tabs and for moving the selection cursor from the notebook tabs to the application window and the other way around. Note: If more than one notebook window is open, displaying a page or tab in one notebook window has no effect on the pages or tabs displayed in any other notebook window. ═══ 8.3.1.1. Pointing Device Support ═══ A user can use a pointing device to display notebook pages or tabs by selecting the notebook components described in the following list. The CUA guidelines define mouse button 1 (the select button) to be used for selecting these components. This definition also applies to the same button on any other pointing device a user might have.  Selecting tabs using a pointing device A tab can be selected to bring a page that has a major or minor tab attribute to the top of the notebook. The selection cursor, a dotted outline, is drawn inside the tab's border to indicate the selected tab. In addition, the selected tab is given the same background color as the notebook page area. The color of the other tabs is specified in the BKM_SETNOTEBOOKCOLORS message. This helps the user distinguish the selected tab from the other tabs if different colors are used. Because all tabs are mutually exclusive, only one of them can be selected at a time. Therefore, the only type of selection supported by the notebook control is single selection. This selection type conforms to the guidelines in the SAA CUA Advanced Interface Design Reference. If the user moves the pointing device to a place in the notebook page window that can accept a cursor, such as an entry field, check box, or radio button, and presses the select button, the selection cursor is removed from the tab it is on and is displayed in the notebook page window. The selection cursor never can be displayed both on a tab and in the notebook page window at the same time.  Selecting page buttons using a pointing device A forward or backward page button can be selected to display the next or previous page, respectively, one at a time. The arrow pointing to the right is the forward page button, and the arrow pointing to the left is the backward page button. When the selection of a page button brings a page that has a major or minor tab to the top of the notebook, the selection cursor is drawn inside that tab's border.  Selecting tab scroll buttons using a pointing device A user can decrease the size of a notebook window so that some of the available notebook tabs cannot be displayed. When this happens, the notebook control automatically draws tab scroll buttons at the corners of the notebook side or sides to notify the user that more tabs are available. Tab scroll buttons have another purpose: to give the user the means to scroll into view, one at a time, the tabs that are not displayed. The user does this by selecting a forward or backward tab scroll button, which causes the next tab to scroll into view, but does not change the location of the selection cursor. Once the tab is in view, the user can display that tab's page by selecting the tab. A maximum of four tab scroll buttons can be displayed: two for the major tab side and two for the minor tab side. When the first tab in the notebook is displayed, the backward tab scroll button is deactivated. Unavailable-state emphasis is applied to it to show that no more tabs can be scrolled into view by using the backward tab scroll button. Unavailable-state emphasis is applied to the forward tab scroll button if the last tab in the notebook is displayed. ═══ 8.3.1.2. Keyboard Support ═══ The users can utilize the keyboard to display and manipulate notebook pages and components. ═══ 8.3.1.2.1. Focus on Application Dialog or Window ═══ If the application dialog page or window has the focus, the notebook handles the following keyboard interactions: Keyboard Input Description Alt+PgDn or PgDn Brings the next page to the top of the notebook. If the application uses the PgDn key, then it must be used in combination with the Alt key. Alt+PgUp or PgUp Brings the previous page to the top of the notebook. If the application uses the PgUp key, then it must be used in combination with the Alt key. Alt+Up Arrow Switch the focus to the notebook window. Tab Move the cursor to the next control within the top page window or dialog. If the cursor is currently on the last control within the top page window or dialog when the Tab key is pressed, the cursor is moved to the notebook major tab, if it exists; else to the minor tab, if it exists; else to the right page button. Shift+Tab Move the cursor to the previous control within the top page window or dialog. If the cursor is currently on the first control within the top page window or dialog when the Shift+Tab key is pressed, the cursor is moved to the previous control. If the previous control is the notebook, the cursor is moved to the right page button. ═══ 8.3.1.2.2. Focus on the Notebook Control ═══ If the notebook control has the focus, it handles the following keyboard intereactions: Keyboard Input Description Alt+Down Arrow Switch the focus to the application's primary window. Alt+PgDn or PgDn Brings the next page to the top of the notebook. Alt+PgUp or PgUp Brings the previous page to the top of the notebook. Left or Up Arrow If the cursor is currently on a major tab, it is moved to the previous major tab. If the previous major tab is not visible, the tabs are scrolled to bring the previous major tab into view. If the first major tab is reached, scrolling ends. If the cursor is currently on a minor tab, it is moved to the previous minor tab. If the previous minor tab is not visible, the tabs are scrolled to bring the previous minor tab into view. If the first minor tab is reached, scrolling ends. If the cursor is currently on the right page button, the cursor moves to the left page button. If the cursor is currently on the left page button, no action is taken. Right or Down Arrow If the cursor is currently on a major tab, it is moved to the next major tab. If the next major tab is not visible, the tabs are scrolled to bring the next major tab into view. If the last major tab is reached, scrolling ends. If the cursor is currently on a minor tab, it is moved to the next minor tab. If the next minor tab is not visible, the tabs are scrolled to bring the next minor tab into view. If the last minor tab is reached, scrolling ends. If the cursor is currently on the right page button, no action is taken. If the cursor is currently on the left page button, the cursor moves to the right page button. Tab The cursor moves from the major tab, then to the minor tab, then to the right page button, and then to the last tab stop in the application dialog or window. Shift+Tab The cursor moves from the page button, to the minor tab, to the major tab, and then to the first tab stop in the application dialog or window. Home Brings the first page of the notebook to the top and sets the cursor on the associated tab. End Brings the last page of the notebook to the top and sets the cursor on the associated tab. Enter or Spacebar If the cursor is on a major or minor tab, the associated page is brought to the top of the notebook, and the selected tab is given the same background color as the notebook page area. The other tabs have their color specified in the BKM_SETNOTEBOOKCOLORS message. This helps the user distinguish the selected tab from the other tabs if different colors are used. If the cursor is currently on the right page button, the next page is brought to the top of the notebook. If the cursor is currently on the left page button, the previous page is brought to the top of the notebook. Mnemonics Mnemonics are underlined characters in the text of a tab that cause the tab's page to be selected. Coding a tilde (~) before a text character in the BKM_SETTABTEXT message causes that character to be underlined and activates it as a mnemonic-selection character. A user performs mnemonic selection by pressing a character key that corresponds to an underlined character. When this happens, the tab that contains the underlined character is selected, and that tab's page is brought to the top of the notebook. Note: Mnemonic selection is not case sensitive, so the user can type the underscored letter in either uppercase or lowercase. ═══ 8.4. Enhancing Notebook Controls Performance and Effectiveness ═══ This section provides the following information to enable you to fine-tune a notebook control:  Dynamic resizing and scrolling  Tab painting and positioning ═══ 8.4.1. Dynamic Resizing and Scrolling ═══ The notebook control supports dynamic resizing by recalculating the size of the notebook's parts when either the user or the application changes the size of any of those parts. A BKN_NEWPAGESIZE notification code is sent from the notebook to the application whenever the notebook's size changes. The notebook handles the sizing and positioning of each application page window if the BKA_AUTOPAGESIZE attribute is specified for the inserted notebook page. Otherwise, the application must handle this when it receives the BKN_NEWPAGESIZE notification code from the notebook. If the size of the notebook window is decreased so that the page window is not large enough to display all the information the page contains, the information in the page window is clipped. If scroll bars are desired to enable the clipped information to be scrolled into view, they must be provided by the application. Tab scroll buttons are automatically displayed if the size of the notebook is decreased so that all the major or minor tabs cannot be displayed. For example, a notebook has major tabs on the right side, but the height of the notebook does not allow all the tabs to be displayed. In this case, tab scroll buttons are displayed on the upper- and lower-right corners of the notebook. ═══ 8.4.2. Tab Painting and Positioning ═══ The tab pages provide a method for organizing the information in a notebook so that the user easily can see and navigate to that information. When a page is inserted with a major or minor tab attribute, the notebook displays a tab for that page, based on the orientation of the notebook. The contents of the tab can be painted either by the notebook control or the application. If the notebook control is to paint the tabs, the application must associate a text string or bit map with the page whose tab is to be drawn. This is done by sending the BKM_SETTABTEXT or BKM_SETTABBITMAP message to the notebook control for the specified page. If neither of these messages is sent for an inserted page with a major or minor tab attribute, the application must draw the contents of the tab, through ownerdraw. The application receives a WM_DRAWITEM message whenever a tab page that has no text or bit map associated with it is to be drawn. The application can either draw the tab contents or return FALSE, in which case the notebook control fills the tab with the tab background color. Positioning Tabs in Relation to the Top Tab: There are seven page edges that define the back pages. The page attribute (BKA_MAJOR or BKA_MINOR) and the topmost page determine how the tabs are positioned. In most cases, the tabs must be drawn when their position changes. For example, this can happen when a page with a tab attribute is brought to the top of the notebook. The new top major or minor tab will appear attached to the top page. The other tabs will appear as described in the following list. This information is provided to help you understand the relationship between the top tab and the other tabs so that you can organize the information you put into a notebook appropriately. The application has no control over tab positioning.  When the top page is a major tab page: - Any major tabs prior to the top major tab are aligned on the last page of the notebook. - Any major tabs after the top major tab are incrementally cascaded from the topmost edge to the last page. - If the top major tab has minor tabs, no major tab is drawn on the page edge that immediately follows the top tab page. Instead, any major tabs that follow the top tab are incrementally cascaded, beginning on the second page, edge-down from the top tab. This is done to account for the minor tabs that are positioned between the top major tab and the major tab that follows it on the perpendicular notebook edge. The minor tabs are all positioned on the third page edge from the top, thereby giving the appearance of being between the top major tab and the next major tab.  When the top page is a minor tab page: - Any minor tabs prior to the top minor tab are positioned on the third page edge from the top of the notebook. - Any minor tabs after the top minor tab are incrementally cascaded up to the third page edge from the top. ═══ 9. Painting and Drawing ═══ This chapter describes presentation spaces, device contexts, and window regions, explaining how a PM application uses them for painting and drawing in windows. ═══ 9.1. About Painting and Drawing ═══ An application typically maintains an internal representation of the data that it is manipulating. The information displayed in a screen, window, or printed copy is a visual representation of some portion of that data. This chapter introduces the concepts and strategies necessary to make your PM application function smoothly and cooperatively in the OS/2 display environment. ═══ 9.1.1. Presentation Spaces and Device Contexts ═══ A presentation space is a data structure, maintained by the operating system, that describes the drawing environment for an application. An application can create and hold several presentation spaces, each describing a different drawing environment. All drawing in a PM application must be directed to a presentation space. Normally each presentation space is associated with a device context that describes the physical device where graphics commands are displayed. The device context translates graphics commands made to the presentation space into commands that enable the physical device to display information. Typical device contexts are the screen, printers and plotters, and off-screen memory bit maps. By creating presentation spaces and associating them with particular device contexts, an application can control where its graphics output appears. Typically, a presentation space and device context isolate the application from the physical details of displaying graphics, so the same graphics commands can be used for many types of displays. This virtualization of output can reduce the amount of display code an application must include to support multiple output devices. This chapter describes how an application sets up its presentation spaces and device contexts before drawing, and how to use window-drawing functions. Refer to the Graphics Programming Interface Programming Guide for the graphics functions available to PM applications. ═══ 9.1.2. Window Regions ═══ A window and its associated presentation space have three regions that control where drawing takes place in the window. These regions ensure that the application does not draw outside the boundaries of the window or intrude into the space of an overlapping window. ┌───────────────┬─────────────────────────────────────────────┐ │Region │Description │ ├───────────────┼─────────────────────────────────────────────┤ │Update Region │This region represents the area of the window│ │ │that needs to be redrawn. This region changes│ │ │when overlapping windows change their z-order│ │ │or when an application explicitly adds an │ │ │area to the update region to force a window │ │ │to be painted. │ ├───────────────┼─────────────────────────────────────────────┤ │Clip Region │This region and the visible region determine │ │ │where drawing takes place. Applications can │ │ │change the clip region to limit drawing to a │ │ │particular portion of a window. Typically, a │ │ │presentation space is created with a clip │ │ │region equal to NULL, which makes this region│ │ │equivalent to the update region. │ ├───────────────┼─────────────────────────────────────────────┤ │Visible Region │This region and the clip region determine │ │ │where drawing takes place. The system changes│ │ │the visible region to represent the portion │ │ │of a window that is visible. Typically, the │ │ │visible region is used to mask out │ │ │overlapping windows. When an application │ │ │calls the WinBeginPaint function in response │ │ │to a WM_PAINT message, the system sets the │ │ │visible region to the intersection of the │ │ │visible region and the update region to │ │ │produce a new visible region. Applications │ │ │cannot change the visible region directly. │ └───────────────┴─────────────────────────────────────────────┘ Whenever drawing occurs in a window's presentation space, the output is clipped to the intersection of the visible region and clip region. The clip region includes the overlapped part of the back window, but the visible region excludes that portion of the back window. The system maintains the visible region to protect other windows on the screen; the application maintains the clip region to specify the portion of the window in which it draws. Together, these two regions provide safe and controllable clipping. To further control drawing, both the system and the application manipulate the update region. For example, if a window's position is switched from back to front, positions front to back, several changes occur in the regions of both windows. The system adds the lower-right corner of the new front window to that window's visible region. The system also adds that corner area to the window's update region. ═══ 9.1.3. Window Styles for Painting ═══ Most of the styles relating to window drawing can be set either for the window class (CS_ prefix) or for an individual window (WS_ prefix). The styles described in this section control how the system manipulates the window's regions and how the window is notified when it must be painted or redrawn. ═══ 9.1.3.1. WS_CLIPCHILDREN, CS_CLIPCHILDREN ═══ All the windows with this style are excluded from their parent's visible region. This style protects windows but increases the amount of time necessary to calculate the parent's visible region. This style normally is not necessary, because if the parent and child windows overlap and both are invalidated, the parent window is drawn before the child window. If the child window is invalidated independently from its parent window, only the child window is redrawn. If the update region of the parent window does not intersect the child window, drawing the parent window does not disturb the child window. ═══ 9.1.3.2. WS_CLIPSIBLINGS, CS_CLIPSIBLINGS ═══ Windows with this style are excluded from the visible region of sibling windows. This style protects windows with the same parent from being drawn accidentally, but increases the amount of time necessary to calculate the visible region. This style is appropriate for sibling windows that overlap. ═══ 9.1.3.3. WS_PARENTCLIP, CS_PARENTCLIP ═══ The visible region for a window with this style is the same as the visible region of the parent window. This style simplifies the calculation of the visible region but is potentially hazardous, because the parent window's visible region usually is larger than the child window. Windows with this style should not draw outside their boundaries. ═══ 9.1.3.4. WS_SAVEBITS, CS_SAVEBITS ═══ The system saves the bits beneath a window with this style when the window is displayed. When the window moves or is hidden, the system simply restores the uncovered bits. This operation can consume a great deal of memory; it is recommended only for transient windows such as menus and dialog boxes-not for main application windows. This style also is inappropriate for windows that are updated dynamically, such as clocks. ═══ 9.1.3.5. WS_SYNCPAINT, CS_SYNCPAINT ═══ Windows that have these styles receive WM_PAINT messages as soon as their update regions contain something; they are updated immediately (synchronously). ═══ 9.1.3.6. CS_SIZEREDRAW ═══ A window with this class style receives a WM_PAINT message; the window is completely invalidated whenever it is resized, even if it is made smaller. (Typically, only the uncovered area of a window is invalidated when a window is resized.) This class style is useful when an application scales graphics to fill the current window. ═══ 9.2. Strategies for Painting and Drawing ═══ A PM application shares the screen with other windows and applications; therefore, painting and drawing must not interfere with those other applications and windows. When you follow these strategies, your application can coexist with other applications and still take full advantage of the graphics capabilities of the operating system. ═══ 9.2.1. Drawing in a Window ═══ Ideally, all drawing in a window occurs as a result of an application's processing a WM_PAINT message. Applications maintain an internal representation of what must be displayed in the window, such as text or a linked list of graphics objects, and use the WM_PAINT message as a cue to display a visual representation of that data in the window. To route all display output through the WM_PAINT message, an application must not draw on the screen at the time its data changes. Instead, it must update the internal representation of the data and call the WinInvalidateRect or WinInvalidateRegion functions to invalidate the portion of the window that must be redrawn. Sometimes it is much more efficient to draw directly in a window without relying on the WM_PAINT message-for example, when drawing and redrawing an object for a user who is using the mouse to drag or size the object. If a window has the WS_SYNCPAINT or CS_SYNCPAINT style, invalidating a portion of the window causes a WM_PAINT message to be sent to the window immediately. Essentially, sending a message is like making a function call; the actions corresponding to the WM_PAINT message are carried out before the call that caused the invalidation returns-that is to say, the painting is synchronous. If the window does not have the WS_SYNCPAINT or CS_SYNCPAINT style, invalidating a portion of the window causes the invalidated region to be added to the window's update region. The next time the application calls the WinGetMsg or WinPeekMsg functions, the application is sent a WM_PAINT message. If there are many messages in the queue, the painting occurs after the invalidation-that is, the painting is asynchronous. A WM_PAINT message is not posted to the queue in this case, so all invalidation operations since the last WM_PAINT message are consolidated into a single WM_PAINT message the next time the application has no messages in the queue. There are advantages to both synchronous and asynchronous painting. Windows that have simple painting functions should be painted synchronously. Most of the system-defined control windows, such as buttons and frame controls, are painted synchronously because they can be painted quickly without interfering with the responsiveness of the program. Windows that require more time-consuming painting operations should be painted asynchronously so that the painting can be initiated only when there are no other pending messages that might otherwise be blocked while waiting for the window to be painted. Also, a window that uses an incremental approach to invalidating small portions of itself usually should allow those operations to consolidate into a single asynchronous WM_PAINT message, rather than a series of synchronous WM_PAINT messages. If necessary, an application can call the WinUpdateWindow function to cause an asynchronous window to update itself without going through the event loop. WinUpdateWindow sends a WM_PAINT message directly to the window if the window's update region is not empty. ═══ 9.2.2. The WM_PAINT Message ═══ A window receives a WM_PAINT message whenever its update region is not NULL. A window procedure responds to a WM_PAINT message by calling the WinBeginPaint function, drawing to fill in the update areas, then calling the WinEndPaint function. The WinBeginPaint function returns a handle to a presentation space that is associated with the device context for the window and that has a visible region equal to the intersection of the window's update region and its visible region. This means that only those portions of the window that need to be redrawn are drawn. Attempts to draw outside this region are clipped and do not appear on the screen. If the application maintains its own presentation space for the window, it can pass the handle of that presentation space to WinBeginPaint, which modifies the visible region of the presentation space and passes the presentation-space handle back to the caller. If the application does not have its own presentation space, it can pass a NULL presentation-space handle and the system will return a cached-micro presentation space for the window. In either case, the application can use the presentation space to draw in the window. The WinBeginPaint function takes a pointer to a RECTL structure, filling in this structure with the coordinates of the rectangle that encloses the area to be updated. The application can use this rectangle to optimize drawing, by drawing only those portions of the window that intersect with the rectangle. If an application passes a NULL pointer for the rectangle argument, the application draws the entire window and relies on the clipping mechanism to filter out the unneeded areas. After the WinBeginPaint function sets the update region of a window to NULL, the application does the necessary drawing to fill the update areas. If an application handles a WM_PAINT message and does not call WinBeginPaint, or otherwise empty the update region, the application continues to receive WM_PAINT messages as long as the update region is not empty. After the application finishes drawing, it calls the WinEndPaint function to restore the presentation space to its former state. When a cached-micro presentation space is returned by WinBeginPaint, the presentation space is returned to the system for reuse. If the application supplies its own presentation space to WinBeginPaint, the presentation space is restored to its previous state. ═══ 9.2.2.1. Drawing the Minimized View ═══ When an application creates a standard frame window, it has the option of specifying an icon that the system uses to represent the application in its minimized state. Typically, if an icon is supplied, the system draws it in the minimized window and labels it with the name of the window. If the application does not specify the FS_ICON style for the window, the window receives a WM_PAINT message when it is minimized. The code in the window procedure that handles the WM_PAINT message can determine whether the frame window currently is minimized and draw accordingly. Notice that because the WS_MINIMIZED style is relevant only for the frame window, and not for the client window, the window procedure checks the frame window rather than the client window. The following code fragment shows how to draw a window in both the minimized and normal states: Uses Os2Def,Os2Base,Os2PmApi; Function ClientWndProc( hwnd : HWND, msg : ULONG, mp1 : MPARAM, mp2 : MPARAM):MRESULT; cdecl; Var Hps : HPS; (* Сsken var tom!! *) Rcl : RECTL; (* Сsken var tom!! *) FlStyle : ULONG; (* Сsken var tom!! *) Begin Case msg Of WM_PAINT: (* Check whether the frame window (client's parent window) is minimized. *) flStyle := WinQueryWindowULong(WinQueryWindow(hwnd, QW_PARENT), QWL_STYLE); If ((flStyle<>0) AND (WS_MINIMIZED)<>0) Then Begin . . (* Paint the minimized state. *) . End Else Begin . . (* Paint the normal state. *) . End; WinEndPaint(hps); ClientWndProc := 0; Exit End; End; ═══ 9.2.3. Drawing Without the WM_PAINT Message ═══ An application can draw in a window's presentation space without having received a WM_PAINT message. As long as there is a presentation space for the window, an application can draw into the presentation space and avoid intruding into other windows or the desktop. Applications that draw without using the WM_PAINT message typically call the WinGetPS function to obtain a cached-micro presentation space for the window and call the WinReleasePS function when they have finished drawing. An application also can use any of the other types of presentation spaces described in the following sections. ═══ 9.2.4. Three Types of Presentation Spaces ═══ All drawing must take place within a presentation space. The operating system provides three types of presentation spaces for drawing: normal, micro, and cached-micro presentation spaces. The normal presentation space provides the most functionality, allowing access to all the graphics functions of the operating system and enabling the application to draw to all device types. The normal presentation space is more difficult to use than the other two kinds of presentation spaces and it uses more memory. It is created by using the GpiCreatePS function and is destroyed by using the GpiDestroyPS function. The micro presentation space allows access to only a subset of the operating system graphics functions, but it uses less memory and is faster than a normal presentation space. The micro presentation space also enables the application to draw to all device types. It is created by using the GpiCreatePS function and destroyed by using the GpiDestroyPS function. The cached-micro presentation space provides the least functionality of the three kinds of presentation spaces, but it is the most efficient and easiest to use. The cached-micro presentation space draws only to the screen. It is created and destroyed by using either the WinBeginPaint and WinEndPaint functions or the WinGetPS and WinReleasePS functions. The following sections describe each of the types of presentation spaces, in detail, and suggest strategies for using each type in an application. All three kinds of presentation spaces can be used in a single application. Some windows, especially if they never will be printed, are best served by cached-micro presentation spaces. Other windows might require the more flexible services of micro or normal presentation spaces. ═══ 9.2.4.1. Normal Presentation Spaces ═══ The normal presentation space supports the full power of the operating system graphics, including retained graphics. The primary advantages of a normal presentation space over the other two presentation-space types are its support of all graphics functions and its ability to be associated with many kinds of device contexts. A normal presentation space can be associated with many different device contexts. Typically, this means that an application creates a normal presentation space and associates it with a window device context for screen display. When the user asks to print, the application associates the same presentation space with a printer device context. Later, the application can reassociate the presentation space with the window device context. A presentation space can be associated with only one device context at a time, but the normal presentation space enables the application to change the device context whenever necessary. When creating a normal presentation space, an application can associate it with a device context or defer the association to a later time. The GpiAssociate function associates a device context with a normal presentation space after the presentation space has been created. An application typically associates the normal presentation space with a device context when calling the GpiCreatePS function and, later, associates the presentation space with a different device context by calling GpiAssociate. To obtain a device context for a window, call the WinOpenWindowDC function. To obtain a device context for a device other than the screen, call the DevOpenDC function. An application typically creates a normal presentation space during initialization and uses it until termination. Each time the application receives a WM_PAINT message, it passes the handle of the normal presentation space as an argument to WinBeginPaint; this prevents the system from returning a cached-micro presentation space. The system modifies the visible region of the supplied normal presentation space and returns the presentation space to the application. This method enables the application to use the same presentation space for all the drawing in a specified window. Normal presentation spaces created using GpiCreatePS must be destroyed by calling GpiDestroyPS before the application terminates. Do not call WinReleasePS to release a presentation space obtained using GpiCreatePS. Before terminating, applications also must use DevCloseDC to close any device contexts opened using DevOpenDC. No action is necessary for device contexts obtained using WinOpenWindowDC, because the system automatically closes these device contexts when destroying the associated windows. ═══ 9.2.4.2. Micro Presentation Spaces ═══ The primary advantage of a micro presentation space over a cached-micro presentation space is that it can be used for printing as well as painting in a window. An application that uses a micro presentation space must explicitly associate it with a device context. This makes the micro presentation space useful for painting to a printer, a plotter, or an off-screen memory bit map. A micro presentation space does not support the full set of OS/2 graphics functions. Unlike a normal presentation space, a micro presentation space does not support retained graphics. An application that must display graphics or text in a window and print to a printer or plotter typically maintains two presentation spaces: one for the window and one for the printing device. The following figure shows how an application's graphics output can be routed through separate presentation spaces to produce a screen display and printed copy. An application creates a micro presentation space by calling the GpiCreatePS function. A device context must be supplied at the time the micro presentation space is created. An application typically creates a device context and then a presentation space. The following code fragment demonstrates this by obtaining a device context for a window and associating it with a new micro presentation space: hdc := WinOpenWindowDC(...); hps := GpiCreatePS(..., hdc, ..., GPIA_ASSOC); To create a micro presentation space for a device other than the screen, replace the call to the WinOpenWindowDC function with a call to the DevOpenDC function, which obtains a device context for a device other than the screen. Then the device context that is obtained by this call can be used as an argument to GpiCreatePS. An application typically creates a micro presentation space during initialization and uses it until termination. Each time the application receives a WM_PAINT message, it should pass the handle of the micro presentation space as an argument to the WinBeginPaint function; this prevents the system from returning a cached-micro presentation space. The system modifies the visible region of the supplied micro presentation space and returns the presentation space to the application. This method enables the application to use the same presentation space for all drawing in a specified window. Micro presentation spaces created by using GpiCreatePS should be destroyed by calling GpiDestroyPS before the application terminates. Do not call the WinReleasePS function to release a presentation space obtained by using GpiCreatePS. Before terminating, applications must use the DevCloseDC function to close any device contexts opened using the DevOpenDC function. No action is necessary for device contexts obtained using WinOpenWindowDC, because the system automatically closes these device contexts when destroying the associated windows. ═══ 9.2.4.3. Cached-Micro Presentation Spaces ═══ The cached-micro presentation space provides the simplest and most efficient drawing environment. It can be used only for drawing on the screen, typically in the context of a window. It is most appropriate for application tasks that require simple window-drawing functions that will not be printed. Cached-micro presentation spaces do not support retained graphics. After an application draws to a cached-micro presentation space, the drawing commands are routed through an implied device context to the current display. The application does not require information about the actual device context, because the device context is assumed to be the display. This process makes cached-micro presentation spaces easy for applications to use. The following code fragment illustrates this process: Uses Os2Def,Os2Base,Os2PmApi; Var Hps : HPS; (* Сsken var tom!! *) Begin (* Case Of *) WM_PAINT: hps = WinBeginPaint(hwnd,nil,nil); (* * Use PS. *) WinEndPaint (hps); or Uses Os2Def,Os2Base,Os2PmApi; Var Hps : HPS; (* Сsken var tom!! *) Begin (* Case Of *) WM_PAINT: hps = WinGetPS(hwnd); (* * Use PS. *) WinReleasePS(hps); End. There are two common strategies for using cached-micro presentation spaces in an application. The simplest strategy is to call the WinBeginPaint function during the WM_PAINT message, use the resulting cached-micro presentation space to draw in the window, then return the presentation space to the system by calling the WinEndPaint function. By using this method, the application interacts with the presentation space only when drawing in the presentation space. This method is most appropriate for simple drawing. A disadvantage of this method is that the application must set up any special attributes for the presentation space, such as line color and font, each time a new presentation space is obtained. A second strategy is for the application to allocate a cached-micro presentation space during initialization, by calling the WinGetPS function and saving the resulting presentation-space handle in a static variable. Then the application can set attributes in the presentation space that exist for the life of the program. The presentation-space handle can be used as an argument to the WinBeginPaint function each time the window gets a WM_PAINT message; the system modifies the visible region and returns the presentation space to the application with its attributes intact. This strategy is appropriate for applications that need to customize their window-drawing attributes. A presentation space that is obtained by calling the WinGetPS function must be released by calling WinReleasePS when the application has finished using it, typically during program termination. A presentation space that is obtained by calling WinBeginPaint must be released by calling WinEndPaint, typically as the last part of processing a WM_PAINT message. ═══ 10. Resource Files ═══ Resource files enable you to specify the resource information used in creating an application's window. Some examples of resources that can be defined in resource files are:  Menus  Accelerator tables  Dialog and window templates  Icons  Fonts  Bit maps  Strings To add resource information to an application, use a text editor to create a resource script file, and then compile it using the Resource Compiler, RC.EXE. The advantage of using resource files is that resource information can be maintained and updated separately in the resource script file and then linked to your application program's .EXE file. This greatly simplifies customizing an application because you can modify resource information without having to recompile the entire application. This chapter describes the use of resource files in Presentation Manager (PM) programming. ═══ 10.1. About Resource Files ═══ A resource script file is a text file that contains one or more resource statements that define the type, identifier, and data for each resource. Because some resources might contain binary data that cannot be created using a text editor, there are resource statements that let you specify additional files to include when compiling the resource script file. For example, you can use the Dialog Box Editor to design dialog boxes, the Font Editor to edit font files, and the Icon Editor to create customized icons, pointers, and bit maps. The definitions for these resources can be included with other resource definitions in the resource file. ═══ 10.1.1. Resource Statements ═══ This section provides overview information on resource statements and directives. Resource statements consist of one or more keywords, numbers, character strings, constants, or file names. You combine these to define the resource type, identifier, and data. Directives are special types of resource statements that perform functions such as including header files, defining constants, and conditionally compiling portions of the file. Resource statements have three basic forms:  Single-line statements  Multiple-line statements  Directives ═══ 10.1.1.1. Single-line Statements ═══ Single-line statements consist of a keyword identifying the resource type, a constant or number specifying the resource identifier, and a file name specifying the file containing the resource data. For example, this ICON statement defines an icon resource: ICON 1 myicon.ico The icon resource has the icon identifier 1, and the file MYICON.ICO contains the icon data. ═══ 10.1.1.2. Multiple-line Statements ═══ Multiple-line statements consist of a keyword identifying the resource type, a constant or number specifying the resource identifier, and, between the BEGIN and END keywords, additional resource statements that define the resource data. For example, this MENU statement defines a menu resource: MENU 1 BEGIN MENUITEM "Alpha", 101 MENUITEM "Beta", 102 END The menu identifier is 1. The menu contains two MENUITEM statements that define the contents of the menu. In multiple-line statements such as DLGTEMPLATE and WINDOWTEMPLATE, any level of nested statements is allowed. For example, the DLGTEMPLATE and WINDOWTEMPLATE statements typically contain a single DIALOG or FRAME statement. These statements can contain any number of WINDOW and CONTROL statements; the WINDOW and CONTROL statements can contain additional WINDOW and CONTROL statements, and so forth. The nested statements let you define controls and other child windows for the dialog boxes and windows. If a nested statement creates a child window or control, the parent and owner of the new window is the window created by the containing statement. (FRAME statements occasionally create frame controls whose parent and owner windows are not the same.) ═══ 10.1.1.3. Directives ═══ Directives consist of the reserved character # in the first column of a line, followed by the directive keyword and any additional numbers, character strings, or file names. Some examples of directives are:  #define  #if  #ifdef  #include Descriptions of the individual directives follow the resource file statement descriptions. ═══ 10.1.2. Resource File Statement Descriptions ═══ This section provides the syntax, description, and an example of each of the resource file statements. The following table summarizes, at a general level, the most commonly used parameters on the statements. ┌────────────┬────────────────────────────────────────────────┐ │Parameter │Description │ ├────────────┼────────────────────────────────────────────────┤ │id │Control identifier. │ ├────────────┼────────────────────────────────────────────────┤ │x │X coordinate of the lower-left corner of the │ │ │control. │ ├────────────┼────────────────────────────────────────────────┤ │y │Y coordinate of the lower-left corner of the │ │ │control. │ ├────────────┼────────────────────────────────────────────────┤ │height │Height of the control ( in 1/8 character units).│ ├────────────┼────────────────────────────────────────────────┤ │width │Width of the control. │ ├────────────┼────────────────────────────────────────────────┤ │style │Predefined bit representation of a style or │ │ │combination of styles. │ ├────────────┼────────────────────────────────────────────────┤ │load option │Definition of when the system should load the │ │ │resource into memory (for example, PRELOAD or │ │ │LOADONCALL). │ ├────────────┼────────────────────────────────────────────────┤ │mem option │Definition of how the system manages the │ │ │resource when in memory (for example, FIXED, │ │ │MOVABLE, or DISCARDABLE). │ ├────────────┼────────────────────────────────────────────────┤ │text │Text associated with a control. │ ├────────────┼────────────────────────────────────────────────┤ │class │Predefined class for a particular control. │ └────────────┴────────────────────────────────────────────────┘ ═══ 10.1.2.1. ACCELTABLE Statement ═══ The ACCELTABLE statement creates a table of accelerators for an application. ═══ 10.1.2.1.1. Syntax ═══ ACCELTABLE acceltable-id [mem-option][load-option] BEGIN key-value, command[, accelerator-options] ... . . . END ═══ 10.1.2.1.2. Description ═══ An accelerator is a keystroke that gives the user a quick way to choose a command from a menu or carry out some other task. An accelerator table can be loaded when needed from the executable file by using the WinLoadAccelTable function. ═══ 10.1.2.1.3. Example ═══ This example creates an accelerator table whose accelerator-table identifier is 1. The table contains two accelerators: Ctrl+S and Ctrl+G. These accelerators generate WM_COMMAND messages with values of 101 and 102, respectively, when the user presses the corresponding keys. ACCELTABLE 1 BEGIN "S", 101, CONTROL "G", 102, CONTROL END ═══ 10.1.2.2. ASSOCTABLE Statement ═══ The ASSOCTABLE statement defines a file-association table for an application. ═══ 10.1.2.2.1. Syntax ═══ ASSOCTABLE assoctable-id [load-option][mem-option] BEGIN association-name, file-match-string[, extended-attribute-flag] [, icon-filename] . . . END ═══ 10.1.2.2.2. Description ═══ This table associates the data files that an application creates with the executable file of the application. When the user selects one of these data files, the associated application begins executing. A file-association table can also associate icons with the data files that an application creates. The icons are used to identify the data files graphically. Because a file-association table associates icons by file type, all data files having the same file type have the same icon. You can provide any number of ASSOCTABLE statements in a resource script file, but each statement must specify a unique assoctable-id value. The file-association tables are written not only to the resources within your executable file, but also to the .ASSOC extended attribute. However, only the last file-association table specified in the resource script file is actually written to the extended attribute. ═══ 10.1.2.3. AUTOCHECKBOX Statement ═══ The AUTOCHECKBOX statement creates an automatic-check-box control. ═══ 10.1.2.3.1. Syntax ═══ AUTOCHECKBOX text, id, x, y, width [, style] ═══ 10.1.2.3.2. Description ═══ The control is a small rectangle (check box) that contains an X when the user selects it. The specified text is displayed to the right of the check box. An X appears in the square when the user first selects the control and disappears the next time the user selects it. The AUTOCHECKBOX statement, which can only be used in a DIALOG or WINDOW statement, defines the text, identifier, dimensions, and attributes of a control window. The predefined class for this control is WC_BUTTON. If the style is not specified, the default style is BS_AUTOCHECKBOX and WS_TABSTOP. ═══ 10.1.2.3.3. Example ═══ This example creates an automatic-check-box control that is labeled "Italic." AUTOCHECKBOX "Italic", 101, 10, 10, 100, 100 ═══ 10.1.2.4. AUTORADIOBUTTON Statement ═══ The AUTORADIOBUTTON statement creates an automatic-radio-button control. ═══ 10.1.2.4.1. Syntax ═══ AUTORADIOBUTTON text, id, x, y, width, height [, style] ═══ 10.1.2.4.2. Description ═══ This control is a small circle with the given text displayed to its right. The control highlights the circle and sends a message to its parent window when the user selects the button. The control also removes the selection from any other automatic-radio-button controls in the same group. When the user selects the button again, the control removes the highlight before sending a message. The AUTORADIOBUTTON statement, which you can use only in a DIALOG or WINDOW statement, defines the text, identifier, dimensions, and attributes of a control window. The predefined class for this control is WC_BUTTON. If you do not specify a style, the default style is BS_AUTORADIOBUTTON. ═══ 10.1.2.4.3. Example ═══ This example creates an automatic-radio-button control that is labeled "Italic." AUTORADIOBUTTON "Italic", 101, 10, 10, 24, 50 ═══ 10.1.2.5. BITMAP Statement ═══ The BITMAP statement defines a bit-map resource for an application. ═══ 10.1.2.5.1. Syntax ═══ BITMAP bitmap-id [load-option] [mem-option] filename ═══ 10.1.2.5.2. Description ═══ A bit-map resource, typically created using the Icon Editor, is a custom bit map that an application uses in its display or as an item in a menu. The BITMAP statement copies the bit-map resource from the file specified in the filename field and adds it to the application's other resources. A bit-map resource can be loaded from the executable file when needed by using the GpiLoadBitmap function. You can provide any number of BITMAP statements in a resource script file, but each statement must specify a unique bitmap-id value. ═══ 10.1.2.5.3. Example ═══ This example defines a bit map whose bit-map identifier is 12. The bit-map resource is copied from the file CUSTOM.BMP. BITMAP 12 custom.bmp ═══ 10.1.2.6. CHECKBOX Statement ═══ The CHECKBOX statement creates a check-box control. ═══ 10.1.2.6.1. Syntax ═══ CHECKBOX text, id, x, y, width, height [, style] ═══ 10.1.2.6.2. Description ═══ The control is a small rectangle (check box) that has the specified text displayed to the right. The control highlights the rectangle and sends a message to its parent window when the user selects the control. The CHECKBOX statement, which you can use only in a DIALOG or WINDOW statement, defines the text, identifier, dimensions, and attributes of a control window. The predefined class for this control is WC_BUTTON. If you do not specify a style, the default style is BS_CHECKBOX and WS_TABSTOP. ═══ 10.1.2.6.3. Example ═══ This example creates a check-box control that is labeled "Italic." CHECKBOX "Italic", 101, 10, 10, 100, 100 ═══ 10.1.2.7. CODEPAGE Statement ═══ The CODEPAGE statement sets the code page for all subsequent resources. ═══ 10.1.2.7.1. Syntax ═══ CODEPAGE codepage-id ═══ 10.1.2.7.2. Description ═══ The code page specifies the character set used for characters in the resource. If the CODEPAGE statement is not given in a resource script file, the resource compiler uses the code page set up for the individual system. If more than one CODEPAGE statement is given in the file, each CODEPAGE statement applies to the resource statements between it and the next CODEPAGE statement. ═══ 10.1.2.7.3. Example ═══ In this example, the code page for the character-string resources is set to Portuguese (860). CODEPAGE 860 STRINGTABLE BEGIN 1 "Filename not found" 2 "Cannot open file for reading" END ═══ 10.1.2.8. COMBOBOX Statement ═══ The COMBOBOX statement creates a combination-box control. ═══ 10.1.2.8.1. Syntax ═══ COMBOBOX text, id, x, y, width, height [, style] ═══ 10.1.2.8.2. Description ═══ This control combines a list-box control with an entry-field control. It allows the user to place the selected item from a list box into an entry field. The COMBOBOX statement, which you can use only in a DIALOG or WINDOW statement, defines the text, identifier, dimensions, and attributes of a control window. The predefined class for this control is WC_COMBOBOX. If you do not specify a style, the default style is CBS_SIMPLE, WS_GROUP, WS_TABSTOP, and WS_VISIBLE. ═══ 10.1.2.8.3. Example ═══ This example creates a combination-box control. COMBOBOX "", 101, 10, 10, 24, 50 ═══ 10.1.2.9. CONTAINER Statement ═══ The CONTAINER statement creates a container control within a dialog window. ═══ 10.1.2.9.1. Syntax ═══ CONTAINER id, x, y, width, height [, style] ═══ 10.1.2.9.2. Description ═══ The container control is a visual component that holds objects. The CONTAINER statement defines the identifier, position, dimensions, and attributes of a container control. The predefined class for this control is WC_CONTAINER. If you do not specify a style, the default style is WS_TABSTOP, WS_VISIBLE, and CCS_SINGLESEL. A CONTAINER statement is only used in a DIALOG or WINDOW statement. ═══ 10.1.2.9.3. Example ═══ This example creates a container control at position (30,30) within the dialog window. The container has a width of 70 character units and a height of 25 character units. Its resource ID is 301. The default style CCS_SINGLESEL has been overridden by the style specification CCS_MULTIPLESEL. The default styles WS_TABSTOP and WS_GROUP are both in effect, though only the latter is specified. Const IDC_CONTAINER = 301; IDD_CONTAINERDLG = 504; DIALOG "Container", IDD_CONTAINERDLG, 23, 6, 120, 280, FS_NOBYTEALIGN Or WS_VISIBLE, FCF_SYSMENU Or FCF_TITLEBAR BEGIN CONTAINER IDC_CONTAINER, 30, 30, 70, 200, CCS_MULTIPLESEL Or WS_GROUP END ═══ 10.1.2.10. CONTROL Statement ═══ The CONTROL statement defines a control as belonging to the specified class. ═══ 10.1.2.10.1. Syntax ═══ CONTROL text, id, x, y, width, height, class [, style] [ data-definitions ] ... [ BEGIN control-definition . . . END ] ═══ 10.1.2.10.2. Description ═══ The statement defines the position and dimensions of the control within the parent window, as well as the control style. The CONTROL statement is most often used in a DIALOG or WINDOW statement. Typically, several CONTROL statements are used in each DIALOG statement, and each CONTROL statement must have a unique id value. The optional BEGIN and END statements enclose any CONTROL statements that may be given with the control. CONTROL statements given in this manner represent child windows belonging to the control created by the CONTROL statement. The CONTROL statement can actually contain any combination of CONTROL, DIALOG, and WINDOW statements, but it usually does not contain such statements. ═══ 10.1.2.10.3. Example ═══ This example creates a push-button control with the WS_TABSTOP and WS_VISIBLE styles. CONTROL "OK", 101, 10, 10, 20, 50, WC_BUTTON, BS_PUSHBUTTON Or WS_TABSTOP Or WS_VISIBLE ═══ 10.1.2.11. CTEXT Statement ═══ The CTEXT statement creates a centered-text control. ═══ 10.1.2.11.1. Syntax ═══ CTEXT text, id, x, y, width, height [, style] ═══ 10.1.2.11.2. Description ═══ The control is a simple rectangle displaying the given text centered in the rectangle. The text is formatted before it is displayed. Words that would extend past the end of a line are automatically wrapped to the beginning of the next line. The CTEXT statement defines the text, identifier, dimensions, and attributes of the control. The predefined class for this control is WC_STATIC. If you do not specify a style, the default style is SS_TEXT, DT_CENTER, and WS_GROUP. Use the CTEXT statement only in a DIALOG or WINDOW statement. ═══ 10.1.2.11.3. Example ═══ This example creates a centered-text control that is labeled "Filename." CTEXT "Filename", 101, 10, 10, 100, 100 ═══ 10.1.2.12. CTLDATA Statement ═══ The CTLDATA statement defines control data for a custom dialog box, window, or control. ═══ 10.1.2.12.1. Syntax ═══ CTLDATA word-value [, word-value] ... CTLDATA string CTLDATA MENU BEGIN menuitem-definition . . . END ═══ 10.1.2.12.2. Description ═══ The statement has three basic forms to permit specifying a menu or specifying data in words or characters. The data can be in any format, because only your window procedure will use it. The window procedure of the dialog box, window, or control receives this data when the item is created. It is up to the window procedure to process the data. CTLDATA is often used to supply data that controls the subsequent operation of the custom window. For example, the CTLDATA statement may contain extended style bits - that is, style bits designed specifically for your customized window. You should reserve the CTLDATA statement for window classes that you create yourself. ═══ 10.1.2.12.3. Example ═══ This example creates a menu for the window created with the WINDOW statement. WINDOWTEMPLATE 1 BEGIN WINDOW "Sample", 1, 0, 0, 100, 100, "MYCLASS", 0, FCF_STANDARD CTLDATA MENU BEGIN MENUITEM "Exit", 101 END END ═══ 10.1.2.13. DEFAULTICON Statement ═══ This statement installs the named icon file definition under the ICON Extended Attribute of the program file. ═══ 10.1.2.13.1. Syntax ═══ DEFAULTICON filename ═══ 10.1.2.13.2. Description ═══ An icon with an icon-id of 1 is the default icon by default, unless you supply a different icon. ═══ 10.1.2.13.3. Example ═══ DEFAULTICON filename.ico ═══ 10.1.2.14. DEFPUSHBUTTON Statement ═══ The DEFPUSHBUTTON statement creates a default push-button control. ═══ 10.1.2.14.1. Syntax ═══ DEFPUSHBUTTON text, id, x, y, width, height [, style] ═══ 10.1.2.14.2. Description ═══ The control is a round-cornered rectangle containing the given text. The rectangle has a bold outline to represent that it is the default response for the user. The control sends a message to its parent window when the user chooses the control. The DEFPUSHBUTTON statement defines the text, identifier, dimensions, and attributes of the control. The predefined class for this control is WC_BUTTON. If you do not specify a style, the default style is BS_PUSHBUTTON, BS_DEFAULT, and WS_TABSTOP. Use the DEFPUSHBUTTON statement only in a DIALOG or WINDOW statement. ═══ 10.1.2.14.3. Example ═══ This example creates a default push-button control that is labeled "Cancel." DEFPUSHBUTTON "Cancel", 101, 10, 10, 24, 50 ═══ 10.1.2.15. DIALOG Statement ═══ The DIALOG statement defines a window that an application can use to create dialog boxes. ═══ 10.1.2.15.1. Syntax ═══ DIALOG text, id, x, y, width, height [, [style] [,framectl]] [data-definitions] BEGIN control-definition . . . END ═══ 10.1.2.15.2. Description ═══ The statement defines the position and dimensions of the dialog box on the screen, as well as the dialog-box style. The DIALOG statement is most often used in a DLGTEMPLATE statement. Typically, you use only one DIALOG statement in each DLGTEMPLATE statement, and the DIALOG statement contains at least one control definition. The exact meaning of the coordinates depends on the style defined by the style field. For dialog boxes with FS_SCREENALIGN style, the coordinates are relative to the origin of the display screen. For dialog boxes with the style FS_MOUSEALIGN, the coordinates are relative to the position of the mouse pointer at the time the dialog box is created. For all other dialog boxes, the coordinates are relative to the origin of the parent window. The DIALOG statement can actually contain any combination of CONTROL, DIALOG, and WINDOW statements. Typically, a DIALOG statement contains one or more CONTROL statements. ═══ 10.1.2.15.3. Example ═══ This example creates a dialog box that is labeled "Disk Error." DLGTEMPLATE 1 BEGIN DIALOG "Disk Error", 100, 10, 10, 300, 110 BEGIN CTEXT "Select One:", 1, 10, 80, 280, 12 RADIOBUTTON "Retry", 2, 75, 50, 60, 12 RADIOBUTTON "Abort", 3, 75, 30, 60, 12 RADIOBUTTON "Ignore", 4, 75, 10, 60, 12 END END ═══ 10.1.2.16. DLGINCLUDE Statement ═══ The DLGINCLUDE statement adds the specified file name to the resource file. ═══ 10.1.2.16.1. Syntax ═══ DLGINCLUDE id filename ═══ 10.1.2.16.2. Description ═══ The DLGINCLUDE statement is typically used to let the application access the definitions file for the dialog box with the corresponding identifier. The file specified in the filename field must contain the define directives used by the dialog box. You can provide any number of DLGINCLUDE statements in a resource script file, but each must have a unique identifier. ═══ 10.1.2.16.3. Example ═══ This example includes the name of the definition file dlgdef.h. The dialog-box identifier is 5. DLGINCLUDE 5 &bsl.&bsl.INCLUDE&bsl.&bsl.DLGDEF.H ═══ 10.1.2.17. DLGTEMPLATE Statement ═══ The DLGTEMPLATE statement creates a dialog-box template. ═══ 10.1.2.17.1. Syntax ═══ DLGTEMPLATE dialog-id [load-option] [mem-option] BEGIN dialog-definition . . . END ═══ 10.1.2.17.2. Description ═══ A dialog-box template consists of a series of statements that define the identifier, load and memory options, dialog-box dimensions, and controls in the dialog box. The dialog-box template can be loaded from the executable file by using the WinLoadDlg function. You can provide any number of dialog-box templates in a resource script file, but each template must have a unique dialog-id value. A DLGTEMPLATE statement can actually contain DIALOG, CONTROL, and WINDOW statements. Typically, you include only one DIALOG statement. ═══ 10.1.2.17.3. Example ═══ This example uses a DLGTEMPLATE statement to create a dialog box. DLGTEMPLATE ID_GETTIMER BEGIN DIALOG "Timer", 1, 10, 10, 100, 40 BEGIN LTEXT "Time (0 - 15):", 4, 8, 24, 72, 12 ENTRYFIELD "0", ID_TIME, 80, 28, 16, 8, ES_MARGIN DEFPUSHBUTTON "Enter", ID_TIMEOK, 10, 6, 36, 12 PUSHBUTTON "Cancel", ID_TIMECANCEL, 52, 6, 40, 12 END END ═══ 10.1.2.18. EDITTEXT Statement ═══ The EDITTEXT statement creates an entry-field control. ═══ 10.1.2.18.1. Syntax ═══ EDITTEXT text, id, x, y, width, height [, style] ═══ 10.1.2.18.2. Description ═══ This control is a rectangle in which the user can type and edit text. The control displays a pointer when the user selects the control. The user can then use the keyboard to enter text or edit the existing text. Editing keys include the BACKSPACE and DELETE keys. By using the mouse or the DIRECTION keys, the user can select the characters to delete or select the place to insert new characters. The EDITTEXT statement defines the text, identifier, dimensions, and attributes of a control window. The predefined class for this control is WC_ENTRYFIELD. If you do not specify a style, the default style is ES_AUTOSCROLL and WS_TABSTOP. The EDITTEXT control statement is identical to the ENTRYFIELD control statement. Use the EDITTEXT statement only in a DIALOG or WINDOW statement. ═══ 10.1.2.18.3. Example ═══ This example creates an entry-field control that is not labeled. EDITTEXT "", 101, 10, 10, 24, 50 ═══ 10.1.2.19. ENTRYFIELD Statement ═══ The ENTRYFIELD statement creates an entry-field control. ═══ 10.1.2.19.1. Syntax ═══ ENTRYFIELD text, id, x, y, width, height [, style] ═══ 10.1.2.19.2. Description ═══ This control is a rectangle in which the user can type and edit text. The control displays a pointer when the user selects the control. The user can then use the keyboard to enter text or edit the existing text. Editing keys include the BACKSPACE and DELETE keys. By using the mouse or the DIRECTION keys, the user can select the characters to delete or select the place to insert new characters. The ENTRYFIELD statement, which you can use only in a DIALOG or WINDOW statement, defines the text, identifier, dimensions, and attributes of a control window. The predefined class for this control is WC_ENTRYFIELD. If you do not specify a style, the default style is ES_AUTOSCROLL and WS_TABSTOP. ═══ 10.1.2.19.3. Example ═══ This example creates an entry-field control that is not labeled. ENTRYFIELD "", 101, 10, 10, 24, 50 ═══ 10.1.2.20. FONT Statement ═══ The FONT statement defines a font resource for an application. ═══ 10.1.2.20.1. Syntax ═══ FONT font-id [load-option] [mem-option] filename ═══ 10.1.2.20.2. Description ═══ A font resource, typically created by using the OS/2 Font Editor, is a bit map defining the shape of the individual characters in a character set. The FONT statement copies the font resource from the file specified in the filename field and adds it to the other resources of the application. A font resource can be loaded from the executable file when needed by using the GpiLoadFonts function. You can provide any number of FONT statements in a resource script file, but each statement must specify a unique font-id value. ═══ 10.1.2.20.3. Example ═══ This example defines a font whose font identifier is 5. The font resource is copied from the file cmroman.fon. FONT 5 cmroman.fon ═══ 10.1.2.21. FRAME Statement ═══ The FRAME statement defines a frame window. ═══ 10.1.2.21.1. Syntax ═══ FRAME text, id, x, y, width, height, style [, framectl] data-definitions [ BEGIN window-definition . . . END ] ═══ 10.1.2.21.2. Description ═══ The statement defines the title, identifier, position, and dimensions of the frame window, as well as the window style. The FRAME statement is most often used in a WINDOWTEMPLATE statement and, typically, only one FRAME statement is used. The FRAME statement, in turn, typically contains at least one WINDOW statement that defines the client window belonging to the frame window. The frame window has no default style. You must use the framectl field to define additional frame controls, such as a title bar and system menu, to be created when the frame window is created. If the text field is not empty, the statement automatically adds a title-bar control to the frame window, whether or not you specify the FCF_TITLEBAR style. Frame controls are given default styles and control identifiers, depending on their class. For example, a title-bar control receives the identifier FID_TITLEBAR. The FRAME statement can actually contain any combination of CONTROL, DIALOG, and WINDOW statements. Typically, a FRAME statement contains one WINDOW statement. ═══ 10.1.2.21.3. Example ═══ This example creates a standard frame window with a title bar, a system menu, minimize and maximize boxes, and a vertical scroll bar. The FRAME statement contains a WINDOW statement defining the client window belonging to the frame window. WINDOWTEMPLATE 1 BEGIN FRAME "My Window", 1, 10, 10, 320, 130, 0, FCF_STANDARD Or FCF_VERTSCROLL BEGIN WINDOW "", FID_CLIENT, 0, 0, 0, 0, "MyClientClass" END END ═══ 10.1.2.22. GROUPBOX Statement ═══ The GROUPBOX statement creates a group-box control. ═══ 10.1.2.22.1. Syntax ═══ GROUPBOX text, id, x, y, width, height [, style] ═══ 10.1.2.22.2. Description ═══ The control is a rectangle that groups other controls together by drawing a border around them and displaying the given text in the upper-left corner. The GROUPBOX statement defines the text, identifier, dimensions, and attributes of a control window. The predefined class for this control is WC_STATIC. If you do not specify a style, the default style is SS_GROUPBOX and WS_TABSTOP. Use the GROUPBOX statement only in a DIALOG or WINDOW statement. ═══ 10.1.2.22.3. Example ═══ This example creates a group-box control that is labeled "Options." GROUPBOX "Options", 101, 10, 10, 100, 100 ═══ 10.1.2.23. HELPITEM Statement ═══ The HELPITEM statement defines the help items in a help table. ═══ 10.1.2.23.1. Syntax ═══ HELPITEM application-window-id, help-subtable-id, extended-helppanel-id ═══ 10.1.2.23.2. Description ═══ This statement specifies the resource identifier of an application window for which help is provided, along with the resource identifiers of the help subtable and extended help panel associated with the application window. You can provide any number of HELPITEM statements in a HELPTABLE statement. You should provide one HELPITEM statement for each application window for which help is provided. Use the HELPITEM statement only in a HELPTABLE statement. ═══ 10.1.2.23.3. Example ═══ This example defines a help item that associates a help subtable called IDSUB_FILEMENU and an extended help panel called IDEXT_APPHLP with an application window called IDWIN_FILEMENU. HELPITEM IDWIN_FILEMENU, IDSUB_FILEMENU, IDEXT_APPHLP ═══ 10.1.2.24. HELPSUBITEM Statement ═══ The HELPSUBITEM statement defines the help subitems in a help subtable. ═══ 10.1.2.24.1. Syntax ═══ HELPSUBITEM child-window-id, helppanel-id [, integer] ... ═══ 10.1.2.24.2. Description ═══ This statement specifies the identifier of a child window for which help is provided, the identifier of the help panel associated with the child window, and one or more optional, application-defined integers. You can provide any number of HELPSUBITEM statements in a HELPSUBTABLE statement. You should provide one HELPSUBITEM statement for each child window for which help is provided. Use the HELPSUBITEM statement only in a HELPSUBTABLE statement. ═══ 10.1.2.24.3. Example ═══ This example defines a help subitem that associates a child window called IDCLD_FILEMENU with a help panel called IDHP_FILEMENU. HELPSUBITEM IDCLD_FILEMENU, IDHP_FILEMENU ═══ 10.1.2.25. HELPSUBTABLE Statement ═══ The HELPSUBTABLE statement defines the contents of a help-subtable resource. ═══ 10.1.2.25.1. Syntax ═══ HELPSUBTABLE helpsubtable-id [SUBITEMSIZE size] BEGIN helpsubitem-definition . . . END ═══ 10.1.2.25.2. Description ═══ A help-subtable resource contains a help-subitem entry for each item that can be selected in an application window. Each of these items should be a child window of the application window specified in the help-table resource. The help subtable should contain a help subitem for each control, child window, and menu item in the application window. You can provide any number of HELPSUBTABLE statements in a resource script file, but each statement must specify a unique helpsubtable-id value. You can also provide any number of helpsubitem-definition statements in the help subtable. These specify the child window for which help is provided, the help panel containing the help text for the child window, and one or more application-defined integers. If you include optional integers in the helpsubitem-definition statements, you must also include a SUBITEMSIZE statement to specify the size, in words, of each help subitem. All help subitems in a help subtable must be the same size. The default size is two words per help subitem. ═══ 10.1.2.25.3. Example ═══ This example creates a help-subtable resource whose help-subtable identifier is IDSUB_FILEMENU. Each HELPSUBITEM statement specifies a child window and a help panel. HELPSUBTABLE IDSUB_FILEMENU BEGIN HELPSUBITEM IDCLD_OPEN, IDPNL_OPEN HELPSUBITEM IDCLD_SAVE, IDPNL_SAVE END ═══ 10.1.2.26. HELPTABLE Statement ═══ The HELPTABLE statement defines the contents of a help-table resource. ═══ 10.1.2.26.1. Syntax ═══ HELPTABLE helptable-id BEGIN helpitem-definition . . . END ═══ 10.1.2.26.2. Description ═══ A help-table resource contains a help-item entry for each application window, dialog box, and message box for which help is provided. You can provide any number of HELPTABLE statements in a resource script file, but each statement must specify a unique helptable-id value. You can also provide any number of helpitem-definition statements in the help table. These statements specify the application windows for which help is provided, the help subtables associated with each application window, and the extended help panels associated with each application window. ═══ 10.1.2.26.3. Example ═══ This example creates a help-table resource whose help-table identifier is 1. Each HELPITEM statement specifies an application window, a help subtable, and an extended help panel. HELPTABLE 1 BEGIN HELPITEM IDWIN_FILEMENU, IDSUB_FILEMENU, IDEXT_APPHLP HELPITEM IDWIN_EDITMENU, IDSUB_EDITMENU, IDEXT_APPHLP END ═══ 10.1.2.27. ICON Statement (Resource) ═══ This form of the ICON statement defines an icon resource for an application. ═══ 10.1.2.27.1. Syntax ═══ ICON icon-id [load-option] [mem-option] filename ═══ 10.1.2.27.2. Description ═══ An icon resource, typically created by using the Icon Editor, is a bit map defining the shape of the icon to be used for a given application. The ICON statement copies the icon resource from the file specified in the filename field and adds it to the application's other resources. An icon resource can be loaded when creating a window by using the WinCreateStdWindow function with the FS_ICON style. You can provide any number of ICON statements in a resource script file, but each statement must specify a unique icon-id value. An icon with an icon-id of 1 is the default icon. The RC program writes the icon not only to the resources in your executable file but also as the .ICON extended attribute. ═══ 10.1.2.27.3. Example ═══ This example defines an icon whose icon identifier is 11. The icon resource is copied from the file custom.ico. ICON 11 custom.ico ═══ 10.1.2.28. ICON Statement (Control) ═══ This form of the ICON statement creates an icon control. ═══ 10.1.2.28.1. Syntax ═══ ICON icon-id, id, x, y, width, height [, style] ═══ 10.1.2.28.2. Description ═══ This control is an icon displayed in a dialog box. The ICON statement defines the icon-resource identifier, icon-control identifier, and position and attributes of a control window. The predefined class for this control is WC_STATIC. If you do not specify a style, the default style is SS_ICON. For the ICON statement, the width and height fields are ignored; the icon automatically sizes itself. Use the ICON statement only in a DIALOG or WINDOW statement. ═══ 10.1.2.28.3. Example ═══ This example creates an icon control whose icon identifier is 99. ICON 99, 101, 10, 10, 0, 0 ═══ 10.1.2.29. LISTBOX Statement ═══ The LISTBOX statement creates commonly-used controls for a dialog box or window. ═══ 10.1.2.29.1. Syntax ═══ LISTBOX id, x, y, width, height [, style] ═══ 10.1.2.29.2. Description ═══ The control is a rectangle containing a list of user-selectable strings, such as file names. The LISTBOX statement defines the identifier, dimensions, and attributes of a control window. The predefined class for this control is WC_LISTBOX. If you do not specify a style, the default style is WS_TABSTOP. Use the LISTBOX statement only in a DIALOG or WINDOW statement. ═══ 10.1.2.29.3. Example ═══ This example creates a list-box control whose identifier is 101. LISTBOX 101, 10, 10, 100, 100 ═══ 10.1.2.30. LTEXT Statement ═══ The LTEXT statement creates a left-aligned text control. ═══ 10.1.2.30.1. Syntax ═══ LTEXT text, id, x, y, width, height [, style] ═══ 10.1.2.30.2. Description ═══ The control is a simple rectangle displaying the given text left-aligned in the rectangle. The text is formatted before it is displayed. Words that would extend past the end of a line are automatically wrapped to the beginning of the next line. The LTEXT statement defines the text, identifier, dimensions, and attributes of the control. The predefined class for this control is WC_STATIC. If you do not specify a style, the default style is SS_TEXT, DT_LEFT, and WS_GROUP. Use the LTEXT statement only in a DIALOG or WINDOW statement. ═══ 10.1.2.30.3. Example ═══ This example creates a left-aligned text control that is labeled "Filename." LTEXT "Filename", 101, 10, 10, 100, 100 ═══ 10.1.2.31. MENU Statement ═══ The MENU statement defines the contents of a menu resource. ═══ 10.1.2.31.1. Syntax ═══ MENU menu-id [load-option] [mem-option] BEGIN menuitem-definition . . . END ═══ 10.1.2.31.2. Description ═══ A menu resource is a collection of information that defines the appearance and function of an application menu. A menu is a special input tool that lets a user choose commands from a list of command names. A menu resource can be loaded from the executable file when needed by using the WinLoadMenu function. You can provide any number of MENU statements in a resource script file, but each statement must specify a unique menu-id value. You can provide any number of menuitem-definition statements in the menu. These define the submenus and menu items (commands) in the menu. The order of the statements defines the order of the menu items. ═══ 10.1.2.31.3. Example ═══ This example creates a menu resource whose menu identifier is 1. The menu contains a menu item named Alpha and a submenu named Beta. The submenu contains two menu items: Item 1 and Item 2. MENU 1 BEGIN MENUITEM "Alpha", 100 SUBMENU "Beta", 101 BEGIN MENUITEM "Item 1", 200 MENUITEM "Item 2", 201, , MIA_CHECKED END END ═══ 10.1.2.32. MENUITEM Statement ═══ The MENUITEM statement creates a menu item for a menu. ═══ 10.1.2.32.1. Syntax ═══ MENUITEM text, menu-id [, menuitem-style [, menuitem-attributerbrk.] ═══ 10.1.2.32.2. Description ═══ This statement defines the text, identifier, and attributes of a menu item. Use the MENUITEM statement only in a MENU or SUBMENU statement. The system displays the text when it displays the corresponding menu. If the user chooses the menu item, the system generates a WM_COMMAND message that includes the specified menu-item identifier and sends it to the window owning the menu. You can provide any number of MENUITEM statements, but each must have a unique menu-id value. The alternative form of the MENUITEM statement, MENUITEM SEPARATOR, creates a menu separator. A menu separator is a horizontal dividing bar between two menu items in a submenu. The separator is not active - that is, the user cannot choose it, it has no text associated with it, and it has no identifier. You can use the \t or \a character combination in any item name. The \t character inserts a tab when the name is displayed and is typically used to separate the menu-item name from the name of an accelerator key. The \a character aligns to the right all text that follows it. These characters are intended to be used for menu items in submenus only. The width of the displayed submenu is always adjusted so there is at least one space (and usually more) between any pieces of text separated by a \t or \a. (When compiling the menu resource, the compiler stores the \t and \a characters as control characters. For example, the \t is stored as 0x09.) A tilde ( ~ ) character in the item name indicates that the following character is used as a mnemonic character for the item. When the menu is displayed, the tilde is not shown, but the mnemonic character is underlined. The user can choose the menu item by pressing the key corresponding to the underlined mnemonic character. ═══ 10.1.2.32.3. Example ═══ This example creates a menu item named Alpha. The item identifier is 101. MENUITEM "Alpha", 101 This example creates a menu item named Beta. The item identifier is 102. The menu item has a text style and a checked attribute. MENUITEM "Beta", 102, MIS_TEXT, MIA_CHECKED This example creates a menu separator between menu items named Gamma and Delta. MENUITEM "Gamma", 103 MENUITEM SEPARATOR MENUITEM "Delta", 104 This example creates a menu item that has a bit map instead of a name. The bit-map identifier, 1, is first defined using a BITMAP statement. The identifier for the menu item is 301. Note that a # sign must be placed in front of the bit map identifier in the MENUITEM statement. BITMAP 1 mybitmap.bmp MENUITEM "#1", 301, MIS_BITMAP ═══ 10.1.2.33. MESSAGETABLE Statement ═══ The MESSAGETABLE statement creates one or more string resources for an application. ═══ 10.1.2.33.1. Syntax ═══ MESSAGETABLE [load-option] [mem-option] BEGIN string-id string-definition . . . END ═══ 10.1.2.33.2. Description ═══ A string resource is a null-terminated character string that has a unique string identifier. A string resource can be loaded from the executable file when needed by using the DosGetResource function with the RT_MESSAGE resource type. RT_MESSAGE resources are bundled together in groups of 16, with any missing IDs replaced with zero length strings. Each group, or bundle, is assigned a unique sequential ID. The resource string ID is not necessarily the same as the ID specified when using DosGetResource. The formula for calculating the ID of the resource bundle, for use in DosGetResource, is as follows: bundle ID := ( id / 16) +1, where id is the string ID assigned in the RC file. Thus, bundle 1 contains strings 0 to 15, bundle 2 contains strings 16 to 31, and so on. Once the address of the bundle has been returned by DosGetResource (using the calculated ID), the buffer can be parsed to locate the particular string within the bundle. The number of the string is calculated by the formula: string := id % 16 (string = remainder for id/16). The buffer returned consists of the CodePage of the strings in the first USHORT, followed by the 16 strings in the bundle. The first BYTE of each string is the length of the string (including the null terminator), followed by the string and the terminator. A zero length string is represented by two bytes: 01 (string length) followed by the null terminator. You can provide any number of MESSAGETABLE statements in a resource script file. The compiler treats all the strings from the various MESSAGETABLE statements as if they belonged to a single statement. This means that no two strings in a resource script file can have the same string identifier. Although the MESSAGETABLE and STRINGTABLE statements are nearly identical, most applications use the STRINGTABLE statement instead of the MESSAGETABLE statement to create string resources. You can continue a string on multiple lines by terminating the line with a backslash (\) or by terminating the line with a double quotation mark (") and then starting the next line with a double quotation mark. ═══ 10.1.2.33.3. Example ═══ This example creates two string resources whose string identifiers are 1 and 2. MESSAGETABLE BEGIN 1 "Filename not found" 2 "Cannot open file for reading" END ═══ 10.1.2.34. MLE Statement ═══ The MLE statement creates a multiple-line entry-field control. ═══ 10.1.2.34.1. Syntax ═══ MLE text, id, x, y, width, height [, style] ═══ 10.1.2.34.2. Description ═══ The control is a rectangle in which the user can type and edit multiple lines of text. The control displays a pointer when the user selects it. The user can then use the keyboard to enter text or edit the existing text. Editing keys include the BACKSPACE and DELETE keys. By using the mouse or the DIRECTION keys, the user can select the characters to delete or select the place to insert new characters. The MLE statement, which you can use only in a DIALOG or WINDOW statement, defines the text, identifier, dimensions, and attributes of a control window. The predefined class for this control is WC_MLE. If you do not specify a style, the default style is MLS_BORDER, WS_GROUP, and WS_TABSTOP. ═══ 10.1.2.34.3. Example ═══ This example creates a multiple-line entry-field control that is not labeled. MLE "", 101, 10, 10, 50, 100 ═══ 10.1.2.35. NOTEBOOK Statement ═══ The NOTEBOOK statement creates a notebook control within the dialog window. ═══ 10.1.2.35.1. Syntax ═══ NOTEBOOK id, x, y, width, height [, style] ═══ 10.1.2.35.2. Description ═══ This control is used to organize information on individual pages so that it can be located and displayed easily. The NOTEBOOK statement defines the identifier, position, dimensions, and attributes of a notebook control. The predefined class for this control is WC_NOTEBOOK. If you do not specify a style, the default style is WS_TABSTOP and WS_VISIBLE. Use the NOTEBOOK statement only in a DIALOG or WINDOW statement. ═══ 10.1.2.35.3. Example ═══ This example creates a notebook control at position (20, 20) within the dialog window. The notebook has a width of 200 character units and a height of 50 character units. Its resource ID is 201. The tabs style BKS_ROUNDEDTABS specification overrides the notebook default style of square tabs. The default styles WS_TABSTOP and WS_GROUP are both in effect, although only the latter is specified. Const IDC_NOTEBOOK = 201; IDD_NOTEBOOKDLG = 503; DIALOG "Notebook", IDD_NOTEBOOKDLG, 11, 11, 420, 420, FS_NOBYTEALIGN Or WS_VISIBLE, FCF_SYSMENU Or FCF_TITLEBAR BEGIN NOTEBOOK IDC_NOTEBOOK, 20, 20, 200, 400, BKS_ROUNDEDTABS Or WS_GROUP END ═══ 10.1.2.36. POINTER Statement ═══ The POINTER statement defines a pointer resource for an application. ═══ 10.1.2.36.1. Syntax ═══ POINTER pointer-id [load-option] [mem-option] filename ═══ 10.1.2.36.2. Description ═══ A pointer resource, typically created by using the OS/2 Icon Editor, is a bit map defining the shape of the mouse pointer on the screen. The POINTER statement copies the pointer resource from the file specified in the filename field and adds it to the application's other resources. A pointer resource can be loaded from the executable file when needed by using the WinLoadPointer function. You can provide any number of POINTER statements in a resource script file, but each statement must specify a unique pointer-id value. ═══ 10.1.2.36.3. Example ═══ This example defines a pointer whose pointer identifier is 10. The pointer resource is copied from the file custom.cur. POINTER 10 custom.cur ═══ 10.1.2.37. PRESPARAMS Statement ═══ The PRESPARAMS statement defines presentation fields that customize a dialog box, menu, window, or control. ═══ 10.1.2.37.1. Syntax ═══ PRESPARAMS presparam, value [, value] ... ═══ 10.1.2.37.2. Description ═══ PRESPARAMS data is a series of types and values. The window procedure of the dialog box, menu, window, or control receives and processes this data when the item is created. The data for custom controls can be in any format. PRESPARAMS is often used to supply data to control the appearance of the customized window when it is first created. For example, the PRESPARAMS statement may specify the colors to be used in the window. ═══ 10.1.2.37.3. Example ═══ This example creates a menu resource with a menu identifier of 1. The PRESPARAMS statement specifies that the following three menu items be displayed in the 12-point Helvetica** font. MENU 1 BEGIN PRESPARAMS PP_FONTNAMESIZE, "12.Helv" MENUITEM "New", 100 MENUITEM "Open", 101 MENUITEM "Save", 102 END ═══ 10.1.2.38. PUSHBUTTON Statement ═══ The PUSHBUTTON statement creates a push-button control. ═══ 10.1.2.38.1. Syntax ═══ PUSHBUTTON text, id, x, y, width, height [, style ] ═══ 10.1.2.38.2. Description ═══ The control is a round-cornered rectangle containing the given text. The control sends a message to its parent whenever the user chooses the control. The PUSHBUTTON statement defines the text, identifier, dimensions, and attributes of a control window. The predefined class for this control is WC_BUTTON. If you do not specify a style, the default style is BS_PUSHBUTTON and WS_TABSTOP. Use the PUSHBUTTON statement only in a DIALOG or WINDOW statement. ═══ 10.1.2.38.3. Example ═══ This example creates a push-button control that is labeled "OK." PUSHBUTTON "OK", 101, 10, 10, 100, 100 ═══ 10.1.2.39. RADIOBUTTON Statement ═══ The RADIOBUTTON statement creates a radio-button control, which is a small circle that has the given text displayed to its right. ═══ 10.1.2.39.1. Syntax ═══ RADIOBUTTON text, id, x, y, width, height [, style] ═══ 10.1.2.39.2. Description ═══ The control highlights the circle and sends a message to its parent window when the user selects the button. The control removes the highlight and sends a message when the button is next selected. The RADIOBUTTON statement defines the text, identifier, dimensions, and attributes of a control window. The predefined class for this control is WC_BUTTON. If you do not specify a style, the default style is BS_RADIOBUTTON. Use the RADIOBUTTON statement only in a DIALOG or WINDOW statement. ═══ 10.1.2.39.3. Example ═══ This example creates a radio-button control that is labeled "Italic." RADIOBUTTON "Italic", 101, 10, 10, 24, 50 ═══ 10.1.2.40. RCDATA Statement ═══ The RCDATA statement defines a custom-data resource for an application. ═══ 10.1.2.40.1. Syntax ═══ RCDATA resource-id BEGIN data-definition [, data-definition] ... . . . END ═══ 10.1.2.40.2. Description ═══ The custom data can be in whatever format the application requires. You can provide any number of RCDATA statements in a resource script file, but each statement must specify a unique resource-id value. A custom-data resource can be loaded from the executable file when needed by using the DosGetResource or DosGetResource2 functions with the RT_RCDATA resource type. ═══ 10.1.2.40.3. Example ═══ This example defines custom data that has a resource identifier of 5. RCDATA 5 BEGIN "E. A. Poe", 1849, -32, 3L, 0x8000000l, 3+4+5 END ═══ 10.1.2.41. RCINCLUDE Statement ═══ The RCINCLUDE statement causes RC to process the resource script file specified in the filename field along with the current resource script file. ═══ 10.1.2.41.1. Syntax ═══ RCINCLUDE filename ═══ 10.1.2.41.2. Description ═══ The contents of both script files are compiled by RC and the results are placed in one binary resource file and/or executable file. RCINCLUDE statements are processed before any other processing is done, including preprocessing by RCPP.EXE, which removes comments, replaces values in the define directives, and so forth. When specifying a high performance file system (HPFS) file name on an RCINCLUDE statement, enclose the path and file name in double quotes; for example: RCINCLUDE &odq.d:&bslash.project&bslash.long dialog&per.dlg&cdq. Double quotes enable the resource compiler to recognize a name containing embedded blank characters. ═══ 10.1.2.41.3. Example ═══ This example includes the file DIALOGS.RC as part of the current resource script file. RCINCLUDE dialogs.rc ═══ 10.1.2.42. RESOURCE Statement ═══ The RESOURCE statement defines a custom resource for an application. ═══ 10.1.2.42.1. Syntax ═══ RESOURCE type-id resource-id [load-option] [mem-option] filename ═══ 10.1.2.42.2. Description ═══ A custom resource can be any data in any format. The RESOURCE statement copies the custom resource from the specified file and adds it to the application's other resources. A custom resource can be loaded from the executable file when needed by using the DosGetResource or DosGetResource2 function and specifying the resource's type and resource identifier. You can provide any number of RESOURCE statements in a resource script file, but each statement must specify a unique combination of type-id and resource-id values. That is, RESOURCE statements having the same type-id value are permitted as long as the resource-id value for each is unique. ═══ 10.1.2.42.3. Example ═══ This example defines a custom resource whose type identifier is 300 and whose resource identifier is 14. The custom resource is copied from the file CUSTOM.RES. RESOURCE 300 14 custom.res ═══ 10.1.2.43. RTEXT Statement ═══ The RTEXT statement creates a right-aligned text control. ═══ 10.1.2.43.1. Syntax ═══ RTEXT text, id, x, y, width, height [, style] ═══ 10.1.2.43.2. Description ═══ The control is a simple rectangle displaying the given text right-aligned in the rectangle. The text is formatted before it is displayed. Words that would extend past the end of a line are automatically wrapped to the beginning of the next line. The RTEXT statement, which you can use only in a DIALOG or WINDOW statement, defines the text, identifier, dimensions, and attributes of the control. The predefined class for the control is WC_STATIC. If you do not specify a style, the default style is SS_TEXT, DT_RIGHT, and WS_GROUP. ═══ 10.1.2.43.3. Example ═══ This example creates a right-aligned text control that is labeled "Filename." RTEXT "Filename", 101, 10, 10, 100, 100 ═══ 10.1.2.44. SLIDER Statement ═══ The SLIDER statement creates a slider control within the dialog window. ═══ 10.1.2.44.1. Syntax ═══ SLIDER id, x, y, width, height [, style] ═══ 10.1.2.44.2. Description ═══ This control lets the user set, display, or modify a value by moving a slider arm along a slider shaft. The SLIDER statement defines the identifier, position, dimensions, and attributes of a slider control. The predefined class for this control is WC_SLIDER. If you do not specify a style, the default style is WS_TABSTOP and WS_VISIBLE. Use the SLIDER statement only in a DIALOG or WINDOW statement. ═══ 10.1.2.44.3. Example ═══ This example creates a slider control at position (40, 30) within the dialog window. The slider has a width of 120 character units and a height of 2 character units. Its resource ID is 101. The style specification SLS_BUTTONSLEFT adds buttons to the left of the slider shaft. The default styles WS_TABSTOP and WS_VISIBLE are both in effect, although only the latter is specified. Const IDC_SLIDER = 101; IDD_SLIDERDLG = 502; DIALOG "Slider", IDD_SLIDERDLG, 11, 11, 200, 240, FS_NOBYTEALIGN Or WS_VISIBLE, FCF_SYSMENU Or FCF_TITLEBAR BEGIN SLIDER IDC_SLIDER, 40, 30, 120, 16, SLS_BUTTONSLEFT Or WS_VISIBLE END ═══ 10.1.2.45. SPINBUTTON Statement ═══ The SPINBUTTON statement creates a spin-button control within the dialog window. ═══ 10.1.2.45.1. Syntax ═══ SPINBUTTON id, x, y, width, height [, style] ═══ 10.1.2.45.2. Description ═══ This control gives the user quick access to a finite set of data. The SPINBUTTON statement defines the identifier, position, dimensions, and attributes of a spin-button control. The predefined class for this control is WC_SPINBUTTON. If you do not specify a style, the default style is WS_TABSTOP, WS_VISIBLE, and SPBS_MASTER. Use the SPINBUTTON statement only in a DIALOG or WINDOW statement. ═══ 10.1.2.45.3. Example ═══ This example creates a spin-button control at position (80, 20) within the dialog window. The spin button has a width of 60 character units and a height of 3 character units. Its resource ID is 302. The style specification SPBS_NUMERICONLY creates a control which accepts only the digits 0-9 and virtual keys. The default styles SPBS_MASTER, WS_TABSTOP, and WS_VISIBLE are all in effect, although only WS_TABSTOP is specified. Const IDC_SPINBUTTON = 302; IDD_SPINDLG = 502; DIALOG "Spin button", IDD_SPINDLG, 11, 11, 200, 240, FS_NOBYTEALIGN Or WS_VISIBLE, FCF_SYSMENU Or FCF_TITLEBAR BEGIN SPINBUTTON IDC_SPINBUTTON, 80, 20, 60, 24, SPBS_NUMERICONLY Or WS_TABSTOP END ═══ 10.1.2.46. STRINGTABLE Statement ═══ The STRINGTABLE statement creates one or more string resources for an application. ═══ 10.1.2.46.1. Syntax ═══ STRINGTABLE [load-option] [mem-option] BEGIN string-id string-definition . . . END ═══ 10.1.2.46.2. Description ═══ A string resource is a null-terminated character string that has a unique string identifier. A string resource can be loaded from the executable file when needed by using WinLoadString or with DosGetResource with the RT_STRING resource type. RT_STRING resources are bundled together in groups of 16, with any missing IDs replaced with zero length strings. Each group, or bundle, is assigned a unique sequential ID. The resource string ID is not necessarily the same as the ID specified when using DosGetResource. The formula for calculating the ID of the resource bundle, for use in DosGetResource, is as follows: bundle ID := ( id / 16) +1 where id is the string ID assigned in the RC file. Thus, bundle 1 contains strings 0 to 15, bundle 2 contains strings 16 to 31, and so on. Once the address of the bundle has been returned by DosGetResource (using the calculated ID), the buffer can be parsed to locate the particular string within the bundle. The number of the string is calculated by the formula: string := id % 16 (string = remainder for id/16). The buffer returned consists of the CodePage of the strings in the first USHORT, followed by the 16 strings in the bundle. The first BYTE of each string is the length of the string (including the null terminator), followed by the string and the terminator. A zero length string is represented by two bytes: 01 (string length) followed by the null terminator. You can provide any number of STRINGTABLE statements in a resource script file. The compiler treats all the strings from the various STRINGTABLE statements as if they belonged to a single statement. This means that no two strings in a resource script file can have the same string identifier. You can continue a string on multiple lines by terminating the line with a backslash (\) or by terminating the line with a double quotation mark (") and then starting the next line with a double quotation mark. ═══ 10.1.2.46.3. Example ═══ This example creates two string resources whose string identifiers are 1 and 2. Const IDS_HELLO = 1; IDS_GOODBYE = 2; STRINGTABLE BEGIN IDS_HELLO "Hello" IDS_GOODBYE "Goodbye" END ═══ 10.1.2.47. SUBITEMSIZE Statement ═══ The SUBITEMSIZE statement specifies the size, in words, of each help subitem in a help subtable. ═══ 10.1.2.47.1. Syntax ═══ SUBITEMSIZE size ═══ 10.1.2.47.2. Description ═══ The minimum size is two words, and each help subitem in a help subtable must be the same size. When used, the SUBITEMSIZE statement must appear after the HELPSUBTABLE statement and before the BEGIN keyword. You do not need to use the SUBITEMSIZE statement if the help subitems are the default size (2). ═══ 10.1.2.47.3. Example ═══ The SUBITEMSIZE statement in this example specifies that each HELPSUBITEM statement contains three words. HELPSUBTABLE 1 SUBITEMSIZE 3 BEGIN HELPSUBITEM IDCLD_FILEMENU, IDHP_FILEMENU, 5 HELPSUBITEM IDCLD_HELPMENU, IDHP_HELPMENU, 6 END ═══ 10.1.2.48. SUBMENU Statement ═══ The SUBMENU statement creates a submenu for a given menu. ═══ 10.1.2.48.1. Syntax ═══ SUBMENU text, submenu-id [, menuitem-style[, menuitem-attributerbrk.] BEGIN menuitem-definition . . . END ═══ 10.1.2.48.2. Description ═══ A submenu is a vertical list of menu items from which the user can choose a command. You can provide any number of SUBMENU statements in a MENU statement, but each SUBMENU statement must specify a unique submenu-id value. You can provide any number of menuitem-definition statements in the SUBMENU statement. These define the menu items (commands) in the menu. The order of the statements determines the order of the menu items. ═══ 10.1.2.48.3. Example ═══ This example creates a submenu named Elements. Its identifier is 2. The submenu contains three menu items, which are created by using MENUITEM statements. SUBMENU "Elements", 2 BEGIN MENUITEM "Oxygen", 200 MENUITEM "Carbon", 201, , MIA_CHECKED MENUITEM "Hydrogen", 202 END ═══ 10.1.2.49. VALUESET Statement ═══ The VALUESET statement creates a value set control within the dialog window. ═══ 10.1.2.49.1. Syntax ═══ VALUESET id, x, y, width, height [, style] ═══ 10.1.2.49.2. Description ═══ This control lets a user select one choice from a group of mutually exclusive choices. The VALUESET statement defines the identifier, position, dimensions, and attributes of a value set control. The predefined class for this control is WC_VALUESET. If you do not specify a style, the default style is WS_TABSTOP and WS_VISIBLE. Use the VALUESET statement only in a DIALOG or WINDOW statement. ═══ 10.1.2.49.3. Example ═══ This example creates a value set control at position (40, 40) within the dialog window. The value set control has a width of 220 character units and a height of 20 character units. Its resource ID is 302. The style specification VS_ICON creates a control to show items in icon form. The default styles WS_TABSTOP and WS_VISIBLE are both in effect, although only WS_TABSTOP is specified. Const IDC_VALUESET = 302; IDD_VALUESETDLG = 501; DIALOG "Value set", IDD_VALUESETDLG, 11, 11, 260, 240, FS_NOBYTEALIGN | WS_VISIBLE, FCF_SYSMENU | FCF_TITLEBAR BEGIN VALUESET IDC_VALUESET, 40, 40, 220, 160, VS_ICON | WS_TABSTOP END ═══ 10.1.2.50. WINDOW Statement ═══ The WINDOW statement creates a window of the specified class. ═══ 10.1.2.50.1. Syntax ═══ WINDOW text, id, x, y, width, height, class [, style [, framect]] data-definitions [ BEGIN control-definition . . . END ] ═══ 10.1.2.50.2. Description ═══ The statement defines the position and dimensions of the window relative to its parent window, as well as the window-box style. The WINDOW statement is typically used in a WINDOWTEMPLATE or FRAME statement. Usually, only one WINDOW statement is used in a FRAME statement. It defines the client window belonging to the corresponding frame window. The optional BEGIN and END keywords enclose any CONTROL statements that are given with the window. CONTROL statements given in this manner represent child windows belonging to the window created by the WINDOW statement. The WINDOW statement can actually contain any combination of CONTROL, DIALOG, and WINDOW statements. Typically, a WINDOW statement contains one or no such statements. ═══ 10.1.2.50.3. Example ═══ This example creates a client window belonging to the frame window. The client window belongs to the "MyClientClass" window class and has the standard window identifier FID_CLIENT. WINDOWTEMPLATE 1 BEGIN FRAME "My Window", 1, 10, 10, 320, 130, 0, FCF_STANDARD | FCF_VERTSCROLL BEGIN WINDOW "", FID_CLIENT, 0, 0, 0, 0, "MyClientClass" END END ═══ 10.1.2.51. WINDOWTEMPLATE Statement ═══ The WINDOWTEMPLATE statement creates a window template. ═══ 10.1.2.51.1. Syntax ═══ WINDOWTEMPLATE window-id [load-option] [mem-option] BEGIN window-definition . . . END ═══ 10.1.2.51.2. Description ═══ A window template consists of a series of statements that define the window identifier, load and memory options, window dimensions, and controls in the window. The window template can be loaded from the executable file by using the WinLoadDlg function. You can provide any number of window templates in a resource script file, but each template must have a unique window-id value. A WINDOWTEMPLATE statement can contain DIALOG, CONTROL, and WINDOW statements. Typically, only one WINDOW statement is used in the WINDOWTEMPLATE statement. ═══ 10.2. Directive Descriptions ═══ This section provides the syntax, a description, and an example of each of the directives. ═══ 10.2.1. #define Directive ═══ The #define directive assigns the given value to the specified name. All subsequent occurrences of the name are replaced by the value. ═══ 10.2.1.1. Syntax ═══ #define name value ═══ 10.2.1.2. Example ═══ This example assigns values to the names "NONZERO" and "USERCLASS". Const NONZERO = 1; USERCLASS = 'MyControlClass'; ═══ 10.2.2. #elif Directive ═══ The #elif directive marks an optional clause of a conditional-compilation block defined by a #ifdef, #ifndef, or #if directive. The directive controls conditional compilation of the resource file by checking the specified constant expression. If the constant expression is nonzero, #elif directs the compiler to continue processing statements up to the next #endif, #else, or #elif directive and then skip to the statement after #endif. If the constant expression is zero, #elif directs the compiler to skip to the next #endif, #else, or #elif directive. You can use any number of #elif directives in a conditional block. ═══ 10.2.2.1. Syntax ═══ #elif constant-expression ═══ 10.2.2.2. Example ═══ In this example, #elif directs the compiler to process the second BITMAP statement only if the value assigned to the name "Version" is less than 7. The #elif directive itself is processed only if Version is greater than or equal to 3. #if Version < 3 BITMAP 1 errbox.bmp #elif Version < 7 BITMAP 1 userbox.bmp #endif ═══ 10.2.3. #else Directive ═══ The #else directive marks an optional clause of a conditional-compilation block defined by a #ifdef, #ifndef, or #if directive. The #else directive must be the last directive before the #endif directive. This directive has no arguments. ═══ 10.2.3.1. Syntax ═══ #else ═══ 10.2.3.2. Example ═══ This example compiles the second BITMAP statement only if the name "DEBUG" is not defined. #ifdef DEBUG BITMAP 1 errbox.bmp #else BITMAP 1 userbox.bmp #endif ═══ 10.2.4. #endif directive ═══ The #endif directive marks the end of a conditional-compilation block defined by a #ifdef directive. One #endif is required for each #if, #ifdef, or #ifndef directive. This directive has no arguments. ═══ 10.2.4.1. Syntax ═══ #endif ═══ 10.2.5. #if Directive ═══ The #if directive controls conditional compilation of the resource file by checking the specified constant expression. If the constant expression is nonzero, #if directs the compiler to continue processing statements up to the next #endif, #else, or #elif directive and then skip to the statement after the #endif directive. If the constant expression is zero, it directs the compiler to skip to the next #endif, #else, or #elif directive. ═══ 10.2.5.1. Syntax ═══ #If constant-expression ═══ 10.2.5.2. Example ═══ This example compiles the BITMAP statement only if the value assigned to the name "Version" is less than 3. #if Version < 3 BITMAP 1 errbox.bmp #endif ═══ 10.2.6. #ifdef Directive ═══ The #ifdef directive controls conditional compilation of the resource file by checking the specified name. If the name has been defined by using a define directive or by using the -d command-line option of rc, #ifdef directs the compiler to continue with the statement immediately after the #ifdef directive. If the name has not been defined, #ifdef directs the compiler to skip all statements up to the next #endif directive. ═══ 10.2.6.1. Syntax ═══ #ifdef name ═══ 10.2.6.2. Example ═══ This example compiles the BITMAP statement only if the name "Debug" is defined. #ifdef Debug BITMAP 1 errbox.bmp #endif ═══ 10.2.7. #ifndef Directive ═══ The #ifndef directive controls conditional compilation of the resource file by checking the specified name. If the name has not been defined or if its definition has been removed by using the #undef directive, #ifndef directs the compiler to continue processing statements up to the next #endif, #else, or #elif directive and then skip to the statement after the #endif directive. If the name is defined, #ifndef directs the compiler to skip to the next #endif, #else, or #elif directive. ═══ 10.2.7.1. Syntax ═══ #ifndef name ═══ 10.2.7.2. Example ═══ This example compiles the BITMAP statement only if the name "Optimize" is not defined. #ifndef Optimize BITMAP 1 errbox.bmp #endif ═══ 10.2.8. #include Directive ═══ The #include directive causes RC to process the file specified in the filename field. This file should be a header file that defines the constants used in the resource script file. Only the define directives in the specified file are processed. All other statements are ignored. The filename field is handled as a C string. Therefore, you must include two backslashes (\\) wherever one is required in the path. (As an alternative, you can use a single forward slash (/) instead of two backslashes.) ═══ 10.2.8.1. Syntax ═══ #include filename ═══ 10.2.8.2. Example ═══ This example processes the header files OS2.H and HEADERS\MYDEFS.H\I while compiling the resource script file. #include #include "headers&bsl.&bsl.&bsl.&bsl.mydefs.h" ═══ 10.2.9. #undef Directive ═══ The undef directive removes the current definition of the specIfied name. All subsequent occurrences of the name are processed without replacement. ═══ 10.2.9.1. Syntax ═══ #undef name ═══ 10.2.9.2. Example ═══ This example removes the definitions for the names "nonzero" and "USERCLASS". #undef nonzero #undef USERCLASS ═══ 10.3. Using Resource Files ═══ This section explains how to create a resource script file, compile it using the Resource Compiler (RC.EXE), and optionally add the resources to your executable file. Resource script files have a default file-name extension of .RC. For resource information on the individual controls, see the chapter on the specific control. For example, an example of a resource script file for frame windows is in Frame Windows. ═══ 10.3.1. Creating and Compiling a Resource File ═══ The resource compiler (RC) compiles a resource script file to create a new file, called a binary resource file, which has a .RES file-name extension. The binary resource file can be added to the executable file of the application, thereby replacing any existing resources in that file. The RC command line has the following three basic forms: rc resource-script-file [executable-file] rc binary-resource-file [executable-file] rc -r resource-script-file [binary-resource-file] Note: The third option does not add to the executable file. The resource-script-file parameter is the file name of the resource script file to be compiled. The executable-file parameter must be the name of the executable file to receive the compiled resources. This is a file having a file-name extension of either .EXE or .DLL. If you omit the executable-file field, RC adds the compiled resources to the executable file that has the same name as the resource script file but which has the .EXE file-name extension. The binary-resource-file parameter is the name of the binary resource file to be added to the executable file. The -r option directs RC to compile the resource script file without adding it to an executable file. ═══ 10.3.1.1. Compiling and Adding Resources to the .EXE File ═══ To compile the resource script file EXAMPLE.RC and add the result to the executable file EXAMPLE.EXE, use the following command: rc example You do not need to specify the .RC extension. RC creates the binary resource file EXAMPLE.RES and adds the compiled resource to the executable file EXAMPLE.EXE. ═══ 10.3.1.2. Compiling without Adding Resources to the .EXE File ═══ To compile the resource script file EXAMPLE.RC into a binary resource file without adding the resources to an executable file, use the following command: rc -r example The compiler creates the binary resource file EXAMPLE.RES. To create a binary resource file that has a name different from the resource script file, use the following command: rc -r example newfile.res ═══ 10.3.1.3. Adding the Compiled Resources to the .EXE File ═══ To add the compiled resources in the binary resource file EXAMPLE.RES to an executable file, use the following command: rc example.res To specify the name of the executable file, if the name is different from the resource file, use the following command: rc example.res newfile.exe ═══ 10.3.1.4. Adding the Compiled Resources to a DLL ═══ To add the compiled resources to a dynamic-link-library (DLL) file, use the following command: rc example.res dynalink.dll ═══ 11. Scroll-Bar Controls ═══ Scroll bars are control windows that convert mouse and keyboard input into integers; they are used by an application to scroll the contents of a client window. This chapter describes how to create and use scroll bars in PM applications. ═══ 11.1. About Scroll Bars ═══ A scroll bar has three main parts: the bar, its arrows, and a slider. The arrows are located at each end of the scroll bar. The left scroll arrow, on the left side of a horizontal scroll bar, enables the user to scroll to the left in a document. The right scroll arrow lets the user scroll to the right. On a vertical scroll bar, the upper scroll arrow enables the user to scroll upward in the document; the lower scroll arrow, downward. The slider, which lies between the two scroll arrows, reflects the current value of the scroll bar. Scroll bars monitor the slider and send notification messages to the owner window when the slider position changes as a result of mouse or keyboard input. Although, typically, scroll bars are used in frame windows, an application can use stand-alone scroll bars of any size or shape, at any position, in a window of almost any class. Scroll bars can be used as parts of other control windows; for example, a list box uses a scroll bar to enable the user to view items when the list box is too small to display all the items. ═══ 11.1.1. Scroll-Bar Creation ═══ An application can include a scroll bar in a standard frame window by specifying the FCF_HORZSCROLL or FCF_VERTSCROLL flag in the WinCreateStdWindow function. To create a scroll bar in another type of window, an application can specify the predefined (preregistered) window class WC_SCROLLBAR in the WinCreateWindow function or in the CONTROL statement in a resource file. Although most applications specify an owner window when creating a scroll bar, an owner is not required. If an application does not specify an owner, the scroll bar does not send notification messages. ═══ 11.1.1.1. Scroll-Bar Styles ═══ A scroll bar has styles that determine what it looks like and how it responds to input. Styles are specified in the WinCreateWindow function or the CONTROL statement. A scroll-bar can have the following styles: ┌───────────────┬─────────────────────────────────────────────┐ │Style │Meaning │ ├───────────────┼─────────────────────────────────────────────┤ │SBS_AUTOTRACK │Causes the entire slider to track the │ │ │movement of the mouse pointer when the user │ │ │scrolls the window. Without this style, only │ │ │an outlined image of the slider tracks the │ │ │movement of the mouse pointer, and the slider│ │ │jumps to the new location when the user │ │ │releases the mouse button. │ ├───────────────┼─────────────────────────────────────────────┤ │SBS_HORZ │Creates a horizontal scroll bar. │ ├───────────────┼─────────────────────────────────────────────┤ │SBS_THUMBSIZE │Used to calculate the size of the scroll-bar │ │ │slider from the SBCDATA passed to │ │ │WinCreateWindow. │ ├───────────────┼─────────────────────────────────────────────┤ │SBS_VERT │Creates a vertical scroll bar. │ └───────────────┴─────────────────────────────────────────────┘ ═══ 11.1.1.2. Scroll-Bar Range and Position ═══ Every scroll bar has a range and a slider position. The range specifies the minimum and maximum values for the slider position. As the user moves the slider in a scroll bar, the scroll bar reports the slider position as an integer in this range. If the slider position is the minimum value, the slider is at the top of a vertical scroll bar or at the left end of a horizontal scroll bar. If the slider position is the maximum value, the slider is at the bottom or right end of the vertical or horizontal scroll bar, respectively. An application can adjust the range to convenient integers by using SBM_SETSCROLLBAR or WM_SETWINDOWPARAMS, or by using the SBCDATA structure during creation of the scroll bar. This enables you to easily translate the slider position into a value that corresponds to the data being scrolled. For example, an application attempting to display 100 lines of text (numbered 0 to 99) in a window that can show only 20 lines at a time could set the vertical scroll-bar range from 0-99, permitting any line to be the top line, and requiring blank lines to fill the viewing area when there are not sufficient lines of information to fill the area (lines 80-99). More likely, the range would be set to 0-79, so that only the first 80 lines could be the top line; this guarantees that there would always be 20 lines of text to fill the window. The current settings can be obtained using SBM_QUERYRANGE or WM_QUERYWINDOWPARAMS. To establish a useful relationship between the scroll-bar range and the data, an application must adjust the range whenever the data or the size of the window changes. This means the application should adjust the range as part of processing WM_SIZE messages. An application must move the slider in a scroll bar. Although the user requests scrolling in a scroll bar, the scroll bar does not update the slider position. Instead, it passes the request to the owner window, which scrolls the data and updates the slider position using the SBM_SETPOS message. The application controls the slider movement and can move the slider in the increments best suited for the data being scrolled. An application can retrieve the current slider position of a scroll bar by sending the SBM_QUERYPOS message to the scroll bar. If a scroll bar is a descendant of a frame window, its position relative to its parent can change when the position of the frame window changes. Frame windows draw scroll bars relative to the upper-left corner of the frame window (rather than the lower-left corner). The frame window can adjust the y coordinate of the scroll-bar position, which would be desirable if the scroll bar is a child of the frame window, but would be undesirable if the scroll bar is not a child window. ═══ 11.1.1.3. Scroll-Bar Slider Size ═══ The slider can be displayed either as a square (the default), or as a portion of the scroll bar if SBCDATA and the SBS_THUMBSIZE style are specified at creation. Displaying the slider as a proportional rectangle permits the size of the slider to be proportional to the amount of data being viewed in the visible range. The size is set based on the visible range and the number of values in the range. As an example, where the viewing area is 20 items and the range is 100, the slider size would be 20% of the potential slider area. Note that there is no direct connection between the scroll bar range and the range value used to set the slider size. It is possible to set the scroll-bar range from 0-99, and base the slider size on a viewing area of 500 and a range of 1000. This will set the scroll-bar to have 100 positions and will display a slider that is half the size of the scroll bar. The slider size can be set using SBM_SETTHUMBSIZE or WM_SETWINDOWPARAMS, and obtained using WM_QUERYWINDOWPARAMS. ═══ 11.1.2. Scroll-Bar Notification Messages ═══ A scroll bar sends notification messages to its owner whenever the user clicks the scroll bar. WM_VSCROLL and WM_HSCROLL are the notification messages for vertical and horizontal scroll bars, respectively. If the scroll bar is a frame control window, the frame window passes the message to its client window. Each notification message includes the scroll-bar identifier, scroll-bar command code corresponding to the action of the user, and, in some cases, the position of the slider. If an application creates a scroll bar as part of a frame control window, the scroll-bar identifier is the predefined constant FID_VERTSCROLL or FID_HORZSCROLL. Otherwise, it is the identifier given in the WinCreateWindow function. The scroll-bar command codes specify the action the user has taken. Operating system user-interface guidelines recommend certain responses for each action. Following is a list of the command codes; for each code, the user action is specified, followed by the application's response. In each case, a scrolling unit, appropriate for the given data, must be defined by the application. For example, for scrolling text vertically, the typical unit is a line. ┌────────────────────┬────────────────────────────────────────┐ │Command Code │Description │ ├────────────────────┼────────────────────────────────────────┤ │SB_LINEUP │Indicates that the user clicked the top │ │ │scroll arrow. Decrement the slider │ │ │position by one, and scroll toward the │ │ │top of the data by one unit. │ ├────────────────────┼────────────────────────────────────────┤ │SB_LINEDOWN │Indicates that the user clicked the │ │ │bottom scroll arrow. Increment the │ │ │slider position by one, and scroll │ │ │toward the bottom of the data by one │ │ │unit. │ ├────────────────────┼────────────────────────────────────────┤ │SB_LINELEFT │Indicates that the user clicked the left│ │ │scroll arrow. Decrement the slider │ │ │position by one, and scroll toward the │ │ │left end of the data by one unit. │ ├────────────────────┼────────────────────────────────────────┤ │SB_LINERIGHT │Indicates that the user clicked the │ │ │right scroll arrow. Increment the slider│ │ │position by one, and scroll toward the │ │ │right end of the data by one unit. │ ├────────────────────┼────────────────────────────────────────┤ │SB_PAGEUP │Indicates that the user clicked the │ │ │scroll-bar background above the slider. │ │ │Decrement the slider position by the │ │ │number of data units in the window, and │ │ │scroll toward the top of the data by the│ │ │same number of units. │ ├────────────────────┼────────────────────────────────────────┤ │SB_PAGEDOWN │Indicates that the user clicked the │ │ │scroll-bar background below the slider. │ │ │Increment the slider position by the │ │ │number of data units in the window, and │ │ │scroll toward the bottom of the data by │ │ │the same number of units. │ ├────────────────────┼────────────────────────────────────────┤ │SB_PAGELEFT │Indicates that the user clicked the │ │ │scroll-bar background to the left of the│ │ │slider. Decrement the slider position by│ │ │the number of data units in the window, │ │ │and scroll toward the left end of the │ │ │data by the same number of units. │ ├────────────────────┼────────────────────────────────────────┤ │SB_PAGERIGHT │Indicates that the user clicked the │ │ │scroll-bar background to the right of │ │ │the slider. Increment the slider │ │ │position by the number of data units in │ │ │the window, and scroll toward the right │ │ │end of the data by the same number of │ │ │units. │ ├────────────────────┼────────────────────────────────────────┤ │SB_SLIDERTRACK │Indicates that the user is dragging the │ │ │slider. Applications that draw data │ │ │quickly can set the slider to the │ │ │position given in the message, and │ │ │scroll the data by the same number of │ │ │units the slider has moved. Applications│ │ │that cannot draw data quickly should │ │ │wait for the SB_SLIDERPOSITION code │ │ │before moving the slider and scrolling │ │ │the data. │ ├────────────────────┼────────────────────────────────────────┤ │SB_SLIDERPOSITION │Indicates that the user released the │ │ │slider after dragging it. Set the slider│ │ │to the position given in the message, │ │ │and scroll the data by the same number │ │ │of units the slider was moved. │ ├────────────────────┼────────────────────────────────────────┤ │SB_ENDSCROLL │Indicates that the user released the │ │ │mouse after holding it on an arrow or in│ │ │the scroll-bar background. No response │ │ │is necessary. │ └────────────────────┴────────────────────────────────────────┘ If the command code is SB_SLIDERTRACK or SB_SLIDERPOSITION, indicating that the user is moving the scroll-bar slider, the notification message also contains the current position of the slider. The owner window can send a message to the scroll bar to read or reset the current value and range of the scroll bar. To reflect any changes in the state of the scroll bar, the owner window also can adjust the data the scroll bar controls. An application can use the WinEnableWindow function to disable a scroll bar. A disabled scroll bar ignores the actions of the user, sending out no notification messages when the user tries to manipulate it. If an application has no data to scroll, or if all data fits in the client window, the application should disable the scroll bar. ═══ 11.1.3. Scroll Bars and the Keyboard ═══ When a scroll bar has the keyboard focus, it generates notification messages for the following keys: ┌───────────────┬─────────────────────────────────────────────┐ │Keys │Response │ ├───────────────┼─────────────────────────────────────────────┤ │UP │SB_LINEUP or SB_LINELEFT │ ├───────────────┼─────────────────────────────────────────────┤ │LEFT │SB_LINEUP or SB_LINELEFT │ ├───────────────┼─────────────────────────────────────────────┤ │DOWN │SB_LINEDOWN or SB_LINERIGHT │ ├───────────────┼─────────────────────────────────────────────┤ │RIGHT │SB_LINEDOWN or SB_LINERIGHT │ ├───────────────┼─────────────────────────────────────────────┤ │PGUP │SB_PAGEUP or SB_PAGELEFT │ ├───────────────┼─────────────────────────────────────────────┤ │PGDN │SB_PAGEDOWN or SB_PAGERIGHT │ └───────────────┴─────────────────────────────────────────────┘ If an application uses scroll bars to scroll data but does not give the scroll bar the input focus, the window with the focus must process keyboard input. The window can generate scroll-bar notification messages or carry out the indicated scrolling. The following table shows the responses to keys that a window must process: ┌───────────────┬─────────────────────────────────────────────┐ │Key │Response │ ├───────────────┼─────────────────────────────────────────────┤ │UP │SB_LINEUP │ ├───────────────┼─────────────────────────────────────────────┤ │DOWN │SB_LINEDOWN │ ├───────────────┼─────────────────────────────────────────────┤ │PGUP │SB_PAGEUP │ ├───────────────┼─────────────────────────────────────────────┤ │PGDN │SB_PAGEDOWN │ ├───────────────┼─────────────────────────────────────────────┤ │CTRL+HOME │SB_SLIDERTRACK, with the slider set to the │ │ │minimum position │ ├───────────────┼─────────────────────────────────────────────┤ │CTRL+END │SB_SLIDERTRACK, with the slider set to the │ │ │maximum position │ ├───────────────┼─────────────────────────────────────────────┤ │LEFT │SB_LINELEFT │ ├───────────────┼─────────────────────────────────────────────┤ │RIGHT │SB_LINERIGHT │ ├───────────────┼─────────────────────────────────────────────┤ │CTRL+PGUP │SB_PAGELEFT │ ├───────────────┼─────────────────────────────────────────────┤ │CTRL+PGDN │SB_PAGERIGHT │ ├───────────────┼─────────────────────────────────────────────┤ │HOME │SB_SLIDERTRACK, with the slider set to the │ │ │minimum position │ ├───────────────┼─────────────────────────────────────────────┤ │END │SB_SLIDERTRACK, with the slider set to the │ │ │maximum position │ └───────────────┴─────────────────────────────────────────────┘ For vertical scroll bars that are part of list boxes, the following table shows the responses to keys: ┌───────────────┬─────────────────────────────────────────────┐ │Key │Command │ ├───────────────┼─────────────────────────────────────────────┤ │CTRL+UP │SB_SLIDERTRACK, with the slider set to the │ │ │minimum position │ ├───────────────┼─────────────────────────────────────────────┤ │CTRL+DOWN │SB_SLIDERTRACK, with the slider set to the │ │ │maximum position │ ├───────────────┼─────────────────────────────────────────────┤ │F7 │SB_PAGEUP │ ├───────────────┼─────────────────────────────────────────────┤ │F8 │SB_PAGEDOWN │ └───────────────┴─────────────────────────────────────────────┘ ═══ 11.2. Using Scroll Bars ═══ This section explains how to perform the following tasks:  Create scroll bars  Retrieve a scroll-bar handle  Initialize, adjust, and read the scroll-bar range and position ═══ 11.2.1. Creating Scroll Bars ═══ When creating a frame window, you can add scroll bars by specifying the FCF_HORZSCROLL flag, FCF_VERTSCROLL flag, or both flags in the WinCreateStdWindow function. This adds horizontal, vertical, or both (as specified) scroll bars to the frame window. The frame window owns the scroll bars and passes notification messages from the scroll bars to the client window. The following code fragment adds scroll bars to a frame window: Uses Os2Def,Os2Base,Os2PmApi; Var UlFrameControlFlags : ULONG; (* Сsken var tom!! *) Begin (* Set flags for a main window with scroll bars. *) UlFrameControlFlags := FCF_STANDARD Or FCF_HORZSCROLL Or FCF_VERTSCROLL; (* Create the window. *) hwndFrame := WinCreateStdWindow(HWND_DESKTOP, WS_VISIBLE, &ulFrameControlFlags, szClientClass, szFrameTitle, 0, nil, 0, &hwndClient); End. Scroll bars created this way have the window identifier FID_HORZSCROLL or FID_VERTSCROLL. To determine the size and position of the scroll bars, the frame window uses the standard size specified by the system values SV_CXVSCROLL and SV_CYHSCROLL. The position always is defined by the right and bottom edges of the frame window. Another way to create scroll bars is using the WinCreateWindow function. This method is most commonly used for stand-alone scroll bars. Creating scroll bars this way lets you set the size and position of the scroll bars. You also can specify which window should receive notification messages. The following code fragment creates a stand-alone scroll bar: Uses Os2Def,Os2Base,Os2PmApi; Const ID_SCROLL_BAR = 1; Var HwndScroll,hwndClient : HWND; (* Сsken var tom!! *) Begin hwndScroll := WinCreateWindow( hwndClient, (* Scroll-bar parent window *) WC_SCROLLBAR, (* Preregistered scroll-bar class *) nil, (* No window title *) SBS_VERT Or WS_VISIBLE, (* Vertical style and visible *) 10, 10, (* Position & Size *) 20, 100, (* Size *) hwndClient, (* Owner *) HWND_TOP, (* Z-order position *) ID_SCROLL_BAR, (* Scroll-bar identIfier *) nil, (* No class-specIfic data *) nil); (* No presentation parameters *) End. ═══ 11.2.2. Retrieving a Scroll-Bar Handle ═══ If you use the WinCreateStdWindow function to create a scroll bar as a child of the frame window, you must be able to retrieve the scroll-bar handle. One way to do this is to use the WinWindowFromID function, the frame-window handle, and a predefined identifier (such as FID_HORZSCROLL or FID_VERTSCROLL), as shown in the following code fragment: Uses Os2Def,Os2Base,Os2PmApi; Var HwndFrame,hwndHorzScroll,hwndVertScroll : HWND; (* Сsken var tom!! *) Begin hwndHorzScroll := WinWindowFromID(hwndFrame, FID_HORZSCROLL); hwndVertScroll := WinWindowFromID(hwndFrame, FID_VERTSCROLL); End. If the standard frame window includes a client window, you can use that handle to access the scroll bars. The idea is to get the frame-window handle first; then, the scroll-bar handle. Uses Os2Def,Os2Base,Os2PmApi; Var HwndScroll,hwndClient : HWND; (* Сsken var tom!! *) Begin (* Get a handle to the horizontal scroll bar. *) hwndScroll := WinWindowFromID( WinQueryWindow(hwndClient, QW_PARENT), FID_HORZSCROLL); End. ═══ 11.2.3. Using the Scroll-Bar Range and Position ═══ You can initialize the current value and range of a scroll bar to non-default values by sending the SBCDATA structure with class-specific data for a call to WinCreateWindow: Uses Os2Def,Os2Base,Os2PmApi; Const ID_SCROLL_BAR = 1; Var Sbcd : SBCDATA; (* Сsken var tom!! *) HwndScroll,hwndClient : HWND; (* Сsken var tom!! *) Begin (* Set up scroll-bar control data. *) Sbcd.posFirst := 200; Sbcd.posLast := 400; Sbcd.posThumb := 300; (* Create the scroll bar. *) hwndScroll := WinCreateWindow(hwndClient, WC_SCROLLBAR, nil, SBS_VERT Or WS_VISIBLE, 10, 10, 20, 100, hwndClient, HWND_TOP, ID_SCROLL_BAR, &sbcd, (* Class-specIfic data *) nil); End. You can adjust a scroll-bar value and range by sending it an SBM_SETSCROLLBAR message: (* Set the scroll-bar value and range. *) WinSendMsg(hwndScroll, SBM_SETSCROLLBAR, 300, MPFROM2SHORT(200, 400)); You can read a scroll-bar value by sending it an SBM_QUERYPOS message: Uses Os2Def,Os2Base,Os2PmApi; Var UsSliderPos : USHORT; (* Сsken var tom!! *) Begin (* Read the scroll-bar value. *) usSliderPos := WinSendMsg(hwndScroll, SBM_QUERYPOS, nil, nil); end. Similarly, you can set a scroll-bar value by sending an SBM_SETPOS message: (* Set the vertical scroll-bar value. *) WinSendMsg(hwndScroll, SBM_SETPOS, 300, nil); You can read a scroll-bar range by sending it an SBM_QUERYRANGE message: Uses Os2Def,Os2Base,Os2PmApi; Var Mr : MRESULT; (* Сsken var tom!! *) UsMinimum, UsMaximum : USHORT; (* Сsken var tom!! *) Begin (* Read the vertical scroll-bar range. *) mr := WinSendMsg(hwndScroll, SBM_QUERYRANGE, nil, nil); usMinimum := SHORT1FROMMR(mr); (* minimum in the low word *) usMaximum := SHORT2FROMMR(mr); (* maximum in the high word *) end. ═══ 12. Slider Controls ═══ A slider control is a visual component that displays a range of values and allows a user to set, display, or modify a value by moving a slider arm. There are two types of sliders:  The linear slider is represented as a shaft along which the slider arm can be moved by the user to set a value.  The circular slider is represented as a dial with the slider arm shown as the radius of the dial. This chapter explains how to use each of these slider controls in PM applications. ═══ 12.1. About Slider Controls ═══ This section covers linear and circular slider controls. Linear sliders are used to set values that have familiar increments. Circular sliders, although different in appearance from linear sliders, provide much the same function. Both types of sliders can be used in a window to create a user interface. ═══ 12.1.1. Linear Sliders ═══ Typically, linear sliders are used to easily set values that have familiar increments, such as feet, inches, degrees, and decibels. They also can be used for other purposes when immediate feedback is required, such as blending colors or showing a task's percentage of completion. For example, an application might let a user mix and match color shades by moving a slider arm, or a read-only slider could show how much of a task is complete by filling in the slider shaft as the task progresses. These are just a few examples of the ways in which sliders can be used. The slider arm shows the value currently set by its position on the slider shaft. The user selects slider values by changing the location of the slider arm. A tick mark indicates an incremental value in a slider scale. A detent, which is similar to a tick mark, also represents a value on the scale. However, a detent can be placed anywhere along the slider scale, rather than only in specific increments, and can be selected. The appearance of a slider and the user interaction with a slider are similar to that of a scroll bar. However, these two controls are not interchangeable because each has a unique purpose. A scroll bar scrolls information into view that is outside a window's work area, while the slider is used to set, display, or modify that information, whether it is in or out of the work area. Although linear sliders usually use values that have familiar increments, text also can be used. However, if the text is too long it can overlap the text displayed on the next tick mark or detent. Also, if the text on the far edge markers is too long, some of the text will not be displayed on screen. To prevent this use one of the following:  Smaller font  Shorter text values  Static controls The slider can be customized to meet varying application requirements, while providing a user interface component that can be used easily to develop products that conform to the Systems Application Architecture (SAA) Common User Access (CUA) user interface guidelines. The application can specify different scales, sizes, and orientations for its sliders, but the underlying function of the control remains the same. For a complete description of CUA sliders, refer to the SAA CUA Guide to User Interface Design and the SAA CUA Advanced Interface Design Reference. ═══ 12.1.1.1. Linear Slider Styles ═══ Slider control styles are set when a slider window is created. The following table describes linear slider control styles. If no styles are specified, defaults are used as indicated in the table. ┌──────────────────────┬──────────────────────────────────────┐ │Style Name │Description │ ├──────────────────────┼──────────────────────────────────────┤ │SLS_BOTTOM │Positions the slider at the bottom of │ │ │the slider window. Valid only for │ │ │horizontal sliders. │ ├──────────────────────┼──────────────────────────────────────┤ │SLS_BUTTONSBOTTOM │Specifies that the optional slider │ │ │buttons are to be used and places them│ │ │at the bottom of the slider shaft. The│ │ │buttons move the slider arm by one │ │ │position, up or down, in the direction│ │ │selected. Valid only for vertical │ │ │sliders. │ ├──────────────────────┼──────────────────────────────────────┤ │SLS_BUTTONSLEFT │Specifies that the optional slider │ │ │buttons are to be used and places them│ │ │to the left of the slider shaft. The │ │ │buttons move the slider arm by one │ │ │position, left or right, in the │ │ │direction selected. Valid only for │ │ │horizontal sliders. │ ├──────────────────────┼──────────────────────────────────────┤ │SLS_BUTTONSRIGHT │Specifies that the optional slider │ │ │buttons are to be used and places them│ │ │to the right of the slider shaft. The │ │ │buttons move the slider arm by one │ │ │position, left or right, in the │ │ │direction selected. Valid only for │ │ │horizontal sliders. │ ├──────────────────────┼──────────────────────────────────────┤ │SLS_BUTTONSTOP │Specifies that the optional slider │ │ │buttons are to be used and places them│ │ │at the top of the slider shaft. The │ │ │buttons move the slider arm by one │ │ │position, up or down, in the direction│ │ │selected. Valid only for vertical │ │ │sliders. │ ├──────────────────────┼──────────────────────────────────────┤ │SLS_CENTER │Centers the slider within the slider │ │ │window. This is the default position │ │ │of the slider. │ ├──────────────────────┼──────────────────────────────────────┤ │SLS_HOMEBOTTOM │Specifies the slider arm's home │ │ │position. The bottom of the slider is │ │ │used as the base value for │ │ │incrementing. Valid only for vertical │ │ │sliders. │ ├──────────────────────┼──────────────────────────────────────┤ │SLS_HOMELEFT │Specifies the slider arm's home │ │ │position. The left edge is used as the│ │ │base value for incrementing. This is │ │ │the default for horizontal sliders and│ │ │is valid only for horizontal sliders. │ ├──────────────────────┼──────────────────────────────────────┤ │SLS_HOMERIGHT │Specifies the slider arm's home │ │ │position. The right edge is used as │ │ │the base value for incrementing. Valid│ │ │only for horizontal sliders. │ ├──────────────────────┼──────────────────────────────────────┤ │SLS_HOMETOP │Specifies the slider arm's home │ │ │position. The top of the slider is │ │ │used as the base value for │ │ │incrementing. Valid only for vertical │ │ │sliders. │ ├──────────────────────┼──────────────────────────────────────┤ │SLS_HORIZONTAL │Positions the slider horizontally. The│ │ │slider arm can move left and right on │ │ │the slider shaft. A scale can be │ │ │placed on top of the slider shaft, │ │ │below the slider shaft, or in both │ │ │places. This is the default │ │ │orientation of the slider. │ ├──────────────────────┼──────────────────────────────────────┤ │SLS_LEFT │Positions the slider at the left edge │ │ │of the slider window. Valid only for │ │ │vertical sliders. │ ├──────────────────────┼──────────────────────────────────────┤ │SLS_OWNERDRAW │Notifies the application whenever the │ │ │slider shaft, the ribbon strip, the │ │ │slider arm, and the slider background │ │ │are to be drawn. │ ├──────────────────────┼──────────────────────────────────────┤ │SLS_PRIMARYSCALE1 │Determines the location of the scale │ │ │on the slider shaft by using increment│ │ │and spacing specified for scale 1 as │ │ │the incremental value for positioning │ │ │the slider arm. Scale 1 is displayed │ │ │above the slider shaft of a horizontal│ │ │slider and to the right of the slider │ │ │shaft of a vertical slider. This is │ │ │the default for a slider. │ ├──────────────────────┼──────────────────────────────────────┤ │SLS_PRIMARYSCALE2 │Determines the location of the scale │ │ │on the slider shaft by using increment│ │ │and spacing specified for scale 2 as │ │ │the incremental value for positioning │ │ │the slider arm. Scale 2 is displayed │ │ │below the slider shaft of a horizontal│ │ │slider and to the left of the slider │ │ │shaft of a vertical slider. │ ├──────────────────────┼──────────────────────────────────────┤ │SLS_READONLY │Creates a read-only slider, which │ │ │presents information to the user but │ │ │allows no interaction with the user. │ ├──────────────────────┼──────────────────────────────────────┤ │SLS_RIBBONSTRIP │Fills, as the slider arm moves, the │ │ │slider shaft between the home position│ │ │and the slider arm with a color value │ │ │different from slider shaft color, │ │ │similar to mercury in a thermometer. │ ├──────────────────────┼──────────────────────────────────────┤ │SLS_RIGHT │Positions the slider at the right edge│ │ │of the slider window. Valid only for │ │ │vertical sliders. │ ├──────────────────────┼──────────────────────────────────────┤ │SLS_SNAPTOINCREMENT │Causes the slider arm, when positioned│ │ │between two values, to be positioned │ │ │to the nearest value and redrawn at │ │ │that position. │ ├──────────────────────┼──────────────────────────────────────┤ │SLS_TOP │Positions the slider at the top of the│ │ │slider window. Valid only for │ │ │horizontal sliders. │ ├──────────────────────┼──────────────────────────────────────┤ │SLS_VERTICAL │Positions the slider vertically. The │ │ │slider arm can move up and down the │ │ │slider shaft. A scale can be placed on│ │ │the left side of the slider shaft, on │ │ │the right side of the slider shaft, or│ │ │in both places. │ └──────────────────────┴──────────────────────────────────────┘ ═══ 12.1.1.1.1. More on Linear Slider Styles ═══ This section summarizes information in the table and provides additional information on some of the styles. ═══ 12.1.1.1.1.1. Slider Orientation ═══ The slider's orientation is determined by specifying SLS_HORIZONTAL or SLS_VERTICAL. The default orientation is horizontal, with the slider arm moving left and right on the shaft. ═══ 12.1.1.1.1.2. Slider Positioning ═══ The slider's positioning within the slider window is determined by specifying SLS_CENTER, SLS_BOTTOM, SLS_TOP, SLS_LEFT, or SLS_RIGHT. The default positioning is centered in the slider window. ═══ 12.1.1.1.1.3. Slider Scale Location ═══ The location of the scale on the slider shaft is determined by specifying SLS_PRIMARYSCALE1 or SLS_PRIMARYSCALE2. The default is to use the increment and spacing specified for scale 1 as the incremental value for positioning the slider arm. Scale 1 is displayed above the slider shaft of a horizontal slider and to the right of the slider shaft of a vertical slider. ═══ 12.1.1.1.1.4. Slider Arm Home Position ═══ The slider arm's home position is determined by specifying SLS_HOMELEFT, SLS_HOMERIGHT, SLS_HOMEBOTTOM, or SLS_HOMETOP. The default is SLS_HOMELEFT for horizontal sliders and SLS_HOMEBOTTOM for vertical sliders. ═══ 12.1.1.1.1.5. Slider Buttons Location ═══ The location of the slider buttons, if used, is determined by specifying SLS_BUTTONSLEFT, SLS_BUTTONSRIGHT, SLS_BUTTONSBOTTOM, or SLS_BUTTONSTOP. If you do not specify one of these styles, or if conflicting styles are specified, slider buttons are not included in the slider control. ═══ 12.1.1.1.1.6. Other Styles ═══ If SLS_SNAPTOINCREMENT is specified and the slider arm is moved to a position between two values on the slider scale, it is positioned on the nearest value and redrawn at that position. If this style is not specified, the slider arm remains at the position to which it is moved. SLS_READONLY creates a read-only slider. This means the user cannot interact with the slider. It is simply used as to present a quantity to the user, such as the percentage of completion of an ongoing task. Visual differences for a read-only slider include a narrow slider arm, no slider buttons, and no detents. The SLS_RIBBONSTRIP style allows movement of the slider arm to cause the slider shaft between home position and the slider arm to be filled with a color value that is different from the slider shaft color, similar to mercury in a thermometer. If SLS_OWNERDRAW is specified, the application is notified whenever the slider shaft, the ribbon strip, the slider arm, and the slider background are to be drawn. ═══ 12.1.2. Circular Sliders ═══ The circular slider, although different in appearance from the linear slider, provides much the same function. The circular slider control provides an analog user interface and emulates the controls of stereo and video equipment. Because the circular slider takes up less space on the screen, it may be more practical to use in cases where you might want to have several controls in the same window. You may want to use both types of sliders in a window to create a user interface that makes good use of available space and provides a familiar appearance to the user. The slider arm shows the value currently set by its position on the slider dial. The slider arm can also be represented as a small circular thumb on the dial rather than a line. The user selects slider values by changing the location of the slider arm on the dial. Outside the perimeter of the dial is a circular scale with tick marks representing incremental values the slider arm can point to. Its values can be tracked by pointing to any area on the dial and pressing the select button while moving the mouse on the desktop. The circular slider can have a set of buttons, one to the left and the other to the right of the scroll range, similar to the buttons found on the linear slider, that can be used to modify the value shown on the slider. The minus sign on the left button and plus sign on the right button can be replaced with other symbols. For example, you might want to use a left arrow and a right arrow instead of the minus and plus signs. Another option of the circular slider is to have a window, in the center of the dial, that displays the value of the dial in scrollable numeric text. The appearance and functionality of the circular slider are controlled by the circular slider control styles specified. These style bits are summarized in the section that follows. ═══ 12.1.2.1. Circular Slider Styles ═══ Circular slider control style bits control the appearance and behavior of the slider. The following table describes circular slider control styles: ┌──────────────────────┬──────────────────────────────────────┐ │Style Name │Description │ ├──────────────────────┼──────────────────────────────────────┤ │CSS_360 │Extends the scroll range of the dial │ │ │to 360 degrees. When this style is │ │ │set, CSS_NONUMBER and CSS_NOBUTTON │ │ │styles automatically are set. │ ├──────────────────────┼──────────────────────────────────────┤ │CSS_CIRCULARVALUE │Draws a circular thumb, rather than a │ │ │line, for the value indicator. │ ├──────────────────────┼──────────────────────────────────────┤ │CSS_MIDPOINT │Enlarges the mid-point and end-point │ │ │tick marks. │ ├──────────────────────┼──────────────────────────────────────┤ │CSS_NOBUTTON │Prevents the display of the + and - │ │ │value buttons. │ ├──────────────────────┼──────────────────────────────────────┤ │CSS_NONUMBER │Prevents the display of a scrollable │ │ │numeric value on the dial indicating │ │ │the dial's value. │ ├──────────────────────┼──────────────────────────────────────┤ │CSS_NOTEXT │Prevents the display of a window title│ │ │beneath the dial. │ ├──────────────────────┼──────────────────────────────────────┤ │CSS_POINTSELECT │Enables tracking of the dial's value │ │ │with the mouse. │ ├──────────────────────┼──────────────────────────────────────┤ │CSS_PROPORTIONALTICKS │Enables the length of the tick marks │ │ │to be calculated as a percentage of │ │ │the dial's radius. │ └──────────────────────┴──────────────────────────────────────┘ ═══ 12.1.2.1.1. More on Circular Slider Styles ═══ This section provides information on some of the styles. ═══ 12.1.2.1.1.1. Circular Slider Buttons ═══ The circular slider has a set of buttons, one to the left and the other to the right of the scroll range. These buttons are similar to the buttons found on the linear slider. When selected, they modify the value of the circular slider in opposing ways. If you decide you do not want to display these buttons as part of your circular slider, specify the style CSS_NOBUTTON. The bit maps that show a minus sign (-) on the left button and a plus sign (+) on the right button can be replaced. For example, you might want to use a left arrow () and a right arrow (). To set the bit map data for the replacement bit maps, the owner window must send the CSM_SETBITMAPDATA control message. The optimal size for the button bit maps is 10x10 pels. ═══ 12.1.2.1.1.2. Window Title ═══ Centered beneath the dial of the circular slider is a rectangular text field that contains the title of the window. To prevent the display of this feature, specify CSS_NOTEXT. ═══ 12.1.2.1.1.3. Dial Value Window ═══ Another option of the circular slider is a window, in the center of the dial, that displays the value of the dial in scrollable numeric text. To prevent the display of this window, specify CSS_NONUMBER. ═══ 12.1.2.1.1.4. 360-Degree Scale ═══ You can choose a scale of 360 degrees for your slider with CSS_360. Setting this style causes the CSS_NOBUTTON and CSS_NONUMBER styles to be set automatically. The CSS_NONUMBER style prevents the value indicator from corrupting the dial value. A 360-degree circular slider is displayed without the bit maps for the plus and minus buttons. ═══ 12.1.2.1.1.5. Tracking Modes for Direct Manipulation ═══ There are two tracking modes used for direct manipulation of the circular slider: scrolling the dial and point selection. The default tracking behavior is scrolling, where the dial position of the slider is changed gradually. For example, by holding down the select mouse button while the pointer is positioned on the indicator line of the dial, you can move the mouse and cause the dial to rotate. This gradual changing of the dial value might be desirable for a volume control. If the CSS_POINTSELECT style is specified for the circular slider, the position of the dial is changed immediately to a point on the scale that has been selected by the mouse. Point selection allows value changes to occur immediately. ═══ 12.1.2.1.1.6. Sizing Tick Marks ═══ When a low-resolution display is being used, or in situations where the circular slider must be made very small, the length of the tick marks can be sized proportionately to allow effective sizing of the circular slider. Specifying the CSS_PROPORTIONALTICKS style causes the length of the tick marks to be calculated as a percentage of the dial's radius. This style does not adversely affect the size of the push buttons and bit-map graphics an application might provide. ═══ 12.2. Using Slider Controls ═══ This section explains how to use sliders in your PM applications. It covers:  Creating a linear slider  Retrieving data for selected slider values  Creating a circular slider Code samples are provided. ═══ 12.2.1. Creating a Linear Slider ═══ Before the slider is created, a temporary SLDCDATA data structure is allocated, and variables are specified for the slider control window handle and slider style. The SLDCDATA data structure is allocated so that the scale increments and spacing of the slider can be specified. The slider style variable enables the application to specify style bits, SLS_* values, that are used to customize the slider. You create a slider by using the WC_SLIDER window class name in the ClassName parameter of WinCreateWindow call. The handle of the slider control window is returned in the slider window variable. After the slider is created, but before it is made visible, the application can set other slider control characteristics, such as:  Size and placement of tick marks  Text above one or more tick marks  One or more detents  Initial slider arm position The settings in the preceding list are just a few that an application can specify. Slider control messages are used to specify these settings. The sample code in the following figure shows an example of how a linear slider is created. The main components of the slider are labeled. Uses Os2Def,Os2Base,Os2PmApi; Var SldcData : SLDCDATA; (* SLDCDATA data structure *) SzTickText : Array[0..4] : CHAR; (* Text strings variable *) Idx : USHORT; (* Counter for setting text *) (* strings *) HwndSlider : HWND; (* Slider window handle *) UlSliderStyle : ULONG; (* Slider styles *) Begin (**********************************************************************) (* Initialize the parameters in the data structure. *) (**********************************************************************) sldcData.cbSize := sizeof(SLDCDATA); (* Size of SLDCDATA structure *) sldcData.usScale1Increments := 6; (* Number of increments *) sldcData.usScale1Spacing := 0; (* Use 0 to have slider calculate *) (* spacing *) (**********************************************************************) (* Set the SLS_* style flags to the default values, plus slider *) (* buttons right. *) (**********************************************************************) ulSliderStyle := SLS_HORIZONTAL Or (* Slider is horizontal *) SLS_CENTER Or (* Slider shaft centered in *) (* slider window *) SLS_HOMELEFT Or (* Home position is left edge of *) (* slider *) SLS_PRIMARYSCALE1 Or (* Scale is displayed above *) (* slider shaft *) SLS_BUTTONSRIGHT; (* Slider buttons at right end of *) (* slider *) (**********************************************************************) (* Create the slider control window. *) (* The handle of the window is returned in hwndSlider. *) (**********************************************************************) hwndSlider := WinCreateWindow( hwndClient, (* Parent window handle *) WC_SLIDER, (* Slider window class name *) nil, (* No window text *) ulSliderStyle, (* Slider styles variable *) 10, (* X coordinate *) 10, (* Y coordinate *) 150, (* Window width *) 80, (* Window height *) hwndClient, (* Owner window handle *) HWND_TOP, (* Sibling window handle *) ID_SLIDER, (* Slider control window ID *) &sldcData, (* Control data structure *) nil); (* No presentation parameters *) (**********************************************************************) (* Set tick marks at several places on the slider shaft using the *) (* primary scale. *) (**********************************************************************) WinSendMsg(hwndSlider, (* Slider window handle *) SLM_SETTICKSIZE, (* Message for setting tick mark *) (* size. *) MPFROM2SHORT( SMA_SETALLTICKS, (* Attribute for setting all tick *) (* marks to the same size *) 6), (* Draw tick marks 6 pixels long *) nil); (* Reserved value *) (**********************************************************************) (* Set text above the tick marks. *) (**********************************************************************) For idx := 0 To 4 Do Begin (* Count from 0 to 5 *) Str(10*idx, szTickText); (* Set text at increments of 10 *) WinSendMsg(hwndSlider, (* Slider window handle *) SLM_SETSCALETEXT, (* Message for setting text on a *) (* slider scale *) MPFROMSHORT(idx), (* Text string counter *) MPFROMP(szTickText)); (* Text to put on slider scale *) End; (**********************************************************************) (* Set detents between two of the tick marks on the slider shaft. *) (**********************************************************************) WinSendMsg(hwndSlider, (* Slider window handle *) SLM_ADDDETENT, (* Message for adding detents to *) (* a slider scale *) MPFROMSHORT(5), (* Put a detent 5 pixels from home*) nil); (* Reserved value *) WinSendMsg(hwndSlider, (* Slider window handle *) SLM_ADDDETENT, (* Message for adding detents to *) (* slider scale *) MPFROMSHORT(25), (* Put a detent 25 pixels from *) (* home *) nil); (* Reserved value *) (**********************************************************************) (* Set the slider arm position to the 1st increment on the scale. *) (**********************************************************************) WinSendMsg(hwndSlider, (* Slider window handle *) SLM_SETSLIDERINFO, (* Message for setting slider *) (* attributes *) MPFROM2SHORT( SMA_SLIDERARMPOSITION, (* ModIfy slider arm position *) SMA_INCREMENTVALUE), (* Use an increment value *) MPFROMSHORT(1)); (* Value to use is 1st *) (* increment *) (**********************************************************************) (* Since all items have been set, make the control visible. *) (**********************************************************************) WinShowWindow(hwndSlider, (* Slider window handle *) Ord(True)); (* Make the window visible *) End. ═══ 12.2.2. Retrieving Data for Selected Slider Values ═══ To retrieve data represented by a slider value, specify a variable for the current position of the slider arm. Then, use the SLM_QUERYSLIDERINFO message to retrieve information about the current slider arm position in increment coordinates. The code fragment in the following figure shows how to retrieve data for a selected slider value: Uses Os2Def,Os2Base,Os2PmApi; Var UlValue : ULONG; (* Variable in which to store *) (* strings *) Begin (**********************************************************************) (* Get the information about the current slider arm position in *) (* incremental coordinates. *) (**********************************************************************) ulValue := WinSendMsg( hwndSlider, (* Slider window handle *) SLM_QUERYSLIDERINFO, (* Message for querying slider *) (* attributes *) MPFROM2SHORT( SMA_SLIDERARMPOSITION, (* Get increment at which slider *) SMA_INCREMENTVALUE), (* arm is located *) nil); (* Reserved value *) End. ═══ 12.2.3. Creating a Circular Slider ═══ The circular slider PM window class WC_CIRCULARSLIDER is similar to the window class of a linear slider or a scroll bar. This window class must be registered with WinRegisterCircularSlider before you can create a circular slider. A circular slider can be created by a CONTROL statement in a dialog resource, as shown in the following figure: CONTROL "&tilde.Balance", ID_BALANCECS, 10, 50, 60, 60, WC_CIRCULARSLIDER, WS_TABSTOP &vbar. WS_VISIBLE &vbar. CSS_POINTSELECT A circular slider also can be created by specifying the WC_CIRCULARSLIDER window class name as a parameter of the WinCreateWindow call, as shown in the following sample code: hwndCS := WinCreateWindow (hwndClient, (* Parent handle *) WC_CIRCULARSLIDER, (* Class name *) '&tilde.Balance', (* Window text *) WS_VISIBLE Or WS_TABSTOP Or CSS_POINTSELECT, 0,0,0,0, (* Coordinates *) hwndClient, (* Owner handle *) HWND_TOP, (* Z-order *) ID_BALANCECS, (* Window ID *) nil, (* Control data *) nil); (* Presparam *) ═══ 12.2.4. Circular Slider Sample ═══ The following is a complete coding example for adding a circular slider, and includes the following files:  CIRCLE.C  CIRCLE.RC  CIRCLE.H ================ CIRCLE.C ================ Uses Os2Def,Os2Base,Os2PmApi; (* Global Variables *) Const MAIN_FRAME = 255; IDM_FILEMENU = 256; IDM_FILEEXIT = 257; ID_DIAL = 258; Var Hab : HAB; (* Сsken var tom!! *) Hmq : HMQ; (* Сsken var tom!! *) Qmsg : QMSG; (* Сsken var tom!! *) HwndFrame : HWND; (* Сsken var tom!! *) FlCreate : ULONG; (* Сsken var tom!! *) HwndClient : HWND; (* Сsken var tom!! *) Function MainProc( hwnd : HWND, msg : ULONG, mp1 : MPARAM, mp2 : MPARAM) Const hwndCirc : HWND; Var Hps : HPS; (* Сsken var tom!! *) Swp : SWP; (* Сsken var tom!! *) Begin Case msg Of WM_CLOSE: WinPostMsg(hwnd,WM_QUIT,0,0); MainProc := nil; Exit WM_COMMAND: (* Exit option was selected in the menu bar *) Case SHORT1FROMMP(mp1) Of IDM_FILEEXIT: WinPostMsg(hwnd,WM_QUIT,0,0); Halt(nil); End; MainProc := nil; Exit; WM_CONTROL: (* Process circular slider notIfication messages *) If (SHORT1FROMMP(mp1) = ID_DIAL) Then Begin Case SHORT2FROMMP(mp1) Of (* NotIfication codes can be specified here *) End; End; (* Default processing for other control window ids *) MainProc := (WinDefWindowProc(hwnd,msg,mp1,mp2)); WM_CREATE: (* Create circular slider control *) hwndCirc := WinCreateWindow(hwnd, WC_CIRCULARSLIDER, 'My Dial Window', WS_VISIBLE, 0, 0, 0, 0, (* Position & size *) hwnd, (* Client window *) HWND_TOP, ID_DIAL, nil,nil); (* SpecIfy range of values for circular slider *) WinSendMsg (hwndCirc, CSM_SETRANGE, MPFROMLONG(0), MPFROMLONG(100)); (* SpecIfy scroll & tick mark increments *) WinSendMsg (hwndCirc, CSM_SETINCREMENT, MPFROMLONG(10), MPFROMLONG(2)); (* Set initial value *) WinSendMsg (hwndCirc, CSM_SETVALUE, MPFROMLONG(80), nil); MainProc := Ord(False); Exit; WM_SIZE: (* The frame window has changed in size *) (* Recalculate size of circular slider *) WinQueryWindowPos(hwnd,&swp); WinSetWindowPos(hwndCirc, HWND_TOP, 0, 0, swp.cx, swp.cy, SWP_MOVE Or SWP_SIZE); MainProc := nil; Exit; WM_PAINT: WinEndPaint(hps); MainProc := nil; Else Begin MainProc := WinDefWindowProc(hwnd,msg,mp1,mp2); Exit; End; End; Begin (* Convert system pointer into hourglass pointer *) WinSetPointer(HWND_DESKTOP, WinQuerySysPointer(HWND_DESKTOP,SPTR_WAIT,Ord(False))); hab := WinInitialize(0); hmq := WinCreateMsgQueue(hab,0); WinRegisterClass(hab,'Client',MainProc,CS_SIZEREDRAW,0); flCreate := FCF_SYSMENU Or FCF_SIZEBORDER Or FCF_TITLEBAR Or FCF_MENU Or FCF_MINMAX Or FCF_SHELLPOSITION Or FCF_TASKLIST; hwndFrame := WinCreateStdWindow(HWND_DESKTOP, WS_VISIBLE, &flCreate, 'Client', 'My Dial', 0, 0, MAIN_FRAME, &hwndClient); (* Convert system pointer into arrow pointer *) WinSetPointer(HWND_DESKTOP, WinQuerySysPointer(HWND_DESKTOP,SPTR_ARROW,Ord(False))); While (WinGetMsg(hab,&qmsg,0,0,0)<>0) Do WinDispatchMsg(hab,&qmsg); WinDestroyWindow(hwndFrame); WinDestroyMsgQueue(hmq); WinTerminate(hab); (* Beep when done *) DosBeep(750,500); Halt(0); End. ================ CIRCLE.RC ================ #include #include "circle.h" ACCELTABLE MAIN_FRAME { VK_F3, IDM_FILEEXIT, VIRTUALKEY } MENU MAIN_FRAME { SUBMENU "~File", IDM_FILEMENU { MENUITEM "E~xit\tF3", IDM_FILEEXIT } } ================ CIRCLE.H ================ #define MAIN_FRAME 255 #define IDM_FILEMENU 256 #define IDM_FILEEXIT 257 #define ID_DIAL 258 ═══ 12.3. Graphical User Interface Support for Slider Controls ═══ This section describes the support the slider control provides for graphical user interfaces (GUIs). Except where noted, this support conforms to the guidelines in the SAA CUA Advanced Interface Design Reference. Since slider values all are mutually exclusive, only one of them can be selected at a time. Therefore, the only type of selection supported by the slider control is single selection. Note: If more than one slider window is open, selecting values in one slider window has no effect on the values selected in any other slider window. For linear sliders, a black square is drawn in the center of the slider arm to show which slider control window has the focus. An initial value is selected when the slider control is first displayed. If the application does not provide the initial selection for a linear slider (using the SLM_SETSLIDERINFO message) to position the slider arm, the value at the home position is selected automatically. The home position is the end of the slider that contains the lowest value on the scale. ═══ 12.3.1. Slider Navigation Techniques ═══ The slider control supports the use of pointing devices and the keyboard for selecting values. ═══ 12.3.1.1. Pointing Device Support ═══ A user can select slider values with a pointing device. The CUA guidelines defines mouse button 1 (the select button) as the button for selecting values, and button 2 (the drag button) for dragging the slider arm to a value. These definitions also apply to the same buttons on any other pointing device, such as a joystick. The select button and drag button can be used in conjunction with the following slider components to select slider values:  Slider arm Moving the pointer over the slider arm, then pressing and holding the select or drag buttons while moving the pointer, causes the slider arm to move in the direction the pointer is moving. When the button is released, the value closest to the slider arm position becomes the selected value.  Slider shaft Clicking the select button when the pointer is over the slider shaft causes the slider arm to move one increment in the direction of the pointer. For linear sliders, increments are determined by the initial values passed for the primary scale specified (SLS_PRIMARYSCALE1 or SLS_PRIMARYSCALE2) when the slider is created. Clicking the drag button when the pointer is over the slider shaft causes the slider arm to move to the pointer's location.  Slider buttons Clicking the select button when the pointer is over a slider button causes the slider arm to move one increment in the direction the arrow on the slider button is pointing. Slider buttons are optional. If used, two slider buttons are available to the user. The arrows on top of the slider buttons point to opposite ends of the slider. Both slider buttons are positioned at the same end of the slider. For linear sliders, slider buttons are enabled by specifying the appropriate SLS_* value when the slider control window is created. For horizontal sliders, you can specify either SLS_BUTTONSLEFT or SLS_BUTTONSRIGHT. For vertical sliders, you can specify either SLS_BUTTONSBOTTOM or SLS_BUTTONSTOP. The default is no slider buttons. If more than one of these style bits is specified, no slider buttons are enabled.  Detents A detent is similar to a tick mark on a linear slider scale because it represents a value on the scale. However, unlike a tick mark, a detent can be placed anywhere along the slider scale instead of in specific increments. A detent can be selected by moving the pointer over it and pressing the select button on the pointing device. When this happens, the slider arm moves to the position on the slider shaft indicated by the detent. ═══ 12.3.1.2. Keyboard Support ═══ A user can select a value by using the navigation keys to move the slider arm to the value or by typing a value in an entry field, if one is provided by the application, to change the slider arm position. The following list describes these methods of selecting slider values:  Values can be selected using the Up, Down, Left, and Right Arrow keys to move the slider arm one increment at a time. The Up and Down Arrow keys are enabled for vertical sliders, and the Right and Left Arrow keys are enabled for horizontal sliders. If no tick mark exists on the scale in the requested direction, the slider arm does not move. If an Arrow key is pressed in conjunction with the Shift key, the slider arm moves to the next detent instead of the next tick mark. If no detent exists on the scale in the requested direction, the slider arm does not move.  The Home and End keys can be used to select the lowest and highest values, respectively, in the scale. If the Ctrl key is pressed in combination with the Home or End keys, the result is the same as pressing only the Home or End keys.  The application can provide an optional entry field for the slider control. The entry field is a separate control, but it can work in conjunction with the slider control. If the application provides an entry field for the slider control window, it must be implemented as follows: - The user must be allowed to type a value into the entry field. - If the typed value is within the range of the slider scale, the slider arm moves to that value as soon as the value is typed. - No other action, such as pressing the Enter key, is required. ═══ 13. Spin Button Controls ═══ A spin button control (WC_SPINBUTTON window class) is a visual component that gives users quick access to a finite set of data by letting them select from a scrollable ring of choices. Because the user can see only one item at a time, a spin button should be used only with data that is intuitively related, such as a list of the months of the year, or an alphabetic list of cities or states. This chapter explains when and how to use spin buttons in PM applications. ═══ 13.1. About Spin Button Controls ═══ A spin button consists of at least one spin field that is a single-line entry (SLE) field, and up and down arrows that are stacked on top of one another. These arrows are positioned to the right of the SLE field. You can create multi-field spin buttons for those applications in which users must select more than one value. For example, in setting a date, the spin button control can provide individual fields for setting the month, day, and year. The first spin field in the spin button could contain a list of months; the second, a list of numbers; and the third, a list of years. The application uses a multi-field spin button by creating one master component that contains a spin field and the spin arrows, and servant components that contain only spin fields. The spin buttons are created at component initialization. The servant components are passed a handle to the master component in a message. When a servant spin field has the focus, it is spun by the arrows in the master component. The list of values in a spin button entry field can be an array of data or a list of consecutive integers, defined by an upper and a lower limit. ═══ 13.2. Using Spin Button Controls ═══ This section describes how to create a spin button control. ═══ 13.2.1. Creating a Spin Button ═══ A spin button is created as a public window class by using WinCreateWindow, with a class style of WC_SPINBUTTON and a window style of WS_VISIBLE. These are joined with any of the spin button style flags by using a logical OR (Or). The spin button style flags let you specify:  Character input restrictions (none, numeric, read-only)  Presentation of the data in the spin field (left-justified, right-justified, centered)  Presence or absence of a border around the spin field  Spin speed  Zero-padding of numeric spin fields The placement and width of the spin button component are specified as parameters in WinCreateWindow. The upper and lower limits of numeric fields, the value array pointer for arrays of strings, and the initial value in the spin field are all set by messages sent from the application to the component. You can destroy the spin button component window using WinDestroyWindow when finished. The component handle that was returned when the spin button was created is the input parameter to WinDestroyWindow. The following sample code shows an example of how to create a spin button. Uses Os2Def,Os2Base,Os2PmApi; Var UlSpinStyle : ULONG; (* Spin Button style *) HwndSpin : HWND; (* Spin Button window handle *) Begin (**********************************************************************) (* Set the SPBS_* style flags. *) (**********************************************************************) ulSpinStyle := SPBS_MASTER Or (* Spin button has its own *) (* buttons, *) SPBS_NUMERICONLY Or (* and it only holds numbers *) SPBS_JUSTRIGHT Or (* that are right justIfied, *) SPBS_FASTSPIN; (* and it spins faster as *) (* the arrows are held down *) (**********************************************************************) (* Create the Spin Button control window. *) (* The handle of the window is returned in hwndSpin. *) (**********************************************************************) hwndSpin := WinCreateWindow ( hwndClient, (* Parent window handle *) WC_SPINBUTTON, (* Spin Button window class name *) nil, (* No window text *) ulSpinStyle, (* Spin Button styles variable *) 10, (* X coordinate *) 10, (* Y coordinate *) 150, (* Window width *) 50, (* Window height *) hwndClient, (* Owner window handle *) HWND_TOP, (* Sibling window handle *) ID_SPINBUTTON, (* Spin Button control window ID *) nil, (* No control data structure *) nil); (* No presentation parameters *) (**********************************************************************) (* Set the limits of the Spin Button control, since it has a style *) (* of SPBS_NUMERICONLY. *) (**********************************************************************) WinSendMsg (hwndSpin, (* Spin Button window handle *) SPBM_SETLIMITS, (* Set limits message *) 1000, (* Spin Button maximum setting *) 0); (* Spin Button minimum setting *) (**********************************************************************) (* Set the initial value of the Spin Button. *) (**********************************************************************) WinSendMsg (hwndSpin, (* Spin Button window handle *) SPBM_SETCURRENTVALUE, (* Set current value message *) 100, (* Spin Button initial value *) nil); (* Reserved value *) (**********************************************************************) (* Because all items have been set, make the control visible. *) (**********************************************************************) WinShowWindow (hwndSpin, (* Spin Button window handle *) Ord(True)); (* Make the window visible *) End. ═══ 13.3. Graphical User Interface Support for Spin Button Controls ═══ Users can interact with the spin button using either the keyboard or a pointing device, such as a mouse, as follows:  Using the select button (button 1) on the pointing device, users first give focus to the spin field they want to change, and then click on either the Up Arrow or Down Arrow until the value they want is displayed in the spin field.  Using a keyboard, users press the: - Up Arrow and Down Arrow keys to see the choices - Left Arrow and Right Arrow keys to move the cursor left and right within a spin field - Home and End keys to move the cursor to the first and last characters in a spin field - Tab and Shift+Tab keys to move the input focus from one field to another in multi-field spin buttons Users can view the values in a spin field one at a time, or they can rapidly scroll a list by keeping either the Up or Down Arrow keys pressed. When a spin button is not read-only, users can advance quickly to the value they want to set in a spin field by typing over the value currently displayed. ═══ 14. Static Controls ═══ A static control is a simple text field, bit map, or icon that an application can use to label, enclose, or separate other control windows. This chapter describes how to create and use static controls in PM applications. ═══ 14.1. About Static Controls ═══ Unlike the other types of control windows, a static control does not accept user input or send notification messages to its owner. The primary advantage of a static control is that it provides a label or graphic that requires little attention from an application. At most, an application might change the text or position of a static control. ═══ 14.1.1. Keyboard Focus ═══ A static control never accepts the keyboard focus. When a static control receives a WM_SETFOCUS message, or when a user clicks the static control, the system advances the focus to the next sibling window that is not a static control. If the control has no siblings, the system gives the focus to the owner of the static control. ═══ 14.1.2. Static Control Handle ═══ Every static control is associated with a 32-bit data field. A static control with the SS_BITMAP or SS_ICON style uses this field to store the handle of the bit map or icon that it displays. An application can obtain that handle by sending the SM_QUERYHANDLE message to the control. An application can replace the bit map or icon by sending the SM_SETHANDLE message to the control, specifying a valid icon or bit map handle. Changing the handle causes the system to redraw the control. For a non-icon or non-bit map static control, the data field is available for application-defined data and has no effect on the appearance of the control. An application can retrieve the data field of a static control window by calling WinWindowFromID, using the handle of the owner and the window identifier of the static control. The static control window identifier is specified in either the dialog-window template or WinCreateWindow. ═══ 14.1.3. Static Control Styles ═══ A static control has style bits that determine whether the control displays text, draws a simple box containing text, displays an icon or a bit map, or shows a framed or unframed colored box. Applications can specify a combination of the following styles for a static control: ┌────────────────────┬────────────────────────────────────────┐ │Style Name │Description │ ├────────────────────┼────────────────────────────────────────┤ │SS_BITMAP │Draws a bit map. The bit map resource │ │ │must be provided in the │ │ │resource-definition file. To include the│ │ │bit map in a dialog window, the resource│ │ │identifier must be specified in the text│ │ │parameter of the CONTROL statement in │ │ │the resource definition file. To include│ │ │the bit map in a non-dialog window, the │ │ │ASCII representation of the identifier │ │ │must be specified in the pszName │ │ │parameter of WinCreateWindow, that is, │ │ │the first byte of the pszName parameter │ │ │must be the cross-hatch character (#), │ │ │and the remaining text must be the ASCII│ │ │representation of the identifier, for │ │ │example, #125. │ ├────────────────────┼────────────────────────────────────────┤ │SS_BKGNDFRAME │Creates a box whose frame has the │ │ │background color. │ ├────────────────────┼────────────────────────────────────────┤ │SS_BKGNDRECT │Creates a rectangle filled with the │ │ │background color. │ ├────────────────────┼────────────────────────────────────────┤ │SS_FGNDFRAME │Creates a box whose frame has the │ │ │foreground color. │ ├────────────────────┼────────────────────────────────────────┤ │SS_FGNDRECT │Creates a rectangle filled with the │ │ │foreground color. │ ├────────────────────┼────────────────────────────────────────┤ │SS_GROUPBOX │Creates a box whose upper-right corner │ │ │contains control text. This style is │ │ │useful for enclosing groups of radio │ │ │buttons or check boxes in a box. │ ├────────────────────┼────────────────────────────────────────┤ │SS_HALFTONEFRAME │Creates a box whose frame has halftone │ │ │shading. │ ├────────────────────┼────────────────────────────────────────┤ │SS_HALFTONERECT │Creates a box filled with halftone │ │ │shading. │ ├────────────────────┼────────────────────────────────────────┤ │SS_ICON │Draws an icon. The resource identifier │ │ │for the icon resource is determined the │ │ │same way as the SS_BITMAP style. The │ │ │icon resource must be in the │ │ │resource-definition file. │ ├────────────────────┼────────────────────────────────────────┤ │SS_SYSICON │Draws a system-pointer icon. The │ │ │resource identifier for the │ │ │system-pointer resource is determined │ │ │the same way as the SS_BITMAP style. To │ │ │display this system pointer, the system │ │ │calls WinQuerySysPointer with the │ │ │specified identifier. │ ├────────────────────┼────────────────────────────────────────┤ │SS_TEXT │Creates a box with formatted text. An │ │ │application can combine various │ │ │formatting options with this style to │ │ │produce formatted text in the boundaries│ │ │of the control. The formatting flags are│ │ │the same as those used for WinDrawText. │ └────────────────────┴────────────────────────────────────────┘ ═══ 14.1.4. Default Static Control Performance ═══ The messages specifically handled by the predefined static control class (WC_STATIC) are as follows: ┌──────────────────────┬──────────────────────────────────────┐ │Message Name │Description │ ├──────────────────────┼──────────────────────────────────────┤ │SM_QUERYHANDLE │Returns the handle associated with the│ │ │static control window. │ ├──────────────────────┼──────────────────────────────────────┤ │SM_SETHANDLE │Sets the handle associated with the │ │ │static control and invalidates the │ │ │control window, forcing it to be │ │ │redrawn. │ ├──────────────────────┼──────────────────────────────────────┤ │WM_ADJUSTWINDOWPOS │Adjusts the SWP data structure so that│ │ │the new window size matches the bit │ │ │map, icon, or system-pointer │ │ │dimensions associated with the static │ │ │control. │ ├──────────────────────┼──────────────────────────────────────┤ │WM_CREATE │Sets the text for a static-text │ │ │control. Loads the bit map or icon │ │ │resource for the bit map or icon │ │ │static control. Returns TRUE if the │ │ │resource cannot be loaded. │ ├──────────────────────┼──────────────────────────────────────┤ │WM_DESTROY │Frees the text for a static-text │ │ │control. Destroys the bit map or icon │ │ │for a bit map or icon static control. │ │ │The icon for a system-pointer static │ │ │control is not destroyed because it │ │ │belongs to the system. │ ├──────────────────────┼──────────────────────────────────────┤ │WM_ENABLE │Invalidates the entire static control │ │ │window, forcing it to be redrawn. │ ├──────────────────────┼──────────────────────────────────────┤ │WM_HITTEST │Returns the value HT_TRANSPARENT for │ │ │the following static-control styles: │ │ │o SS_BKGNDFRAME │ │ │o SS_BKGNDRECT │ │ │o SS_FGNDFRAME │ │ │o SS_FGNDRECT │ │ │o SS_GROUPBOX │ │ │o SS_HALFTONEFRAME │ │ │o SS_HALFTONERECT. │ │ │ │ │ │For other styles, this message returns│ │ │the result of WinDefWindowProc. │ ├──────────────────────┼──────────────────────────────────────┤ │WM_MATCHMNEMONIC │Returns TRUE if the mnemonic passed in│ │ │the mp1 parameter matches the mnemonic│ │ │in the control-window text. │ ├──────────────────────┼──────────────────────────────────────┤ │WM_MOUSEMOVE │Sets the mouse pointer to the arrow │ │ │pointer and returns TRUE. │ ├──────────────────────┼──────────────────────────────────────┤ │WM_PAINT │Draws the static control based on its │ │ │style attributes. │ ├──────────────────────┼──────────────────────────────────────┤ │WM_QUERYDLGCODE │Returns the predefined constant │ │ │DLGC_STATIC. │ ├──────────────────────┼──────────────────────────────────────┤ │WM_QUERYWINDOWPARAMS │Returns the requested window │ │ │parameters. │ ├──────────────────────┼──────────────────────────────────────┤ │WM_SETFOCUS │Sets the focus to the next sibling │ │ │window that can accept the focus; or │ │ │if no such sibling exists, sets the │ │ │focus to the parent window. │ ├──────────────────────┼──────────────────────────────────────┤ │WM_SETWINDOWPARAMS │Allows the text to be set (static-text│ │ │controls only). │ └──────────────────────┴──────────────────────────────────────┘ ═══ 14.2. Using Static Controls ═══ This section explains how to perform the following tasks:  Include a static control in a dialog window  Include a static control in a client window ═══ 14.2.1. Including a Static Control in a Dialog Window ═══ To include a static control in a dialog window, you must define the control in a dialog-window template in a resource-definition file. The following resource-definition file creates a dialog window that contains a static-text control and three static-icon controls: DLGTEMPLATE IDD_TOOLDLG LOADONCALL MOVEABLE DISCARDABLE BEGIN DIALOG "", IDD_TOOLDLG, 114, 53, 161, 127, FS_NOBYTEALIGN &vbar. FS_DLGBORDER &vbar. WS_VISIBLE &vbar. WS_SAVEBITS BEGIN CTEXT "Select a tool", IDS_TEXT, 49, 110, 56, 8, SS_TEXT &vbar. DT_CENTER &vbar. DT_TOP &vbar. WS_GROUP &vbar. WS_VISIBLE AUTORADIOBUTTON "Paintbrush", IDB_BRUSH, 63, 87, 61, 10, WS_TABSTOP &vbar. WS_GROUP &vbar. WS_VISIBLE AUTORADIOBUTTON "Scissors", IDB_SCISSORS, 63, 64, 60, 10, WS_TABSTOP &vbar. WS_VISIBLE AUTORADIOBUTTON "Eraser", IDB_ERASER, 65, 39, 43, 10, WS_TABSTOP &vbar. WS_VISIBLE ICON IDI_BRUSH, IDI_BRUSHICON, 33, 84, 22, 16, WS_GROUP &vbar. WS_VISIBLE ICON IDI_SCISSORS, IDI_SCISSORSICON, 33, 60, 22, 16, WS_GROUP &vbar. WS_VISIBLE ICON IDI_ERASER, IDI_ERASERICON, 33, 36, 22, 16, WS_GROUP &vbar. WS_VISIBLE PUSHBUTTON "OK", DID_OK, 10, 12, 38, 13, WS_TABSTOP &vbar. WS_GROUP &vbar. WS_VISIBLE PUSHBUTTON "Cancel", DID_CANCEL, 59, 12, 38, 13, BS_DEFAULT &vbar. WS_TABSTOP &vbar. WS_GROUP &vbar. WS_VISIBLE PUSHBUTTON "Help", IDB_HELP, 111, 13, 38, 13, BS_HELP &vbar. WS_TABSTOP &vbar. WS_GROUP &vbar. WS_VISIBLE END END ICON IDI_BRUSH brush.ico ICON IDI_SCISSORS scissr.ico ICON IDI_ERASER eraser.ico ═══ 14.2.2. Including a Static Control in a Client Window ═══ An application can include a static control in a non-dialog window by calling WinCreateWindow with the window class WC_STATIC. The flStyle parameter to WinCreateWindow defines the appearance of the control. The following code fragment creates a static text control whose size and position are based on the size of the client window and the metrics for the current font: Uses Os2Def,Os2Base,Os2PmApi; Const ID_TITLE = 5; Var Hwnd,hwndStatic,hwndClient : HWND; (* Сsken var tom!! *) Hps : HPS; (* Сsken var tom!! *) Rcl : RECTL; (* Сsken var tom!! *) Fm : FONTMETRICS; (* Сsken var tom!! *) UlTitleLen : ULONG; (* Сsken var tom!! *) SzTitle : PCHAR; (* Сsken var tom!! *) Begin szTitle := 'Static Text Controls'; (* Obtain the size of the client window *) hps := WinBeginPaint (hwnd, NULL, NULL); WinQueryWindowRect(hwnd, &rcl); (* Obtain a presentation space handle and *) (* the metrics for the current font *) GpiQueryFontMetrics(hps, sizeof(FONTMETRICS), &fm); (* Obtain the size of the static control text string *) ulTitleLen := strlen(szTitle); (* Create the static control. Base the size and *) (* position on the size of the client window and *) (* the metrics of the current font. *) hwndStatic := WinCreateWindow( hwndClient, (* Parent window *) WC_STATIC, (* Window class *) szTitle, (* Window text *) WS_VISIBLE Or (* Make it visible *) SS_TEXT Or (* Static-text control *) DT_VCENTER Or (* Center text vert. *) DT_CENTER, (* Center text horiz. *) ((rcl.xRight / 2) - (ulTitleLen / 2) * fm.lEmInc), (* x position *) rcl.yTop - fm.lEmHeight * 2, (* y position *) fm.lEmInc * ulTitleLen, (* Width *) fm.lEmHeight * 2, (* Height *) hwndClient, (* Owner window *) HWND_TOP, (* Top of z-order *) ID_TITLE, (* Window identIfier *) nil, (* Control data *) nil); (* Presentation parameters*) WinEndPaint(hps); End. If your application creates a static control with the SS_ICON or SS_BITMAP style, make sure that the resource identifier specified in the pszName parameter corresponds to an icon or a bit map resource in the resource-definition file. If there is no resource, the application cannot create the static control. ═══ 15. Title-Bar Controls ═══ A title bar is one of several control windows that comprise a standard frame window, giving the frame window its distinctive look and performance capabilities. This chapter describes how to create and use title-bar control windows in PM applications. ═══ 15.1. About Title Bars ═══ The title bar in a standard frame window performs the following four functions:  Displays the title of the window across the top of the frame window  Changes its highlighted appearance to show whether the frame window is active (Ordinarily, the topmost window on the screen is the active window.)  Responds to the actions of the user-for example, dragging the frame window to a new location on the screen.  Flashes (as a result of the WinFlashWindow function) to get the attention of the user. Once the frame controls are in place in the frame window, an application typically ignores them, because the system handles frame controls. In some cases, however, an application can take control of the title bar by sending messages to the title-bar control window. ═══ 15.1.1. Default Title-Bar Behavior ═══ A title-bar control window sends messages to its owner (the frame window) when the control receives user input. Following are the messages that the title-bar control processes. Each message is described in terms of how the title-bar control responds to that message. ┌────────────────────┬────────────────────────────────────────┐ │Message │Description │ ├────────────────────┼────────────────────────────────────────┤ │TBM_QUERYHILITE │Returns the highlighted state of the │ │ │title bar. │ ├────────────────────┼────────────────────────────────────────┤ │TBM_SETHILITE │Sets the highlighted state of the title │ │ │bar, repainting the title bar if the │ │ │state is changing. │ ├────────────────────┼────────────────────────────────────────┤ │WM_BUTTON1DBLCLK │Restores the title bar if the owner │ │ │window is minimized or maximized. If │ │ │the window is neither minimized nor │ │ │maximized, this message maximizes the │ │ │window. │ ├────────────────────┼────────────────────────────────────────┤ │WM_BUTTON1DOWN │Sends the WM_TRACKFRAME message to the │ │ │owner window to start the tracking │ │ │operation for the frame window. │ ├────────────────────┼────────────────────────────────────────┤ │WM_CREATE │Sets the text for the title bar. Returns│ │ │FALSE if the text is already set. │ ├────────────────────┼────────────────────────────────────────┤ │WM_DESTROY │Frees the window text for the title bar.│ ├────────────────────┼────────────────────────────────────────┤ │WM_HITTEST │Always returns HT_NORMAL, so that the │ │ │title bar does not beep when it is │ │ │disabled. (It is disabled when the frame│ │ │window is maximized.) │ ├────────────────────┼────────────────────────────────────────┤ │WM_PAINT │Draws the title bar. │ ├────────────────────┼────────────────────────────────────────┤ │WM_QUERYDLGCODE │Returns the predefined constant │ │ │DLGC_STATIC. The user cannot use the Tab│ │ │key to move to the title bar in a dialog│ │ │window. │ ├────────────────────┼────────────────────────────────────────┤ │WM_QUERYWINDOWPARAMS│Returns the requested window parameters.│ ├────────────────────┼────────────────────────────────────────┤ │WM_SETWINDOWPARAMS │Sets the specified window parameters. │ ├────────────────────┼────────────────────────────────────────┤ │WM_WINDOWPOSCHANGED │Returns FALSE. Processes this message to│ │ │prevent the WinDefWindowProc function │ │ │from sending the size and show messages.│ └────────────────────┴────────────────────────────────────────┘ ═══ 15.2. Using Title-Bar Controls ═══ This section explains how to:  Include a title bar in a frame window  Alter the dragging action of a title bar ═══ 15.2.1. Including a Title Bar in a Frame Window ═══ An application can include a title bar in a standard frame window by specifying the FCF_TITLEBAR flag in the WinCreateStdWindow function. The following code fragment shows how to create a standard frame window with a title bar, minimize and maximize (window-sizing) buttons, size border, system menu, and an application menu. Uses Os2Def,Os2Base,Os2PmApi; Const ID_MENU_RESOURCE = 101; Var HwndFrame,hwndClient : HWND; (* Сsken var tom!! *) SzClassName : Array[0..254] of UCHAR; (* Сsken var tom!! *) FlControlStyle : ULONG; (* Сsken var tom!! *) Begin flControlStyle := FCF_TITLEBAR Or FCF_MINMAX Or FCF_SIZEBORDER Or FCF_SYSMENU Or FCF_MENU; hwndFrame := WinCreateStdWindow(HWND_DESKTOP, WS_VISIBLE Or FS_ACCELTABLE, &flControlStyle, szClassName, '', 0, nil, ID_MENU_RESOURCE, &hwndClient); End. To get the window handle of a title-bar control, an application calls WinWindowFromID, specifying the frame-window handle and a constant identifying the title-bar control, as shown in the following code fragment: hwndTitleBar := WinWindowFromID(hwndFrame, FID_TITLEBAR); To set the text of a title bar, an application can use the WinSetWindowText function. The frame window passes the new text to the title-bar control in a WM_SETWINDOWPARAMS message. ═══ 15.2.2. Altering Dragging Action ═══ When the user clicks the title bar, the title-bar control sends a WM_TRACKFRAME message to its owner (the frame window). When the frame window receives the WM_TRACKFRAME message, the frame sends a WM_QUERYTRACKINFO message to itself to fill in a TRACKINFO structure that defines the tracking parameters and boundaries. To modify the default behavior, an application must subclass the frame window, intercept the WM_QUERYTRACKINFO message, and modify the TRACKINFO structure. If the application returns TRUE for the WM_QUERYTRACKINFO message, the tracking operation proceeds according to the information in the TRACKINFO structure. If the application returns FALSE, no tracking occurs. ═══ 16. Value Set Controls ═══ A value set control (WC_VALUESET window class), like a radio button, is a visual component that enables a user to select one choice from a group of mutually exclusive choices. However, unlike radio buttons, a value set can use graphic images (bit maps or icons), as well as colors, text, and numbers, to represent the items a user can select. This chapter presents the basics about value set controls and tells you how to create and use them in PM applications. ═══ 16.1. About Value Set Controls ═══ Even though text is supported, the purpose of a value set control is to display choices as graphic images for faster selection. The user can see the selections instead of having to take time to read descriptions of the choices. Using graphic images in a value set also lets you conserve space on the display screen. For example, if you want to let a user choose from a variety of patterns, you can present those patterns as value set choices, If long strings of data are to be displayed as choices, radio buttons should be used. However, for small sets of numeric or textual information, you can use either a value set or radio buttons. The value set is customizable to meet varying application requirements, while providing a user interface component that can be used easily to develop products that conform to the Common User Access (CUA) user interface guidelines. The application can specify different types of items, sizes, and orientations for its value sets, but the underlying function of the control remains the same. For a complete description of CUA value sets, refer to the SAA CUA Guide to User Interface Design and the SAA CUA Advanced Interface Design Reference. ═══ 16.1.1. Value Set Styles ═══ Value set control window styles are set when a value set window is created.  Set one of the following styles when creating a value set control window. You can override these styles by specifying VIA_BITMAP, VIA_ICON, VIA_TEXT, VIA_RGB, or VIA_COLORINDEX attributes for individual value set items. VS_BITMAP The attribute for each value set item is set to the VIA_BITMAP value set item attribute, which means the value set treats each item as a bit map unless otherwise specified. This is the default. VS_COLORINDEX The attribute for each value set item is set to the VIA_COLORINDEX value set item attribute, which means the value set treats each item as an index into the logical color table unless otherwise specified. This style is most often used when the colors currently available are adequate. VS_ICON The attribute for each value set item is set to the VIA_ICON value set item attribute, which means the value set treats each item as an icon unless otherwise specified. VS_RGB The attribute for each value set item is set to the VIA_RGB value set item attribute, which means the value set treats each item as a RGB color value unless otherwise specified. This style is most often used when you need to create new colors. VS_TEXT The attribute for each value set item is set to the VIA_TEXT value set item attribute, which means the value set treats each item as a text string unless otherwise specified.  Specify one or more of the following optional window styles, if desired, by using an OR operator (Or) to combine them with the style specified from the preceding list: VS_BORDER The value set draws a thin border around itself to delineate the control. VS_ITEMBORDER The value set draws a thin border around each item to delineate it from other items. Note: The VS_ITEMBORDER style is useful for items that are hard to see, such as faint colors or patterns. VS_OWNERDRAW The application is notified whenever the background of the value set window is to be painted. VS_RIGHTTOLEFT The value set interprets column orientation as right-to-left, instead of the default left-to-right arrangement. This means columns are numbered from right-to-left with the rightmost column being 1 and counting up as you move left. Home is the rightmost column and end is the leftmost column. There is no visible difference between a value set ordered left-to-right and a value set ordered right-to-left. Therefore, if your application uses multiple value sets, the ordering of the items should be consistent in each value set to avoid confusing the user. Note: The VS_RIGHTTOLEFT style is used on creation of the control. Changing this style after creation causes unexpected results. VS_SCALEBITMAPS The value set automatically scales bit maps to the size of the cell. If this style is not used, each bit map is centered in its cell. Also, if the cell is smaller than the bit map, the bit map is clipped to the size of the cell. ═══ 16.2. Using Value Set Controls ═══ This section provides information that will enable you to create and use a value set control effectively. ═══ 16.2.1. Creating a Value Set ═══ You create a value set by using the WC_VALUESET window class name in the ClassName parameter of WinCreateWindow call. Before the value set is created, a temporary VSCDATA data structure is allocated so that the number of rows and columns of the value set can be specified. Also, VS_* values are specified in the ulValueSetStyle variable so that the value set can be customized. The following sample code shows the creation of a value set: Uses Os2Def,Os2Base,Os2PmApi; Var VscData : VSCDATA; (* VSCDATA data structure *) HwndValueSet : HWND; (* Value set window handle *) UlValueSetStyle : ULONG; (* Value set style variable *) Begin (**********************************************************************) (* Initialize the parameters in the data structure. *) (**********************************************************************) vscData.cbSize := (* Size of value set equals size *) sizeof(VSCDATA); (* of VSCDATA *) vscData.usRowCount := 1; (* 1 row in the value set *) vscData.usColumnCount := 3; (* 3 columns in the value set *) (**********************************************************************) (* Set the VS_* style flags to customize the value set. *) (**********************************************************************) ulValueSetStyle := VS_RGB Or (* Use colors for items. *) VS_ITEMBORDER Or (* Put border around each value *) (* set item. *) VS_BORDER; (* Put border around the entire *) (* value set *) (**********************************************************************) (* Create the value set control window. *) (* The handle of the window is returned in hwndValueSet. *) (**********************************************************************) hwndValueSet := WinCreateWindow( hwndClient, (* Parent window handle *) WC_VALUESET, (* Value set class name *) nil, (* No window text *) ulValueSetStyle, (* Value set styles *) 10, (* X coordinate *) 10, (* Y coordinate *) 300, (* Window width *) 200, (* Window height *) hwndClient, (* Owner window handle *) HWND_TOP, (* Z-order position *) ID_VALUESET, (* Value set window ID *) &vscData, (* Control data structure *) nil); (* No presentation parameters *) (**********************************************************************) (* Set the color value for each item in each row and column. *) (**********************************************************************) WinSendMsg(hwndValueSet, (* Value set window handle *) VM_SETITEM, (* Message for setting items *) MPFROM2SHORT(1,1), (* Set item in row 1, column 1 *) MPFROMLONG($00FF0000)); (* to the color red. *) WinSendMsg(hwndValueSet, (* Value set window handle *) VM_SETITEM, (* Message for setting items *) MPFROM2SHORT(1,2), (* Set item in row 1, column 2 *) MPFROMLONG($0000FF00)); (* to the color green. *) WinSendMsg(hwndValueSet, (* Value set window handle *) VM_SETITEM, (* Message for setting items *) MPFROM2SHORT(1,3), (* Set item in row 1, column 3 *) MPFROMLONG($000000FF)); (* to the color blue. *) (**********************************************************************) (* Set the default selection. *) (**********************************************************************) WinSendMsg(hwndValueSet, (* Value set window handle *) VM_SELECTITEM, (* Message for selecting items *) MPFROM2SHORT(1,2), (* Item in row 1, column 2 *) nil); (* Reserved value *) (**********************************************************************) (* Since all items have been set in the control, *) (* make the control visible. *) (**********************************************************************) WinShowWindow(hwndValueSet, (* Value set window handle *) Ord(True)); (* Make the window visible *) End. ═══ 16.2.2. Retrieving Data for Selected Value Set Items ═══ The next step is to be able to retrieve the data represented by a value set item. To do this, variables are specified for combined row and column index values, item attributes, and item information. Then the VM_QUERYSELECTEDITEM, VM_QUERYITEMATTR, and VM_QUERYITEM messages are used to retrieve the index values, attributes, and data. The following sample code shows how data for selected value set items is retrieved: Uses Os2Def,Os2Base,Os2PmApi; Var UlIdx : ULONG; (* Combined row and column *) (* index value *) UsItemAttr : USHORT; (* Item attributes *) UlItemData : ULONG; (* Item data *) Begin (**********************************************************************) (* Get the row and column index values of the item selected by the *) (* user. These values are returned in the ulIdx parameter. *) (**********************************************************************) ulIdx := (ULONG)WinSendMsg( hwndValueSet, (* Value set window handle *) VM_QUERYSELECTEDITEM, (* Message for querying *) (* the selected item *) nil, nil); (* Reserved values *) (**********************************************************************) (* Determine the type of item that was selected. This message is *) (* only to determine how to interpret item data when a value set *) (* contains dIfferent types of items. *) (**********************************************************************) usItemAttr := WinSendMsg( hwndValueSet, (* Value set window handle *) VM_QUERYITEMATTR, (* Message for querying item attribute *) MPFROMLONG(ulIdx), (* Row and column of selected item *) nil); (* Reserved value *) (**********************************************************************) (* Get the information about the selected (non-textual) item. *) (* If you are dealing with text, you need to allocate a buffer *) (* for the text string. *) (**********************************************************************) ulItemData := WinSendMsg( hwndValueSet, (* Value set window handle *) VM_QUERYITEM, (* Message for querying an item *) MPFROMLONG(ulIdx), (* Row and column of selected item *) nil); (* Set to nil because the item is not *) (* a text item *) End. ═══ 16.2.3. Arranging Value Set Items ═══ The application defines the arrangement of value set items; they can be arranged in one or more rows, columns, or both. Items are placed from left to right in rows and from top to bottom in columns. The application can change the number of rows and columns at any time. The number of items that can be displayed depends on the number of items that fit into the spaces provided by the defined rows and columns. If the number of items exceeds the number of spaces, the excess items are not displayed. You can change the composition of a value set by specifying new items. The new items either can be added to the value set or can replace existing items. ═══ 16.3. Graphical User Interface Support for Value Set Controls ═══ This section describes the support the value set control provides for graphical user interfaces (GUIs). Except where noted, this support conforms to the guidelines in the SAA CUA Advanced Interface Design Reference. The GUI support provided by the value set control consists of Navigating to and selecting value set items. ═══ 16.3.1. Value Set Navigation Techniques ═══ Since all value set items are mutually exclusive, only one of them can be selected at a time. Therefore, the only type of selection supported by the value set control is single selection. Note: If more than one value set window is open, navigating to and selecting items in one value set window has no affect on the items displayed in any other value set window. An initial choice is selected when the value set control is first displayed. If the application does not provide the initial selection by using the VM_SELECTITEM message, the choice in row 1, column 1 is selected automatically. The value set control supports the use of a pointing device, such as a mouse, and the keyboard for navigating to and selecting items, except for items that are dimmed on the screen. This dimming of items is called unavailable-state emphasis and indicates that the items cannot be selected. However, the selection cursor, a dotted outline that usually indicates that an item can be selected, can be moved to unavailable items so that a user can press F1 to determine why they cannot be selected. The following sections describe the pointing device and keyboard support for the value set control. ═══ 16.3.1.1. Pointing Device Support ═══ A user can use a pointing device to select value set items. The SAA CUA Guide to User Interface Design defines mouse button 1, the select button, to be used for selecting items. This definition also applies to the same button on any other pointing device. An item can be selected by moving the pointer of the pointing device to the item and clicking the select button. When this happens, a black box is drawn around the item to show that it has been selected. The black box is called selected-state emphasis. In addition, the selection cursor is drawn inside the black box. ═══ 16.3.1.2. Keyboard Support ═══ The value set control supports automatic selection, which means that an available item is selected when the selection cursor is moved to that item. The item is given selected-state emphasis as soon as the selection cursor is moved to it. No further action, such as pressing the spacebar, is required. The same black box and dotted outline are used, for selected-state emphasis and the selection cursor respectively, as when an item is selected with a pointing device. A user can navigate to and select an item by using either the navigation keys or mnemonic selection to move the selection cursor to the item, as described in the following list:  Items can be selected using the Up, Down, Left, and Right Arrow keys to move the selection cursor from one item to another.  The Home and End keys can be used to select the leftmost and rightmost items, respectively, in the current row. If the Ctrl key is pressed in combination with the Home or End key, the item in the top row and the leftmost column, or the item in the bottom row and the rightmost column, respectively, is selected. Note: The preceding description assumes that the current style of the value set window is left-to-right. However, if the VS_RIGHTTOLEFT style bit is set, the directions described for the Home, End, Ctrl+Home, and Ctrl+End keys in the preceding paragraph are reversed.  The PgUp key can be used to select the item in the top row that is directly above the current position of the selection cursor. The PgDn key can be used to select the item in the bottom row that is directly below the current position of the selection cursor. If the space in the top or bottom row directly above or below the current cursor position is blank, the cursor moves to the blank space.  Another keyboard method of selecting items is mnemonic selection. A user performs mnemonic selection by pressing a character key that corresponds to an underlined character. Coding a tilde (~) before a text character in the item causes that character to be underlined and activates it as a mnemonic selection character. When this happens, the selection cursor is moved to the item that contains the underlined character, and that item is selected. ═══ 16.4. Enhancing Value Set Controls Performance and Effectiveness ═══ This section provides dynamic resizing and scrolling to enable you to fine-tune a value set control. ═══ 16.4.1. Dynamic Resizing and Scrolling ═══ The value set control supports dynamic resizing if the application sends the WM_SIZE message to a value set window. This means that the value set control automatically recalculates the size of the items when either the user or the application changes the size of the value set window. If the value set window's size is decreased so that the window is not large enough to display all of the items the value set contains, the items are clipped. If scroll bars are desired to allow the clipped information to be scrolled into view, they must be provided by the application. ═══ 17. Windows ═══ To most users, a window is a rectangular area of the display screen where an application receives input from the user and displays output. This chapter describes the parts of the operating system that enable a Presentation Manager (PM) application to create and use windows; manage relationships between windows; and size, move, and display windows. An overview of the following topics is presented:  Window types, classes, and styles  Window-creation techniques  Window messages and message queues  Methods of window input and output  Window resources and procedures  Window identification and modification Subsequent chapters present more in-depth descriptions of windows, their advantages and uses, along with example code fragments. ═══ 17.1. About Windows ═══ A PM application can interact with the user and perform tasks only by way of windows. Each window shares the screen with other windows, including those from other applications. The user employs the mouse and keyboard to interact with windows and their owner applications. ═══ 17.1.1. Desktop Window and Desktop-Object Window ═══ The OS/2 operating system automatically creates the desktop window (known as the workplace in user terminology) when it starts a PM session. ┌────────────────────────────────────────────────┐ │ Desktop Window │ │ ┌────────────────────────────┐ │ │ │ Main Window 3 │ │ │ │ ┌─────────────────────├──────┐ │ │ │ │ Main Window 2 │ │ │ │ │ ┌─────────────────────├──────┐ │ │ │ │ ┌─── Main Window 1 │ │ │ │ │ │Chi│ ┌───────────────┐ │ │ │ │ │ │Win│ │ │ │ │ │ │ │ │2A │ │ ├──────┐ │ │ │ └────── └─── │Child Window 1a│ │ │ │ │ │ │ └────├──────────┘ │ │ │ │ └────── │ Child Window 1b │ │ │ │ │ └─────────────────┘ │ │ │ └────────────────────────────┘ │ └────────────────────────────────────────────────┘ Desktop Window Containing Windows of Several Applications The desktop window paints the background color of the screen and serves as the "progenitor" of all the windows displayed by all PM applications (but not of object windows, which do not require screen display). To make the desktop the parent in the WinCreateStdWindow function, you specify HWND_DESKTOP. The windows immediately below the desktop are called main or top-level windows; these are called primary windows in user terminology. Every PM application creates at least one window to serve as the main window for that application. Most applications also create many other windows, directly or indirectly, to perform tasks related to the main window. Each window helps display output and receive input from the user. The previous figure shows the desktop window containing windows of several applications. Notice that the main windows can overlap one another. (At times, it is possible for a main window to be completely hidden.) Operations in one main window normally do not affect the other main windows. The desktop-object window is like a desktop window that is never displayed; it serves as the base window to coordinate the activity of an application's object windows. The desktop-object window cannot display windows nor process keyboard and mouse input. The primary purpose of the desktop-object window is to enable you to create windows that need not respond to messages at the same rate as the user interface. ═══ 17.1.2. Window Relationships ═══ Window relationships define how windows interact with each other-on the screen and through messages. There are parent-child window relationships and window-owner relationships. The parent-child relationship determines where and how windows appear when drawn on the screen. It also determines what happens to a window when a related window is destroyed or hidden. The parent-child rules apply to all windows at all times and cannot be modified. Ownership determines how windows communicate using messages. Cooperating windows define and carry out their rules of ownership. Although some windows (such as windows of the preregistered public window class, WC_FRAME) have very complex rules of ownership, the application usually defines the ownership rules. The following figure represents the logical relationship of the windows in two applications. Desktop Window ┌─┐ Application 1 │ │ Application 2 ┌─ ── ── ── ── ── ── ─┐ │ │ ┌─ ── ── ── ── ── ── ─┐ ┌───────────────├─┘ └─├──────────────┐ │ │ ┌─────────────├─────├────────────┐ │ │ │ │ │ │ │ Main Window 1 │ │ Main Window 2 │ │ │ │ │ │ ┌──────┘ └──────┐ │ │ ┌──────┘ └──────┐ │ │ ┌───────────┐ │ │ ┌───────────┐ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─┘ └─┘ └─┘ │ Child Child │ │ Child Child │ Window 1.1 Window 1.2 Window 2.1 Window 2.2 │ │ │ │ │ │ └─┘ │ Child │ │ │ Window 1.1.1 └─ ── ── ── ── ── ── ─┘ └─ ── ── ── ── ── ── ─┘ Typical Window Relationships ═══ 17.1.2.1. Parent-Child Relationship ═══ Most windows have a parent window. (The exceptions are the desktop and desktop-object windows, which the system creates at system startup.) An application specifies the parent when it creates a window; then, the system uses the parent to determine where and how to draw any new windows, as well as when to destroy the windows (free all associated resources and remove the windows from the screen). A child window is drawn relative to its parent. The coordinates given to specify the position of a window's lower-left corner are relative to the lower-left corner of its parent. For example, a main window (child of the desktop) is drawn relative to the lower-left corner of the screen (the desktop window's lower-left corner). All main windows are siblings because they share a common parent, the desktop window. Because sibling windows can overlap, an application or a user arranges the windows, one behind another (like a stack of papers on a desk), in the desired viewing order (called z-order). Z-order uses the desktop as a reference point for a "three-dimensional" ranking of the overlapping windows: the topmost window has the highest ranking, while the window at the bottom of the stack has the lowest ranking. The parent of the sibling windows is always at the bottom of the z-order. The following figure illustrates the hierarchy of such an arrangement. ┌─────────┐ │ Desktop │ └──├─├─├──┘ │ │ │ Parent Child │ │ │ ┌─ ─ ─ ─ ─ ─ ─ ─┐ │ │ │ Siblings │ │ │ ┌────────┐ │ ┌──────────┐ │ │ │ └──│ Main 1 ├───────│ Child 1A │ │ │ └────────├──┐ │ └──────────┘ │ │ │ │ │ ┌──────────┐ │ │ └────│ Child 1A │ │ │ │ │ └──────────┘ │ │ └─ ─ ─ ─ ─ ─ ─ ─┘ │ │ ┌────────┐ ┌──────────┐ │ └────│ Main 2 ├───────│ Child 2A │ │ └────────┘ └──────────┘ │ ┌────────┐ └──────│ Main 3 │ └────────┘ Window Hierarchy Although PM supports z-order, it does not enforce the expected appearance unless you specify the CS_CLIPCHILDREN or CS_CLIPSIBLINGS styles. No part of a child window ever appears outside the borders of its parent. If an application creates a window that is larger than its parent, or positions a window so that some or all of it extends beyond the borders of the parent, the extended portion of the child window is not drawn. An application can use the WS_CLIPCHILDREN or WS_CLIPSIBLINGS styles to remove from a window's clipping area (the area in which the window can paint) the area occupied by its child or sibling windows. For example, an application can use these styles to prevent a window from painting over a child or sibling window containing a complex graphic that would be time-consuming to redraw. When a window is minimized, hidden, or destroyed, all of its children are hidden, minimized, or destroyed as well. The order of destruction is always such that every window is destroyed before its parent. The window-destruction sequence starts at the bottom of descendancy so that all related windows can be cleaned up; the last one to go is the window you asked to be destroyed. The final PM task in a window-destruction sequence is to send a WM_DESTROY message to that window, so it has one last chance to release any resources it has allocated and may still be holding. Every window has only one parent, but can have any number of children. window in this tree is said to be a descendant of any window appearing above it in the branch, and an ancestor of any window appearing below it. There are two special cases, of course: the window immediately above is called the window's parent, and any window immediately below it is called its child. An application can change a window's parent window at any time by using the WinSetParent function. Changing the parent window also changes where and how the child window is drawn. The system displays the child within the borders of the new parent and draws the window according to the styles specified for the new parent. ═══ 17.1.2.2. Ownership ═══ Any window can have an owner window. Typically, an application uses ownership to establish a connection between windows so that they can perform useful tasks together. For example, the title bar in an application's main window is owned by the frame window; but, together, the user can move the entire main window by clicking the mouse in the title bar and dragging. An application can set the owner window when it creates the window or at a later time. Ownership establishes a relationship between windows that is independent of the parent-child relationship. While there are few predefined rules for owner- and owned-window interaction, a window always notifies its owner of anything considered a significant event. The preregistered public window classes provided by the OS/2 operating system recognize ownership. Control windows of classes such as WC_TITLEBAR and WC_SCROLLBAR, notify their owners of events; frame windows, of class WC_FRAME, receive and process notification messages from the control windows they own. For example, a title-bar control sends a notification message to its owner when it receives a mouse click. If the owner is a frame window, it receives the notification message and prepares to move itself and its children. Owner and owned windows must be created by the same thread; that is, they must belong to the same message queue. Because ownership is independent of the parent-child relationship, the owner and owned windows do not have to be descendants of the same parent window. However, this can affect how windows are destroyed. Destroying an owner window does not necessarily destroy an owned window. Except for frame windows, an application that needs to destroy an owned window that is not a descendant of the owner window must do so explicitly. Frame windows sometimes own windows that are not descendants but, instead, are siblings. A frame window has the following special ownership properties:  When the frame window is destroyed, it destroys all of the windows it owns, even if they are not descendants.  When a frame window moves, the windows it owns move also. Owned windows that are not descendants maintain their positions, relative to the upper-left (not the usual lower-left) corner of the owner window. An owned window with the style FS_NOMOVEWITHOWNER does not move.  When the frame window changes its position in the z-order, it changes the z-order of all the windows it owns.  When the frame window is minimized or hidden, it hides all the windows it owns. Owned windows hidden this way are restored when the frame window is restored. If an application needs this type of special processing for its own window classes, it must provide that support in the window procedures for those classes. ═══ 17.1.2.3. Object Windows ═══ Any descendant of the desktop-object window is called an object window. Typically, an application uses an object window to provide services for another window. For example, an application can use an object window to manage a shared database. In this way, a window can obtain information from the shared database by sending a message to and receiving a reply from the object window. Only two system-defined messages are available to an object window-WM_CREATE and WM_DESTROY-but the object window enables the user to implement a set of user-defined messages. The window procedure for an object window does not have to process paint messages or user input. The object window processes only messages that affect the data belonging to the object. HWND_OBJECT is the only identifier needed to create an object window. It is very unwise to create descendants of HWND_OBJECT in the same thread that creates descendants of HWND_DESKTOP: this causes the system to hang up or, at the very least, behave slowly. Object windows, sometimes referred to as orphan windows, require no owner. The rules for parent-child and ownership relationships also apply to object windows. In particular, changing the parent window of an object window to the desktop window, or to a descendant of the desktop window, causes the system to display the object window if the object window has the WS_VISIBLE style. ═══ 17.1.3. Application Windows ═══ An application can use several types of secondary windows: frame windows, client windows, control windows, dialog windows, message boxes, and menus. Typically, an application's main window consists of several of these windows acting as one. A frame window is a window that an application uses as the base when constructing a main window or other composite window, such as a dialog window or message box. (A composite window is a collection of windows that interact with one another and are kept together as a unit.) A frame window provides basic features, such as borders and a menu bar. Frame windows have a set of resources associated with them. These include icons, menus, and accelerators (shortcut keys to the user), which, typically, are defined in an application's resource file. A dialog window is a frame window that contains one or more control windows. Dialog windows are used almost exclusively for prompting the user for input. An application usually creates a dialog window when it needs additional information to complete a command. The application destroys the dialog window after the user has provided the requested information. A message box is a frame window that an application uses to display a note, caution, or warning to the user. For instance, an application can use a message box to inform the user of a problem that the application encountered while performing a task. A client window is the window in which the application displays the current document or data. For example, a desktop-publishing application displays the current page of a document in a client window. Most applications create at least one client window. The application must provide a function, called a window procedure, to process input to the client window and to display output. A control window is a window used in conjunction with another window to perform useful tasks, such as displaying a menu or scrolling information in a client window. The operating system provides several predefined control-window classes that an application can use to create control windows. Control windows include buttons, entry fields, list boxes, combination boxes, menus, scroll bars, static text, and title bars. A menu is a control window that presents a list of commands and other menus to the user. Using a mouse or the keyboard, the user can select a task; the application then performs the selected task. ═══ 17.1.4. Window Input and Output ═══ The user directs input data to windows from a mouse and the keyboard. Keyboard input goes to the window with input focus, and, normally, mouse input goes to the window under the mouse pointer. Windows also are places to display output data. PM uses windows to display text and graphics on the screen and to process input from the mouse and keyboard. Windows provide the same input and output capabilities as a virtual graphics terminal without having direct control of the hardware. An application is responsible for painting the data for the window classes it registers and creates. This data can be graphics text or pictures or fixed-size alphanumeric text. Normally it is not necessary for the application to paint the system-provided window classes; the OS/2 window procedures for those window classes do the painting. ═══ 17.1.4.1. Active Window and Focus Window ═══ All frame-window ancestors of the input focus window are said to be active, meaning that the user interacts with them. The active window usually is the topmost main window, which is positioned above all other top-level windows on the screen. The active window is indicated by some form of highlighting. For example, a highlighted title bar shows that a standard frame window is active; an active dialog window has a highlighted border. These types of highlighting ensure that the user can see the window that is accepting input. A main window (or one of its child windows) is activated by using a mouse or the keyboard. When a window is activated, it receives a WM_ACTIVATE message with its first parameter set to TRUE. When it is deactivated, it receives a WM_ACTIVATE message with its first parameter set to FALSE. The focus window can be the active window or one of its descendant windows. The user can change the input focus the same way active windows are changed-by mouse or keyboard. However, the application has more control over the input focus. For example, in a window containing several text entry fields, the tab keys can move the input focus from one input field to another. A WM_SETFOCUS message is sent to the window procedure when a window is gaining or losing the input focus. The WinQueryFocus function tells the user which window has the input focus. ═══ 17.1.4.2. Messages ═══ Messages are a fundamental part of the operating system. PM applications use messages to communicate with the operating system and one another. The system uses messages to communicate with applications to ensure concurrent running and sharing of devices. Typically, a message notifies the receiving application that an event has occurred. The operating system identifies the appropriate application window to receive a message by the window handle included in the message. Sources of events that cause messages to be issued to applications are the user, the operating system, the application, or another application. ═══ 17.1.4.2.1. The User ═══ Mouse or keyboard input to an application window causes the operating system to direct messages to that window. ═══ 17.1.4.2.2. The Operating System ═══ Managing the application windows on the screen, the operating system issues messages to the windows, usually as an indirect result of user interaction. These messages enable the system to work in a uniform and well-ordered manner. For example, where several application windows overlap, and the user terminates an application so that its window disappears, the operating system issues messages to the underlying application windows so that they can repaint themselves. ═══ 17.1.4.2.3. The Application ═══ An event can occur in the application to which another part of that application should respond; for example, when the contents of its window no longer accurately reflect the status of the application. The application can define its own messages outside the range of system-defined messages to communicate such events. ═══ 17.1.4.2.4. Another Application ═══ Communication with other applications through the operating system ensures cooperative use of the system; it even can be used to exchange data. For example, an arithmetic application can supply the results of a lengthy calculation to a business graphics application. ═══ 17.1.4.3. Enabled and Disabled Windows ═══ An application uses the WinEnableWindow function to enable or disable window input. By default, a window is enabled when it is created. However, an application can disable a newly created window. An application usually disables a window to prevent the user from using the window. For example, an application might disable a push button in a dialog window. Enabling a window restores normal input; an application can enable a disabled window at any time. When an application uses the WinEnableWindow function to disable an existing window, that window also loses keyboard focus. WinEnableWindow sets the keyboard focus to NULL, which means that no window has the focus. If a child window or other descendant window has the keyboard focus, it loses the focus when the parent window is disabled. An application can determine whether a window is enabled by calling WinIsWindowEnabled. ═══ 17.1.4.4. System-Modal Window ═══ An application can designate a system-modal window: a window that receives all keyboard and mouse input, effectively disabling all other windows. The user must respond to the system-modal window before continuing work in other windows. An application sets and clears the system-modal window by using the WinSetSysModalWindow function. Because system-modal windows have absolute control of input, you must be careful when using them in your applications. Ideally, an application uses a system-modal window only when there is danger of losing data if the user does not respond to a problem immediately. Although an application can destroy a system-modal window, the new active window then becomes a system-modal window. An application can make another window active while the first system-modal window exists. But again, the new active window will become the system-modal window. In general, once a system-modal window is set, it continues to exist in the PM session until the application explicitly clears it. ═══ 17.1.5. Window Creation ═══ Before any thread in an application can create windows, it must: 1. Call WinInitialize to create an anchor block 2. Call WinCreateMsgQueue to create a message queue for the thread Then, it can create one or more windows by calling one of the window-creation functions, such as WinCreateWindow. The window-creation functions require that the following information be supplied in some form:  Class  Styles  Name  Parent window  Position relative to the parent window  Position relative to any sibling windows (z-order)  Dimensions  Owner window  Identifier  Class-specific data  Resources Every window belongs to a window class that defines that window's appearance and behavior. The chief component of the window class is the window procedure. The window procedure is the function that receives and processes all messages sent to the window. Every window has a style. The window style specifies aspects of a window's appearance and behavior that are not specified by the window's class. For example, the WC_FRAME class always creates a frame window, but the FS_BORDER, FS_DLGBORDER, and FS_SIZEBORDER styles determine the style of a frame window's border. A few window styles apply to all windows, but most apply only to windows of specific window classes. The window procedure for a given class interprets the style and allows an application to adapt a window of a given class for a special circumstance. For example, an application can give a window the style WS_SYNCPAINT to cause it to be painted immediately whenever any portion of the window becomes invalid. Normally, a window is painted only if there are no messages waiting in the message queue. A window can have a text string associated with it. Typically, the window text is displayed in the window or in a title bar. The class of window determines whether the window displays the text and, if so, where the text appears within the window. Every window except the desktop window and desktop-object window has a parent window. The parent provides the coordinate system used to position the window and also affects aspects of a window's appearance. For example, when the parent window is minimized, hidden, or destroyed, the parent's child windows are minimized, hidden, or destroyed also. Every window has a screen position, size, and z-order position. The screen position is the location of the window's lower-left corner, relative to the lower-left corner of its parent window. A window's size is its width and height, measured in pels. A window's z-order position is the position of the window in the order of overlapping windows. This viewing order is oriented along an imaginary axis, the z axis, extending outward from the screen. The window at the top of the z-order overlaps all sibling windows (that is, windows having the same parent window). A window at the bottom of the z-order is overlapped by all sibling windows. An application sets a window's z-order position by placing it behind a given sibling window or at the top or bottom of the z-order of the windows. A window can own, or be owned by, another window. The owner-owned relationship affects how messages are sent between windows, allowing an application to create combinations of windows that work together. A window issues messages about its state to its owner window; the owner window issues messages back about what action to perform next. The window handle is a unique number across the system that is totally unambiguous-it identifies one particular window in the system and is assigned by the system. A window identifier is analogous to a "given" name in family relationships; the only requirement is that the name be unique among siblings. A window can have class-specific data that further defines how the window appears and behaves when it is created. The system passes the class-specific data to the window procedure, which then applies the data to the new window. ═══ 17.1.5.1. Window-Creation Functions ═══ The basic window-creation function is WinCreateWindow. This function uses information about a window's class, style, size, and position to create a new window. All other window-creation functions, such as WinCreateStdWindow and WinCreateDlg, supply some of this information by default and create windows of a specific class or style. Although the WinCreateWindow function provides the most direct means of creating a window, most applications do not use it. Instead, they often use the WinCreateStdWindow function to create a main window and the WinDlgBox or WinCreateDlg functions to create dialog windows. The WinCreateMenu, WinLoadMenu, WinLoadDlg, WinMessageBox, and WinCreateFrameControls functions also create windows. Each of these functions substitutes for one or more required calls to WinCreateWindow to create a given window. For example, an application can create a frame window, one or more control windows, and a client window in a single call to WinCreateStdWindow. ═══ 17.1.5.2. Window-Creation Messages ═══ While creating a window, the system sends messages to that window's window procedure. The window procedure receives a WM_CREATE message, saying that the window is being created. The window also receives a WM_ADJUSTWINDOWPOS message, specifying the initial size and position of the window being created. This message lets the window procedure adjust the size and position of the window before the window is displayed. The system also sends other messages while creating a window; the number and order of these messages depend on the class and style of the window and the function used to create it. ═══ 17.1.6. Window Classes ═══ Each window of a specific window class uses the window procedure associated with that class. An application can create one or more windows that belong to the same window class. Because each window of the same class is processed by the same window procedure, they all behave the same way. Since many windows can result from one window procedure, coding overhead is greatly reduced. There are two types of window classes: public and private. ═══ 17.1.6.1. Public Window Classes ═══ A public window class is one that has a reentrant window procedure that is registered and resides in a dynamic link library (DLL); it can be used by any process in the system to create windows. The operating system provides several preregistered public window classes. You can specify the system-provided window classes by using the symbolic identifiers that have the prefix WC_, as shown in the following table: ┌───────────────┬─────────────────────────────────────────────┐ │Class Name │Description │ ├───────────────┼─────────────────────────────────────────────┤ │WC_BUTTON │Consists of buttons and boxes the user can │ │ │select by clicking the pointing device or │ │ │using the keyboard. │ ├───────────────┼─────────────────────────────────────────────┤ │WC_CONTAINER │Creates a control for the user to group │ │ │objects in a logical manner. A container can│ │ │display those objects in various formats or │ │ │views. The container control supports drag │ │ │and drop so the user can place information in│ │ │a container by simply dragging and dropping. │ ├───────────────┼─────────────────────────────────────────────┤ │WC_ENTRYFIELD │Consists of a single line of text that the │ │ │user can edit. │ ├───────────────┼─────────────────────────────────────────────┤ │WC_FRAME │A window class that can contain child windows│ │ │of many of the other window classes. │ ├───────────────┼─────────────────────────────────────────────┤ │WC_LISTBOX │Presents a list of text items from which the │ │ │user can make selections. │ ├───────────────┼─────────────────────────────────────────────┤ │WC_MENU │Presents a list of items that can be │ │ │displayed horizontally as menu bars, or │ │ │vertically as pull-down menus. Menus usually│ │ │are used to provide a command interface to │ │ │applications. │ ├───────────────┼─────────────────────────────────────────────┤ │WC_NOTEBOOK │Creates a control for the user that is │ │ │displayed as a number of pages. The top page│ │ │is visible, and the others are hidden, with │ │ │their presence being indicated by a visible │ │ │edge on each of the back pages. │ ├───────────────┼─────────────────────────────────────────────┤ │WC_SCROLLBAR │Lets the user scroll the contents of an │ │ │associated window. │ ├───────────────┼─────────────────────────────────────────────┤ │WC_SLIDER │Creates a control that is usable for │ │ │producing approximate (analog) values or │ │ │properties. Scroll bars were used for this │ │ │function in the past, but the slider provides│ │ │a more flexible method of achieving the same │ │ │result, with less programming effort. │ ├───────────────┼─────────────────────────────────────────────┤ │WC_SPINBUTTON │Creates a control that presents itself to the│ │ │user as a scrollable ring of choices, giving │ │ │the user quick access to the data. The user │ │ │is presented only one item at a time, so the │ │ │spin button should be used with data that is │ │ │intuitively related. │ ├───────────────┼─────────────────────────────────────────────┤ │WC_STATIC │Simple display items that do not respond to │ │ │keyboard or pointing device events. │ ├───────────────┼─────────────────────────────────────────────┤ │WC_TITLEBAR │Displays the window title or caption and lets│ │ │the user move the window's owner. │ ├───────────────┼─────────────────────────────────────────────┤ │WC_VALUESET │Creates a control similar in function to the │ │ │radio buttons but provides additional │ │ │flexibility to display graphical, textual, │ │ │and numeric formats. The values set with │ │ │this control are mutually exclusive. │ └───────────────┴─────────────────────────────────────────────┘ With the exception of WC_FRAME, the system-provided window classes are known as control window classes because they give the user an easy means of controlling specific types of interaction. For example, the WC_BUTTON class allows single or multiple selections. These windows conform to the IBM* Systems Application Architecture (SAA) Common User Access (CUA) definition. They are designed specifically to provide function that meets the needs for a graphics-based standard user interface. The code fragments provided in this guide make extensive use of the system window classes. ═══ 17.1.6.2. Private Window Classes ═══ A private window class is one that an application registers for its own use; it is available only to the process that registers it. The application-provided window procedure for a private window class resides either in the application's executable files or in a DLL file. A private window class is deleted when its registering process is terminated. ═══ 17.1.7. Window Styles ═══ A window can have a combination of styles; an application can combine styles by using the bitwise inclusive OR operator. An application usually sets the window styles when it creates the window. The OS/2 operating system provides several standard window styles that apply to all windows. It also provides many styles for the predefined frame and control windows. The frame and control styles are unique to each predefined window class and can be used only for windows of the corresponding class. Initially, the styles of the window class used to create the window determine the styles of the new window. For example, if the window class has the style CS_SYNCPAINT, all windows created using that class, by default, will have the window style WS_SYNCPAINT. The OS/2 operating system has the following standard window styles: ┌─────────────────────────┬─────────────────────────────────────────────┐ │Style Name │Description │ ├─────────────────────────┼─────────────────────────────────────────────┤ │WS_CLIPCHILDREN │Prevents a window from painting over its │ │ │child windows. This style increases the time │ │ │necessary to calculate the visible region. │ │ │This style is usually not necessary because │ │ │if the parent and child windows overlap and │ │ │both are invalidated, the system draws the │ │ │parent window before drawing the child │ │ │window. If the child window is invalidated │ │ │independently of the parent window, the │ │ │system redraws only the child window. If the │ │ │update region of the parent window does not │ │ │intersect the child window, drawing the │ │ │parent window causes the child window to be │ │ │redrawn. This style is useful to prevent a │ │ │child window that contains a complex graphic │ │ │from being redrawn unnecessarily. │ │ │WS_CLIPCHILDREN is an absolute requirement if│ │ │a window with children ever performs output │ │ │in response to any message other than │ │ │WM_PAINT. Only WM_PAINT processing is │ │ │synchronized such that the children will get │ │ │their messages after the parent. │ ├─────────────────────────┼─────────────────────────────────────────────┤ │WS_CLIPSIBLINGS │Prevents a window from painting over its │ │ │sibling windows. This style protects sibling │ │ │windows but increases the time necessary to │ │ │calculate the visible region. This style is │ │ │appropriate for windows that overlap and that│ │ │have the same parent window. │ ├─────────────────────────┼─────────────────────────────────────────────┤ │WS_DISABLED │Used by an application to disable a window. │ │ │It is up to the window to recognize this │ │ │style and reject input. │ ├─────────────────────────┼─────────────────────────────────────────────┤ │WS_GROUP │Specifies the first control of a group of │ │ │controls in which the user can move from one │ │ │control to the next by using the ARROW keys. │ │ │All controls defined after the control with │ │ │the WS_GROUP style belong to the same group. │ │ │The next control with the WS_GROUP style ends│ │ │the first group and starts a new group. │ ├─────────────────────────┼─────────────────────────────────────────────┤ │WS_MAXIMIZED │Enlarges a window to the maximum size. │ ├─────────────────────────┼─────────────────────────────────────────────┤ │WS_MINIMIZED │Reduces a window to the size of an icon. │ ├─────────────────────────┼─────────────────────────────────────────────┤ │WS_PARENTCLIP │Extends a window's visible region to include │ │ │that of its parent window. This style │ │ │simplifies the calculation of the child │ │ │window's visible region but is potentially │ │ │dangerous because the parent window's visible│ │ │region is usually larger than the child │ │ │window. │ ├─────────────────────────┼─────────────────────────────────────────────┤ │WS_SAVEBITS │Saves the screen area under a window as a bit│ │ │map. When the user hides or moves the window,│ │ │the system restores the image by copying the │ │ │bits; there is no need to add the area to the│ │ │uncovered window's update region. The style │ │ │can improve system performance but also can │ │ │consume a great deal of memory. It is │ │ │recommended only for transient windows, such │ │ │as menus and dialog windows, not for main │ │ │application windows. │ ├─────────────────────────┼─────────────────────────────────────────────┤ │WS_SYNCPAINT │Causes a window to receive WM_PAINT messages │ │ │immediately after a part of the window │ │ │becomes invalid. Without this style, the │ │ │window receives WM_PAINT messages only if no │ │ │other message is waiting to be processed. │ ├─────────────────────────┼─────────────────────────────────────────────┤ │WS_TABSTOP │Specifies one of any number of controls │ │ │through which the user can move by tabbing. │ │ │Pressing the TAB key moves the keyboard focus│ │ │to the next control that has the WS_TABSTOP │ │ │style. │ ├─────────────────────────┼─────────────────────────────────────────────┤ │WS_VISIBLE │Makes a window visible. The operating system │ │ │draws the window on the screen unless │ │ │overlapping windows completely obscure it. │ │ │Windows without this style are hidden. If │ │ │overlapping windows completely obscure the │ │ │window, the window is still considered │ │ │visible. (Visibility means that the │ │ │operating system draws the window if it can.)│ └─────────────────────────┴─────────────────────────────────────────────┘ ═══ 17.1.8. Window Handles ═══ After creating a window, the creation function returns a window handle that uniquely identifies the window. An application can use this handle to direct the action of functions to the window. Window handles have the data type HWND; applications must use this data type when declaring variables that hold window handles. There are special constants that an application can use instead of a window handle in certain functions. For example, an application can use HWND_DESKTOP in the WinCreateWindow function to specify the desktop window as the new window's parent. Similarly, HWND_OBJECT represents the desktop-object window. HWND_TOP and HWND_BOTTOM represent the top and bottom positions relative to the z-order position of a window. Although the NULL constant is not a window handle, an application can use it in some functions to specify that no window is affected. For example, an application can use NULL in the WinCreateWindow function to create a window that has no owner window. Some functions might return NULL, indicating that the given action applies to no window. ═══ 17.1.9. Window Size and Position ═══ A window's size and position can be expressed as a bounding rectangle, given in coordinates relative to its parent. An application specifies the window's initial size and position when creating the window. To use the system-default values for the initial size and position of a frame window, an application can specify the FCF_SHELLPOSITION frame-creation flag. The application can change a window's size and position at any time. Note: The default coordinate system for a window specifies that the point (0,0) is at the lower-left corner of the window, with coordinates increasing as they go upward and to the right. A window can be positioned anywhere in relation to its parent. ═══ 17.1.9.1. Size ═══ A window's size (width and height) is given in pels, in the range 0 through 65535. A window can have 0 width and height; however, a window with 0 width or height is not drawn on the screen, even though it has the WS_VISIBLE style. An application can create very large windows; however, it should check the size of the screen before enlarging a window size. One way to choose an appropriate size is to use the WinGetMaxPosition function to retrieve the size of the maximized window. A window that is larger than its maximized size will be larger than the screen also. An application can retrieve the current size of the window by using the WinQueryWindowRect function. ═══ 17.1.9.2. Position ═══ A window's position is defined as the x,y coordinates of its lower-left corner. These coordinates, sometimes called window coordinates, always are relative to the lower-left corner of the parent window. For example, a window having the coordinates (10,10) is placed 10 pels to the right of, and 10 pels up from, the lower-left corner of its parent window. Notice, however, that a window can be positioned anywhere in relation to its parent, but always relative to the parent's lower-left corner. Adjusting a window's position can improve drawing performance. For example, an application could position a window so that its horizontal position is a multiple of 8, relative to the screen origin (the lower-left corner of the screen). Coordinates that are multiples of 8 correspond to byte boundaries in the screen-memory bit map. It is usually faster to start drawing at a byte boundary. By default, the system positions a frame window on a byte boundary; but an application can override this action by using the FCF_NOBYTEALIGN style when creating the window. ═══ 17.1.9.3. Size and Position Messages ═══ A window receives messages when it changes size or position. Before a change is made, the system might send a WM_ADJUSTWINDOWPOS message to allow the window procedure to make final adjustments to the window's size and position. This message includes a pointer to an SWP structure that contains the requested width, height, and position. If the window procedure adjusts these values in the structure, the system uses the adjusted values to redraw the window. The WM_ADJUSTWINDOWPOS message is not sent if the change is a result of a call to the WinSetWindowPos function with the SWP_NOADJUST constant specified. After a change has been made to a window, the system sends a WM_SIZE message to specify the new size of the window. If the window has the class style CS_MOVENOTIFY, the system also sends a WM_MOVE message, which includes the new position for the window. The system sends a WM_SHOW message if the visibility of the window has changed. ═══ 17.1.9.4. System Commands ═══ An application that has a window with a system menu can change the size and position of that window by sending system commands. The system commands are generated when the user chooses commands from the system menu. An application can emulate the user action by sending a WM_SYSCOMMAND message to the window. Following are some of the system commands: ┌───────────────┬─────────────────────────────────────────────┐ │Command │Description │ ├───────────────┼─────────────────────────────────────────────┤ │SC_SIZE │Starts a Size command. The user can change │ │ │the size of the window with a mouse and the │ │ │keyboard. │ ├───────────────┼─────────────────────────────────────────────┤ │SC_MOVE │Starts a Move command. The user can move the│ │ │window with a mouse and the keyboard. │ ├───────────────┼─────────────────────────────────────────────┤ │SC_MINIMIZE │Minimizes the window. │ ├───────────────┼─────────────────────────────────────────────┤ │SC_MAXIMIZE │Maximizes the window. │ ├───────────────┼─────────────────────────────────────────────┤ │SC_RESTORE │Restores a minimized or maximized window to │ │ │its previous size and position. │ ├───────────────┼─────────────────────────────────────────────┤ │SC_CLOSE │Closes the window. This command sends a │ │ │WM_CLOSE message to the window. The window │ │ │performs all tasks needed to clean up and │ │ │destroy itself. │ └───────────────┴─────────────────────────────────────────────┘ ═══ 17.1.10. Window Data ═══ Every window has an associated data structure. The window data structure contains all the information specified for the window at the time it was created and any additional information supplied for the window since that time. Although the exact size and meaning of the information in the window data structure are private to the system, an application can access any of the following data items via system-provided functions:  Pointer to window-instance data structure  Pointer to window procedure  Parent-window handle  Owner-window handle  Handle of first child window  Handle of next sibling window  Window size and position (expressed as a rectangle)  Window style  Window identifier  Update-region handle  Message-queue handle An application can examine and modify this data by using functions such as WinQueryWindowUShort and WinSetWindowUShort. These functions let an application access data that is stored as 16-bit integers. Other functions let an application access data containing 32-bit integers and pointers. Several functions indirectly affect the data items in the window data structure. For example, the WinSubclassWindow function replaces the window-procedure pointer, and the WinSetWindowPos function changes the size and position of the window. An application can extend the number of available data items in the window data structure by specifying a count of extra bytes when it registers the corresponding window class. Then, the window procedure can use these bytes to store information about the window. The WinQueryWindowUShort and WinSetWindowUShort functions give direct access to the extra bytes. It generally is not a good idea to use direct storage in the window data. It is better to allocate a data structure dynamically and set a pointer to that data structure in the window words. This provides two advantages: 1. Most importantly, it is a symbolic way of referencing the data structure. It is very easy to make mistakes and provide the wrong offsets to WinQueryWindowUShort and so forth. 2. You now can add and remove fields without cross dependencies because you now use symbolic references; whereas, when you use the technique of putting window words directly in the window data structure, you have to account for changed offsets. ═══ 17.1.11. Window Resources ═══ Window resources are read-only data segments stored in an application's EXE file or in a dynamic link library's DLL file. Predefined PM window resources include keyboard accelerator tables, icons, menus, bit maps, dialog boxes, and so forth; these are not a regular part of the application window's code and data. Because, in most cases, window resources are not loaded into memory when the operating system runs a program, the resources can be shared by multiple instances of the same application. Most window resources are stored in a format that is unique to each resource type. The application does not need to know these formats because the system translates them, as necessary, for use in PM functions. The following table lists the ten most commonly used PM window resource types. ┌───────────────┬─────────────────────────────────────────────┐ │Resource │Description │ │Identifier │ │ ├───────────────┼─────────────────────────────────────────────┤ │RT_ACCELTABLE │Keyboard accelerator table │ ├───────────────┼─────────────────────────────────────────────┤ │RT_BITMAP │Bit map │ ├───────────────┼─────────────────────────────────────────────┤ │RT_DIALOG │Dialog box template │ ├───────────────┼─────────────────────────────────────────────┤ │RT_FONT │Font │ ├───────────────┼─────────────────────────────────────────────┤ │RT_FONTDIR │Font directory │ ├───────────────┼─────────────────────────────────────────────┤ │RT_MENU │Menu template │ ├───────────────┼─────────────────────────────────────────────┤ │RT_MESSAGE │Message string │ ├───────────────┼─────────────────────────────────────────────┤ │RT_POINTER │Icon or mouse │ ├───────────────┼─────────────────────────────────────────────┤ │RT_RCDATA │Programmer-defined data │ ├───────────────┼─────────────────────────────────────────────┤ │RT_STRING │Text string │ └───────────────┴─────────────────────────────────────────────┘ To access these resources, you must prepare a resource file (ASCII file with the extension .RC). Then the ASCII resource file must be compiled into binary images using the resource compiler. The compiled resource file extension is RES; it can be linked into your program's EXE file or to a dynamic link library's DLL file. ═══ 17.1.12. Maximized and Minimized Windows ═══ A maximized window is a window that has been enlarged to fill the screen. Although a window's size can be set so that it fills the screen exactly, a maximized window is slightly different: the system automatically moves the window's title bar to the top of the screen and sets the WS_MAXIMIZED style for the window. A minimized window is a window whose size has been reduced to exactly the size of an icon or, in the Workplace Shell*, it disappears altogether (by default). Like a maximized window, a minimized window is more than just a window of a given size; typically, the system moves the (icon) minimized window to the lower part of the screen and sets the WS_MINIMIZED style for that window. The lower part of the screen is sometimes called the icon area. Unless the application specifies another position, the system moves a minimized window into the first available icon position in the icon area. If a window is created with the WS_MAXIMIZED or WS_MINIMIZED styles, the system draws the window as a maximized or minimized window. An application can restore maximized or minimized windows to their previous size and position by specifying the SWP_RESTORE flag in a call to the WinSetWindowPos function. ═══ 17.1.13. Window Visibility ═══ A window that is a descendant of the desktop window can be either visible or invisible. The system displays a visible window on the screen. It hides an invisible window by not drawing it. If a window is visible, the user can supply input to the window and view the window's output. If a window is invisible, the window, in effect, is disabled. An invisible window can process messages from the system or from other windows, but it cannot process user input or display output. An application sets a window's visibility state when it creates the window. Later, a user or the application can change the visibility state. The visible region of a window is the position clipped by any overlapping windows. These overlapping windows can be child windows or other main windows in the system. The visible region is defined by a set of one or more rectangles, as shown in the following figure. ┌───────────────────────────────────────────┐ │ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ │ │ ░ A ░░░░░░░░░░░░ ┌───────────────┐ ░░░░░░ │ │ ░░░░░░░░░░░░░░░░ │ B │ ░░░░░░ │ │ ░░░░░░ ┌─────────├─────┐ │ ░░░░░░ │ │ ░░░░░░ │ C │ │ ░░░░░░ │ │ ░░░░░░ │ ├─────────┘ ░░░░░░ │ │ ░░░░░░ │ │ ░░░░░░░░░░░░░░░░ │ │ ░░░░░░ └───────────────┘ ░░░░░░░░░░ ┌─────├─────────┐ │ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ │ D │ │ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ │ │ └───────────────────────────────────── │ └───────────────┘ ┌───────┐ │ ░░░░░ │ - Visible region for Window A │ ░░░░░ │ └───────┘ Visible Region for Window A A window is visible if the WS_VISIBLE style is set for the window. By default, the WinCreateWindow function creates invisible windows unless the application specifies WS_VISIBLE. The application often hides a window to keep its operational details from the user. For example, an application can keep a new window invisible while it customizes the window's appearance. An application can determine whether a window has the WS_VISIBLE style by using the WinIsWindowVisible function. Even if a window has the WS_VISIBLE style, the user might not be able to see the window on the screen because other windows completely overlap it, or it might have been moved beyond the edge of its parent. A visible window is subject to the clipping rules established by its parent-child relationship. If the window's parent window is not visible, the window will not be visible. Because a child window is drawn relative to its parent's lower-left corner, if the parent window is moved beyond the edge of the screen, the child window also will be moved. In other words, if a user moves the parent window containing the child window far enough off the edge of the screen, the user will not be able to see the child window, even though the child window and its parent window have the WS_VISIBLE style. To determine whether the user actually can see a window, an application can use the WinIsWindowShowing function. ═══ 17.1.14. Window Destruction ═══ In general, an application must destroy all the windows it creates. It does this by using the WinDestroyWindow function. When a window is destroyed, the system hides the window, if it is visible, and then removes any internal data associated with the window. This invalidates the window handle so that it can no longer be used by the application. An application destroys many of the windows it creates soon after creating them. For example, an application usually destroys a dialog window as soon as the application has sufficient input from the user to continue its task. An application eventually destroys the main window of the application (before terminating). Destroying a window does not affect the window class from which the window was created. New windows still can be created using that class, and any existing windows of that class continue to operate. When the application calls WinDestroyWindow, the system searches the descendancy tree for all windows below the specified window and destroys them from the bottom up, so each child receives WM_DESTROY before its parent. Each destroyed window is responsible for cleaning up its own resources in response to the WM_DESTROY message. If a presentation space was created by the WinGetPS function for any of the windows to be destroyed, it must be released by calling the WinReleasePS function. The application must do this before calling the WinDestroyWindow function. If a presentation space is associated with the device context for the window, the application must disassociate or destroy the presentation space by using the GpiAssociate or GpiDestroyPS function before calling WinDestroyWindow. Failing to release a resource can cause an error. For more information about presentation spaces and device contexts, see Painting and Drawing. If the window being destroyed is the active window, both the active and focus states are transferred to another window. The window that becomes the active window is the next window, as determined by the Alt+Esc key combination. The new active window then determines which window receives the keyboard focus. ═══ 17.2. Using Windows ═══ The following sections explain how to create and use windows in an application, how to manage ownership and parent-child window relationships, and how to move and size windows. ═══ 17.2.1. Creating a Top-Level Frame Window ═══ The main window in most applications is a top-level frame window. An application creates a top-level frame window by specifying the handle of the desktop window, or HWND_DESKTOP, as the hwndParent parameter in a call to the WinCreateStdWindow function. The following figure shows the main() function for a simple PM application. This function initializes the application, creates a message queue, and registers the window class for the client window before creating a top-level frame window. Uses Os2Def,Os2Base,Os2PmApi; Const IDR_RESOURCES = 1; Uses Os2Def,Os2Base,Os2PmApi; Var HwndFrame : HWND; (* Сsken var tom!! *) HwndClient : HWND; (* Сsken var tom!! *) Hmq : HMQ; (* Сsken var tom!! *) Qmsg : QMSG; (* Сsken var tom!! *) Hab : HAB; (* Сsken var tom!! *) FlFrameFlags : ULONG; (* Сsken var tom!! *) Begin (* Set the frame-window creation flags. *) FlFrameFlags := FCF_TITLEBAR Or (* Title bar *) FCF_SIZEBORDER Or (* Size border *) FCF_MINMAX Or (* Minimize and maximize buttons. *) FCF_SYSMENU Or (* System menu *) FCF_SHELLPOSITION Or (* System-default size and position *) FCF_TASKLIST ; (* Add name to Task List. *) (* Initialize the application for PM *) hab := WinInitialize(0); (* Create the application message queue. *) (* Register the class for the client window. *) WinRegisterClass( hab, (* Anchor block handle *) 'MyPrivateClass', (* Name of class being registered *) ClientWndProc, (* Window procedure for class *) CS_SIZEREDRAW Or (* Class style *) CS_HITTEST, (* Class style *) 0); (* Extra bytes to reserve *) (* Create a top-level frame window with a client window *) (* that belongs to the window class "MyPrivateClass". *) hwndFrame := WinCreateStdWindow( HWND_DESKTOP, (* Parent is desktop window. *) WS_VISIBLE, (* Make frame window visible. *) &flFrameFlags, (* Frame controls *) 'MyPrivateClass', (* Window class for client *) nil, (* No window title *) WS_VISIBLE, (* Make client window visible . *) 0, (* Resources in application module *) IDR_RESOURCES, (* Resource identIfier *) nil); (* Pointer to client window handle *) (* Start the main message loop. Get messages from the *) (* queue and dispatch them to the appropriate windows. *) While (WinGetMsg(hab, &qmsg, 0, 0, 0)<>0) Do WinDispatchMsg(hab, &qmsg); (* Main loop has terminated. Destroy all windows and the *) (* message queue; then terminate the application. *) WinDestroyWindow(hwndFrame); WinDestroyMsgQueue(hmq); WinTerminate(hab); Halt(0); End. ═══ 17.2.2. Creating an Object Window ═══ An application can create an object window by using the WinCreateWindow function and setting the desktop-object window as the parent window. The code fragment in the following figure shows how to create an object window. Uses Os2Def,Os2Base,Os2PmApi; Const ID_OBJWINDOW = 2; Var HwndObject : HWND; (* Сsken var tom!! *) Begin hwndObject := WinCreateWindow( HWND_OBJECT, (* Parent is object window. *) 'MyObjClass', (* Window class for client *) nil, (* Window text *) 0, (* No styles for object window *) 0, 0, (* Lower-left corner *) 0, 0, (* Width and height *) nil, (* No owner *) HWND_BOTTOM, (* Inserts window at bottom of z-order *) ID_OBJWINDOW, (* Window identIfier *) nil, (* No class-specIfic data *) nil); (* No presentation data *) End. ═══ 17.2.3. Querying Window Data ═══ An application can examine the values in the data structure associated with a window by using the WinQueryWindowUShort and WinQueryWindowULong functions. Each of these functions specifies a structure data item to examine. The index value can be an integer representing a zero-based byte index or a constant (QWS_) that identifies a specific item of data. The code fragment in the following figure obtains the programmer-defined identifier of the object window defined in the previous example: Uses Os2Def,Os2Base,Os2PmApi; Var HwndObject : HWND; (* Сsken var tom!! *) UsObjID : USHORT; (* Сsken var tom!! *) Begin usObjID := WinQueryWindowUShort(hwndObject, QWS_ID); End. ═══ 17.2.4. Changing the Parent Window ═══ An application can change a window's parent window by using the WinSetParent function. For example, in an application that uses child windows to display documents, you might want only the active document window to show a system menu. You can do this by changing that menu's parent window back and forth between the document window and the object window when WM_ACTIVATE messages are received. This technique is shown in the code fragment in the following figure. Var hwndFrame, hwndSysMenu, hwnd : HWND; (* Сsken var tom!! *) Case msg Of WM_ACTIVATE: (* Get the handles of the frame window and system menu. *) hwndFrame := WinQueryWindow(hwnd, QW_PARENT); hwndSysMenu := WinWindowFromID(hwndFrame, FID_SYSMENU); (* If the window is being activated, make the frame window the *) (* parent of the system menu. Otherwise, hide the system menu *) (* by making the object window the parent. *) If ( SHORT1FROMMP(mp1)) Then WinSetParent(hwndSysMenu, hwndFrame, Ord(True)) Else WinSetParent(hwndSysMenu, HWND_OBJECT, Ord(True)); Halt(0); End; ═══ 17.2.5. Finding a Parent, Child, or Owner Window ═══ An application can determine the parent, child, and owner windows for any window by using the WinQueryWindow function. This function returns the window handle of the requested window. The code fragment in the following figure determines the parent window of the given window: Uses Os2Def,Os2Base,Os2PmApi; Var HwndParent : HWND; (* Сsken var tom!! *) HwndMyWindow : HWND; (* Сsken var tom!! *) Begin hwndParent := WinQueryWindow(hwndMyWindow, QW_PARENT); The code fragment in the following figure determines the topmost child window (the child window in the top z-order position): Uses Os2Def,Os2Base,Os2PmApi; Var HwndTopChild : HWND; (* Сsken var tom!! *) HwndParent : HWND; (* Сsken var tom!! *) Begin hwndTopChild := WinQueryWindow(hwndParent, QW_TOP); If a given window does not have an owner or child window, WinQueryWindow returns NULL. ═══ 17.2.6. Setting an Owner Window ═══ An application can set the owner for a window by using the WinSetOwner function. Typically, after setting the owner, a window notifies the owner window of the new relationship by sending it a message. The code fragment in the following figure shows how to set the owner window and send it a message: Uses Os2Def,Os2Base,Os2PmApi; Var HwndMyWindow : HWND; (* Сsken var tom!! *) HwndNewOwner : HWND; (* Сsken var tom!! *) Begin If (WinSetOwner(hwndMyWindow, hwndNewOwner)) (* Send a notIfication message. *) WinSendMsg(hwndNewOwner, (* Sends to owner *) WM_CONTROL, (* Control message for notIfication *) (MPARAM) NEW_OWNER, (* NotIfication code *) nil); (* No extra data *) A window can have only one owner, so WinSetOwner removes any previous owner. ═══ 17.2.7. Retrieving the Handle of a Child or Owned Window ═══ A parent or owner window can retrieve the handle of a child or owned window by using the WinWindowFromID function and supplying the identifier of the child or owned window. WinWindowFromID searches all child and owned windows to locate the window with the given identifier. The window identifier is set when the application creates the child or owned window. Typically, an owned window uses WinQueryWindow to get the handle of the owner window; then uses WinSendMsg to issue a notification message to its owner window. The code fragment in the following figure retrieves the window handle of an owner window and sends the window a WM_ENABLE message. Uses Os2Def,Os2Base,Os2PmApi; Var HwndOwned : HWND; (* Сsken var tom!! *) HwndOwner : HWND; (* Сsken var tom!! *) Begin case WM_CONTROL: switch (SHORT2FROMMP (mp2)) { case BN_CLICKED: hwndOwned := WinWindowFromID(hwndOwner, (ULONG)SHORT1FROMMP(mp1)); WinSendMsg(hwndOwned, WM_ENABLE, (MPARAM)Ord(True), (MPARAM) nil); return 0; . . (* Check for other notIfication codes. *) . End. An application also can retrieve the handle of a child window by using the WinWindowFromPoint function and supplying a point in the corresponding parent window. ═══ 17.2.8. Enumerating Top-Level Windows ═══ An application can enumerate all top-level windows in the system by using the WinBeginEnumWindows and WinGetNextWindow functions. An application also can create a list of all child windows for a given parent window using WinBeginEnumWindows. This list contains the window handles of immediate child windows. By using WinGetNextWindow, the application then can retrieve the window handles, one at a time, from the list. When the application has finished using the list, it must release the list with the WinEndEnumWindows function. The code fragment in the following figure shows how to enumerate all top-level windows (all immediate child windows of the desktop window): Uses Os2Def,Os2Base,Os2PmApi; Var HwndTop : HWND; (* Сsken var tom!! *) Henum : HENUM; (* Сsken var tom!! *) Begin (* Enumerate all top-level windows. *) (* Loop through all enumerated windows. *) while (hwndTop := WinGetNextWindow(henum)) { . . (* Perform desired task on each window. *) . End. W ═══ 17.2.9. Moving and Sizing a Window ═══ An application can move a window by using the WinSetWindowPos function and specifying the SWP_MOVE constant. The function changes the position of the window to the specified position. The position is always given in coordinates relative to the parent window. The code fragment in the following figure moves the window to the position (10,10): Uses Os2Def,Os2Base,Os2PmApi; Var Hwnd : HWND; (* Сsken var tom!! *) Begin WinSetWindowPos( hwnd, (* Window handle *) nil, (* Not used for moving and sizing *) 10, 10, (* New position *) 0, 0, (* Not used for moving *) SWP_MOVE); (* Move window *) An application can set the size of a window by using the WinSetWindowPos function and specifying the SWP_SIZE constant. WinSetWindowPos changes the width and height of the window to the specified width and height. An application can combine moving and sizing in a single function call, as shown in the following figure. Uses Os2Def,Os2Base,Os2PmApi; Var Hwnd : HWND; (* Сsken var tom!! *) Begin WinSetWindowPos( hwnd, (* Window handle *) nil, (* Not used for moving and sizing *) 10, 10, (* New position *) 200, 200, (* Width and height *) SWP_MOVE Or SWP_SIZE); (* Move and size window. *) An application can retrieve the current size and position of a window by using the WinQueryWindowPos function. This function copies the current information to an SWP structure. The code fragment in the following figure uses the current size and position to change the height of the window, leaving the width and position unchanged. Uses Os2Def,Os2Base,Os2PmApi; Var Hwnd : HWND; (* Сsken var tom!! *) Swp : SWP; (* Сsken var tom!! *) Begin WinQueryWindowPos(hwnd, &swp); WinSetWindowPos( hwnd, (* Window handle *) nil, (* Not used for moving and sizing *) 0, 0, (* Not used for sizing *) swp.cx, (* Current width *) swp.cy + 200, (* New height *) SWP_SIZE); (* Change the size. *) An application also can move and change the size of several windows at once by using the WinSetMultWindowPos function. This function takes an array of SWP structures. Each structure specifies the window to be moved or changed. An application can move and size a window even if it is not visible, although the user is not able to see the effects of the moving and sizing until the window is visible. ═══ 17.2.10. Redrawing Windows ═══ When the system moves a window or changes its size, it can invalidate all or part of that window. The system attempts to preserve the contents of the window and copy them to the new position; however, if the window's size is increased, the window must fill the area exposed by the size change. If a window is moved from behind an overlapping window, any area formerly obscured by the other window must be drawn. In these cases, the system invalidates the exposed areas and sends a WM_PAINT message to the window. An application can require that the system invalidate an entire window every time the window moves or changes size. To do this, the application sets the CS_SIZEREDRAW class style in the corresponding window class. Typically, this class style is selected for use in an application that uses a window's current size and position to determine how to draw the window. For example, a clock application always would draw the face of the clock so that it filled the window exactly. An application also can explicitly specify which parts of the window to preserve during a move or size change. Before any change is made, the system sends a WM_CALCVALIDRECTS message to windows that do not have the style CS_SIZEREDRAW. This enables the window procedure to specify what part of the window to save and where to align it after the move or size change. ═══ 17.2.11. Changing the Z-Order of Windows ═══ An application can move a window to the top or bottom of the z-order by passing the SWP_ZORDER constant to the WinSetWindowPos function. An application specifies where to move the window by specifying the HWND_TOP or HWND_BOTTOM constants. The code fragment in the following figure uses WinSetWindowPos to change the z-order of a window. Uses Os2Def,Os2Base,Os2PmApi; Var HwndParent : HWND; (* Сsken var tom!! *) HwndNext : HWND; (* Сsken var tom!! *) Henum : HENUM; (* Сsken var tom!! *) Begin WinSetWindowPos( hwndNext, (* Next window to move *) HWND_TOP, (* Put window on top *) 0, 0, 0, 0, (* Not used for z-order *) SWP_ZORDER); (* Change z-order *) An application also can specify the window that the given window is to move behind. In this case, the application specifies the window handle instead of the HWND_TOP or HWND_BOTTOM constant. Uses Os2Def,Os2Base,Os2PmApi; Var HwndParent : HWND; (* Сsken var tom!! *) HwndNext : HWND; (* Сsken var tom!! *) HwndExchange : HWND; (* Сsken var tom!! *) Henum : HENUM; (* Сsken var tom!! *) Begin hwndExchange := WinGetNextWindow(henum); (* hwndNext has top window; hwndExchange has window under the top. *) WinSetWindowPos( hwndNext, (* Next window to move *) hwndExchange, (* Put lower window on top *) 0, 0, 0, 0, (* Not used for z-order *) SWP_ZORDER); (* Change z-order *) WinEndEnumWindows(henum); ═══ 17.2.12. Showing or Hiding a Window ═══ An application can show or hide a window by using the WinShowWindow function. This function changes the WS_VISIBLE style of a window to the specified setting. An application can also use the WinIsWindowVisible function to check the visibility of a window. This function returns TRUE if the window is visible. ═══ 17.2.13. Maximizing, Minimizing, and Restoring a Frame Window ═══ An application can maximize, minimize, or restore a frame window by using the WinSetWindowPos function and specifying the constant SWP_MAXIMIZE, SWP_MINIMIZE, or SWP_RESTORE. Only a frame window can maximize and minimize by default. For any other window, an application must provide support for these actions in the corresponding window procedure. The following figure shows how to maximize a frame window. Uses Os2Def,Os2Base,Os2PmApi; Var SwpCurrent : SWP; (* Сsken var tom!! *) HwndFrame : HWND; (* Сsken var tom!! *) Begin WinQueryWindowPos(hwndFrame, &swpCurrent); WinSetWindowPos( hwndFrame, (* Window handle *) nil, (* Not used to maximize *) swpCurrent.x, swpCurrent.y, (* Stored for restoring window *) swpCurrent.cx, swpCurrent.cy, (* Stored for restoring window *) SWP_MAXIMIZE Or SWP_SIZE Or SWP_MOVE); (* Maximize *) ═══ 17.2.14. Destroying a Window ═══ An application can destroy a window by using the WinDestroyWindow function. The following figure shows how to create and then destroy a control window: Uses Os2Def,Os2Base,Os2PmApi; Var HwndCtrl : HWND; (* Сsken var tom!! *) HwndParent : HWND; (* Сsken var tom!! *) Begin hwndCtrl := WinCreateWindow(hwndParent, WC_BUTTON, ...); WinDestroyWindow(hwndCtrl); ═══ 18. Window Classes ═══ A window class determines which styles and which window procedure are given to a window when it is created. This chapter explains how a PM application creates and uses window classes. ═══ 18.1. About Window Classes ═══ Every window is a member of a window class. An application must specify a window class when it creates a window. Each window class has an associated window procedure that is used by all windows of the same class. The window procedure handles messages for all windows of that class and, therefore, controls the behavior and appearance of the window. A window class must be registered before an application can create a window of that class. Registering a window class associates a window procedure and class styles with a class name. When an application specifies the class name in a window-creation function such as WinCreateWindow, the system creates a window that uses the window procedure and styles associated with the class name. An application can register private classes or use preregistered public window classes. ═══ 18.1.1. Private Window Classes ═══ A private window class is any class registered within an application. An application registers a private class by calling the WinRegisterClass function. A private class cannot be shared with other applications. When an application terminates, the system removes any data associated with the application's private window classes. An application can register a private class anytime but, typically, does so as part of application initialization. To register a private class during application initialization, the application also must call WinInitialize and, usually, WinCreateMsgQueue before class registration. An application cannot de-register a private window class; it remains registered and available until the application terminates. When an application registers a private window class, it must supply the following information:  Class name  Class styles  Window procedure  Window data size ═══ 18.1.1.1. Class Name ═══ The class name identifies the window class. The application uses this name in the window-creation functions to specify the class of the window being created. The class name can be a character string or an atom, and it must be unique within the application. The system checks as to whether a public class or a class already registered by the application has the same name. If the class name is not unique to that application, the system returns an error. ═══ 18.1.1.2. Class Styles ═══ Each window class has one or more values, called class styles, that tell the system which initial window styles to give a window created with that class. An application sets the class styles for a private window class when it registers the class. Once a class is registered, the application cannot change the styles. An application can specify one or more of the following class styles in the WinRegisterClass function, combining them as necessary by using the bitwise OR operator: ┌───────────────┬─────────────────────────────────────────────┐ │Style Name │Description │ ├───────────────┼─────────────────────────────────────────────┤ │CS_CLIPCHILDREN│Prevents a window from painting over its │ │ │child windows, but increases the time │ │ │necessary to calculate the visible region. │ │ │This style usually is not necessary, because │ │ │if the parent and child windows overlap and │ │ │are both invalidated, the operating system │ │ │draws the parent window before drawing the │ │ │child window. If the child window is │ │ │invalidated independently of the parent │ │ │window, the system redraws only the child │ │ │window. If the update region of the parent │ │ │window does not intersect the child window, │ │ │drawing the parent window causes the child │ │ │window to be redrawn. This style is useful to│ │ │prevent a child window containing a complex │ │ │graphic from being redrawn unnecessarily. │ ├───────────────┼─────────────────────────────────────────────┤ │CS_CLIPSIBLINGS│Prevents a window from painting over its │ │ │sibling windows. This style protects sibling │ │ │windows but increases the time necessary to │ │ │calculate the visible region. This style is │ │ │appropriate for windows that overlap and have│ │ │the same parent window. │ ├───────────────┼─────────────────────────────────────────────┤ │CS_FRAME │Identifies the window as a frame window. │ ├───────────────┼─────────────────────────────────────────────┤ │CS_HITTEST │Directs the operating system to send │ │ │WM_HITTEST messages to the window whenever │ │ │the mouse pointer moves in the window. │ ├───────────────┼─────────────────────────────────────────────┤ │CS_MOVENOTIFY │Directs the system to send WM_MOVE messages │ │ │to the window whenever the user moves the │ │ │window. │ ├───────────────┼─────────────────────────────────────────────┤ │CS_PARENTCLIP │Extends a window's visible region to include │ │ │that of its parent window. This style │ │ │simplifies the calculation of the child │ │ │window's visible region but, potentially, is │ │ │dangerous, because the parent window's │ │ │visible region is usually larger than the │ │ │child window. │ ├───────────────┼─────────────────────────────────────────────┤ │CS_SAVEBITS │Saves the screen area under a window as a bit│ │ │map. When the user hides or moves the window,│ │ │the system restores the image by copying the │ │ │bits; there is no need to add the area to the│ │ │uncovered window's update region. This style │ │ │can improve system performance, but also can │ │ │consume a great deal of memory. It is │ │ │recommended only for transient windows such │ │ │as menus and dialog windows-not for main │ │ │application windows. │ ├───────────────┼─────────────────────────────────────────────┤ │CS_SIZEREDRAW │Causes the window to receive a WM_PAINT │ │ │message and be completely invalidated │ │ │whenever the window is resized, even if it is│ │ │made smaller. (Typically, only the uncovered │ │ │area of a window is invalidated when a window│ │ │is resized.) This class style is useful when │ │ │an application scales graphics to fill the │ │ │window. │ ├───────────────┼─────────────────────────────────────────────┤ │CS_SYNCPAINT │Causes the window to receive WM_PAINT │ │ │messages immediately after a part of the │ │ │window becomes invalid. Without this style, │ │ │the window receives WM_PAINT messages only if│ │ │no other message is waiting to be processed. │ └───────────────┴─────────────────────────────────────────────┘ ═══ 18.1.1.3. Window Procedure ═══ The window procedure for a window class processes all messages sent or posted to all windows of that class. It is the chief component of the window class because it controls the appearance and behavior of each window created with the class. Window procedures are shared by all windows of a class, so an application must ensure that no conflicts arise when two windows of the same class attempt to access the same global data. In other words, the window procedure must protect global data and other shared resources. ═══ 18.1.1.4. Window Data Size ═══ The system creates a window data structure for each window, which includes extra space that an application can use to store additional data about a window. An application specifies the number of extra bytes to allocate in the WinRegisterClass function. All windows of the same class have the same amount of window data space. An application can store window data in a window's data structure by using the WinSetWindowUShort and WinSetWindowULong functions. It can retrieve data by using the WinQueryWindowUShort and WinQueryWindowULong functions. ═══ 18.1.1.5. Custom Window Styles ═══ An application that registers a window class also can support its own set of styles for windows of that class. Standard window styles-for example, WS_VISIBLE and WS_SYNCPAINT-still apply to these windows. A window style is a 32-bit integer, and only the high 16 bits are used for the standard window styles; an application can use the low 16 bits for custom styles specific to a window class. The operating system has unique window styles for all preregistered window classes. Styles such as FS_BORDER and BS_PUSHBUTTON are processed by the window procedure for the corresponding class. This means that an application can build the support for its own window styles into the window procedure for its private class. A window style designed for one window class will not work with another window class. ═══ 18.1.2. Public Window Classes ═══ Public window classes are registered during system initialization. Their window procedures are in dynamic link libraries. Therefore, to use a public window class, an application need not register it. Nor does the application need to import the window procedure for a public window class because the system resolves references to the window procedure. An application cannot use a public window class name when it registers a private window class. ═══ 18.1.2.1. System-Defined Public Window Classes ═══ The system provides a number of public window classes that support menus, frame windows, control windows, and dialog windows. An application can create a window of a system-defined public window class by specifying one of the following class name constants in a call to WinCreateWindow: ┌───────────────┬─────────────────────────────────────────────┐ │Class Name │Description │ ├───────────────┼─────────────────────────────────────────────┤ │WC_BUTTON │Consists of buttons and boxes the user can │ │ │select by clicking the pointing device or │ │ │using the keyboard. │ ├───────────────┼─────────────────────────────────────────────┤ │WC_COMBOBOX │Creates a combination-box control, which │ │ │combines a list-box control and an │ │ │entry-field control. It enables the user to │ │ │enter data either by typing in the entry │ │ │field or by choosing from the list in the │ │ │list box. │ ├───────────────┼─────────────────────────────────────────────┤ │WC_CONTAINER │Creates a control in which the user can group│ │ │objects in a logical manner. A container can│ │ │display those objects in various formats or │ │ │views. The container control supports drag │ │ │and drop so the user can place information in│ │ │a container by simply dragging and dropping. │ ├───────────────┼─────────────────────────────────────────────┤ │WC_ENTRYFIELD │Consists of a single line of text that the │ │ │user can edit. │ ├───────────────┼─────────────────────────────────────────────┤ │WC_FRAME │A composite window class that can contain │ │ │child windows of many of the other window │ │ │classes. │ ├───────────────┼─────────────────────────────────────────────┤ │WC_LISTBOX │Presents a list of text items from which the │ │ │user can make selections. │ ├───────────────┼─────────────────────────────────────────────┤ │WC_MENU │Presents a list of items that can be │ │ │displayed horizontally as menu bars, or │ │ │vertically as pull-down menus. Usually menus│ │ │are used to provide a command interface to │ │ │applications. │ ├───────────────┼─────────────────────────────────────────────┤ │WC_NOTEBOOK │Creates a control for the user that is │ │ │displayed as a number of pages. The top page│ │ │is visible, and the others are hidden, with │ │ │their presence being indicated by a visible │ │ │edge on each of the back pages. │ ├───────────────┼─────────────────────────────────────────────┤ │WC_SCROLLBAR │Consists of window scroll bars that let the │ │ │user scroll the contents of the associated │ │ │window. │ ├───────────────┼─────────────────────────────────────────────┤ │WC_SLIDER │Creates a control that is usable for │ │ │producing approximate (analog) values or │ │ │properties. Scroll bars were used for this │ │ │function in the past, but the slider provides│ │ │a more flexible method of achieving the same │ │ │result, with less programming effort. │ ├───────────────┼─────────────────────────────────────────────┤ │WC_SPINBUTTON │Creates a control that presents itself to the│ │ │user as a scrollable ring of choices, giving │ │ │the user quick access to the data. The user │ │ │is presented only one item at a time, so the │ │ │spin button should be used with data that is │ │ │intuitively related. │ ├───────────────┼─────────────────────────────────────────────┤ │WC_STATIC │Simple display items that do not respond to │ │ │keyboard or pointing device events. │ ├───────────────┼─────────────────────────────────────────────┤ │WC_TITLEBAR │Displays the window title or caption and lets│ │ │the user move the window's owner. │ ├───────────────┼─────────────────────────────────────────────┤ │WC_VALUESET │Creates a control similar in function to │ │ │radio buttons but provides additional │ │ │flexibility to display graphical, textual, │ │ │and numeric formats. The values set with │ │ │this control are mutually exclusive. │ └───────────────┴─────────────────────────────────────────────┘ Each system-defined public window class has a corresponding set of window styles that an application can use to customize a window of that class. For example, a window created with the WC_BUTTON class has styles that include BS_PUSHBUTTON and BS_CHECKBOX. Window styles enable you to customize aspects of a window's behavior and appearance. The application specifies the window styles in the WinCreateWindow function. ═══ 18.1.2.2. Custom Public Window Classes ═══ An application can create a custom public window class, but it must do so during system initialization. Only the shell can register a public window class, and it can do so only when the system starts. Registering a public window class requires a special load entry in the os2.ini file. That entry instructs the shell to load a dynamic link library whose initialization routine registers the window class. Custom public window classes must be registered using WinRegisterClass and must have the class style CS_PUBLIC. If a custom public window class registered this way has the same name as an existing public window class, the custom class replaces the original class. If a dynamic link library replaces an existing public window class, the library can save the address of the original window procedure and use the address to subclass the original window class. The dynamic link library retrieves the original window procedure address using the WinQueryClassInfo function. The custom window procedure then passes unprocessed messages to the original window procedure instead of calling WinDefWindowProc. When subclassing a public window class, the custom public window procedure must not make the window data size smaller than the original window data size, because all public window classes that the operating system defines use 4 extra bytes for storing a pointer to custom window data. This size is guaranteed only for public window classes defined by the operating system dynamic link libraries. ═══ 18.1.3. Class Data ═══ An application can examine public window class data by using the WinQueryClassInfo and WinQueryClassName functions. An application retrieves the name of the class for a given window by using the WinQueryClassName function. If the window is one of the preregistered public window classes, the name returned is in the form #nnnnn, where nnnnn is up to 5 digits, representing the value of the window class constant. Using this window class name, the application can call WinQueryClassInfo to retrieve the window class data. WinQueryClassInfo copies the class style, window procedure address, and window data size to a CLASSINFO data structure. ═══ 18.2. Using Window Classes ═══ This section explains how to perform the following tasks:  Register a private window class  Register an imported window procedure ═══ 18.2.1. Registering a Private Window Class ═══ An application can register a private window class at any time by using the WinRegisterClass function. You must define the window procedure in the application, choose a unique name, and set the window styles for the class. The following code fragment shows how to register the window class name "MyPrivateClass": Uses Os2Def,Os2Base,Os2PmApi; Var EXPENTRY : MRESULT; (* Сsken var tom!! *) Begin EXPENTRY := MRESULT Uses Os2Def,Os2Base,Os2PmApi; Var Hab : HAB; (* Сsken var tom!! *) Begin WinRegisterClass(hab, (* Anchor block handle *) "MyPrivateClass", (* Name of class being registered *) ClientWndProc, (* Window procedure for class *) CS_SIZEREDRAW Or (* Class style *) CS_HITTEST, (* Class style *) 0); (* Extra bytes to reserve *) ═══ 19. Window Procedures ═══ Windows have an associated window procedure-a function that processes all messages sent or posted to a window. Every aspect of a window's appearance and behavior depends on the window procedure's response to the messages. This chapter explains how window procedures function, in general, and describes the default window procedure. ═══ 19.1. About Window Procedures ═══ Every window belongs to a window class that determines which window procedure a particular window uses to process its messages. All windows of the same class use the same window procedure. For example, the operating system defines a window procedure for the frame window class (WC_FRAME), and all frame windows use that window procedure. An application typically defines at least one new window class and an associated window procedure. Then, the application can create many windows of that class, all of which use the same window procedure. This means that the same piece of code can be called from several sources simultaneously; therefore, you must be careful when modifying shared resources from a window procedure. Dialog procedures have the same structure and function as window procedures. The primary difference between a dialog procedure and a window procedure is the absence of a client window in the dialog procedure; that is, the controls in a dialog procedure are the immediate child windows of the frame, whereas the controls in a normal window are the grandchildren of the frame. This makes significant differences in the code between the two; for example, WinSendDlgItemMsg does not work from a client window if you pass the client window handle as the first parameter. ═══ 19.1.1. Structure of a Window Procedure ═══ A window procedure is a function that takes 4 arguments and returns a 32-bit pointer. The arguments of a window procedure consist of a window handle, a ULONG message identifier, and two arguments, called message parameters, that are declared with the MPARAM data type. The system defines an MPARAM as a 32-bit pointer to a VOID data type (a generic pointer). The message parameters actually might contain any of the standard data types. The message parameters are interpreted differently,depending on the value of the message identifier. The operating system includes several macros that enable the application to cast the information from the MPARAM values into the actual data type. SHORT1FROMMP, for example, extracts a 16-bit value from a 32-bit MPARAM. The window-procedure arguments are described in the following table: ┌───────────────┬─────────────────────────────────────────────┐ │Argument │Description │ ├───────────────┼─────────────────────────────────────────────┤ │hwnd │Handle of the window receiving the message. │ ├───────────────┼─────────────────────────────────────────────┤ │msg │Message identifier. The message will │ │ │correspond to one of the predefined constants│ │ │(for example, WM_CREATE) defined in the │ │ │system include files or be an │ │ │application-defined message identifier. The │ │ │value of an application-defined message │ │ │identifier must be greater than the value of │ │ │WM_USER, and less than or equal to 0xffff. │ ├───────────────┼─────────────────────────────────────────────┤ │mp1,mp2 │Message parameters. Their interpretation │ │ │depends on the particular message. │ └───────────────┴─────────────────────────────────────────────┘ The return value of a window procedure is defined as an MRESULT data type. The interpretation of the return value depends on the particular message. Consult the description of each message to determine the appropriate return value. ═══ 19.1.2. Default Window Procedure ═══ All windows in the system share certain fundamental behavior, defined in the default window-procedure function, WinDefWindowProc. The default window procedure provides the minimal functionality for a window. An application-defined window procedure should pass any messages it does not process to WinDefWindowProc for default processing. ═══ 19.1.3. Window-Procedure Subclassing ═══ Subclassing enables an application to intercept and process messages sent or posted to a window before that window has a chance to process them. Subclassing most often is used to add functionality to a particular window or to alter a window's default behavior. An application subclasses a window by using the WinSubclassWindow function to replace the window's original window procedure with an application-defined window procedure. Thereafter, the new window procedure processes any messages that are sent or posted to the window. If the new window procedure does not process a particular message, it must pass the message to the original window procedure, not to WinDefWindowProc, for default processing. ═══ 19.2. Using Window Procedures ═══ This section explains how to:  Design a window procedure  Associate a window procedure with a window class  Subclass a window ═══ 19.2.1. Designing a Window Procedure ═══ The following code fragment shows the structure of a typical window procedure and how to use the message argument in a switch statement, with individual messages handled by separate case statements. Notice that each case returns a specific value for each message. For messages that it does not handle itself, the window procedure calls WinDefWindowProc. Uses Os2Def,Os2Base,Os2PmApi; Var ClientWndProc( : MRESULT; (* Сsken var tom!! *) Hwnd, : HWND; (* Сsken var tom!! *) Msg, : ULONG; (* Сsken var tom!! *) Mp1, : MPARAM; (* Сsken var tom!! *) Mp2) : MPARAM; (* Сsken var tom!! *) Begin ClientWndProc( := MRESULT Hwnd, := HWND Msg, := ULONG Mp1, := MPARAM Mp2) := MPARAM { (* Define local variables here, If required. *) switch (msg) { case WM_CREATE: (* Initialize private window data. *) return (MRESULT) Ord(False); case WM_PAINT: (* Paint the window. *) return 0; case WM_DESTROY: (* Clean up private window data. *) return 0; default: break; End. return WinDefWindowProc (hwnd, msg, mp1, mp2); E A dialog window procedure does not receive the WM_CREATE message; however, it does receive a WM_INITDLG message when all of its control windows have been created. At the very least, a window procedure should handle the WM_PAINT message to draw itself. Typically, it should handle mouse and keyboard messages as well. Consult the descriptions of individual messages to determine whether your window procedure should handle them. An application can call WinDefWindowProc as part of the processing of a message. In such a case, the application can modify the message parameters before passing the message to WinDefWindowProc or can continue with the default processing after performing its own operations. ═══ 19.2.2. Associating a Window Procedure with a Window Class ═══ To associate a window procedure with a window class, an application must pass a pointer to that window procedure to the WinRegisterClass function. Once an application has registered the window procedure, the procedure automatically is associated with each new window created with that class. The following code fragment shows how to associate the window procedure in the previous example with a window class: Uses Os2Def,Os2Base,Os2PmApi; Var Hab : HAB; (* Сsken var tom!! *) SzClientClass[] : CHAR; (* Сsken var tom!! *) Begin Hab := @NOTDEFINED@ SzClientClass[] := "My WinRegisterClass(hab, (* Anchor-block handle *) szClientClass, (* Class name *) ClientWndProc, (* Pointer to procedure *) CS_SIZEREDRAW, (* Class style *) 0); (* Window data *) ═══ 19.2.3. Subclassing a Window ═══ To subclass a window, an application calls the WinSubclassWindow function, specifying the handle of the window to subclass and a pointer to the new window procedure. The WinSubclassWindow function returns a pointer to the original window procedure; the application can use this pointer to pass unprocessed messages to the original procedure. The following code fragment subclasses a push button control window. The new window procedure generates a beep whenever the user clicks the push button. Uses Os2Def,Os2Base,Os2PmApi; Var PfnPushBtn : PFNWP; (* Сsken var tom!! *) SzCancel[] : CHAR; (* Сsken var tom!! *) HwndClient : HWND; (* Сsken var tom!! *) HwndPushBtn : HWND; (* Сsken var tom!! *) Begin . . . (* Create a push button control. *) hwndPushBtn := WinCreateWindow( hwndClient, (* Parent-window handle *) WC_BUTTON, (* Window class *) szCancel, (* Window text *) WS_VISIBLE Or (* Window style *) WS_SYNCPAINT Or (* Window style *) BS_PUSHBUTTON, (* Button style *) 50, 50, (* Physical position *) 70, 30, (* Width and height *) hwndClient, (* Owner-window handle *) HWND_TOP, (* Z-order position *) 1, (* Window identIfier *) nil, (* No control data *) nil); (* No presentation parameters *) (* Subclass the push button control. *) pfnPushBtn := WinSubclassWindow(hwndPushBtn, SubclassPushBtnProc); . . . End. (* This procedure subclasses the push button. *) Uses Os2Def,Os2Base,Os2PmApi; Var EXPENTRY : MRESULT; (* Сsken var tom!! *) Begin EXPENTRY := MRESULT { switch (msg) { (* Beep when the user clicks the push button. *) case WM_BUTTON1DOWN: DosBeep(1000, 250); break; default: break; End. (* Pass all messages to the original window procedure. *) return (MRESULT) pfnPushBtn(hwnd, msg, mp1, mp2); E ═══ 20. Window Timers ═══ A window timer enables an application to post timer messages at specified intervals. This chapter describes how to use window timers in PM applications. ═══ 20.1. About Window Timers ═══ A window timer causes the system to post WM_TIMER messages to a message queue at specified time intervals called timeout values. A timeout value is expressed in milliseconds. An application starts the timer for a given window, specifying the timeout value. The system counts down approximately that number of milliseconds and posts a WM_TIMER message to the message queue for the corresponding window. The system repeats the countdown-post cycle continuously until the application stops the timer. The timeout value can be any value in the range from 0 through 4,294,967,295 (full magnitude of ULONG) for OS/2 Version 3; for previous versions, the maximum value is 65535. However, the operating system cannot guarantee that all values are accurate. The actual timeout depends on how often the application retrieves messages from the queue and the system clock rate. In many computers, the operating system clock ticks about every 50 milliseconds, but this can vary widely from computer to computer. In general, a timer message cannot be posted more frequently than every system clock tick. To make the system post a timer message as often as possible, an application can set the timeout value to 0. An application starts a timer by using the WinStartTimer function. If a window handle is given, the timer is created for that window. In such case, the WinDispatchMsg function dispatches the WM_TIMER message to the given window when the message is retrieved from the message queue. If a NULL window handle is given, it is up to the application to check the message queue for WM_TIMER messages and dispatch them to the appropriate window. A new timer starts counting down as soon as it is created. An application can reset or change a timer's timeout value in subsequent calls to the WinStartTimer function. To stop a timer, an application can use the WinStopTimer function. The system contains a limited number of timers that must be shared among all PM applications; each application should use as few timers as possible. An application can determine how many timers currently are available by checking the SV_CTIMERS system value. Every timer has a unique timer identifier. An application can request that a timer be created with a particular identifier or have the system choose a unique value. When a WM_TIMER message is received, the timer identifier is contained in the first message parameter. Timer identifiers enable an application to determine the source of the WM_TIMER message. Three timer identifiers are reserved by and for the system and cannot be used by applications; these system timer identifiers and their symbolic constants are shown in the following table: ┌───────────────┬─────────────────────────────────────────────┐ │Value │Meaning │ ├───────────────┼─────────────────────────────────────────────┤ │TID_CURSOR │Identifies the timer that controls cursor │ │ │blinking. Its timeout value is stored in the │ │ │os2.ini file under the CursorBlinkRate │ │ │keyname in the PM_ControlPanel section. │ ├───────────────┼─────────────────────────────────────────────┤ │TID_FLASHWINDOW│Identifies the window-flashing timer. │ ├───────────────┼─────────────────────────────────────────────┤ │TID_SCROLL │Identifies the scroll-bar repetition timer │ │ │that controls scroll-bar response when the │ │ │mouse button or a key is held down. Its │ │ │timeout value is specified by the system │ │ │value SV_SCROLLRATE. │ └───────────────┴─────────────────────────────────────────────┘ WM_TIMER messages, like WM_PAINT and semaphore messages, are not actually posted to a message queue. Instead, when the time elapses, the system sets a record in the queue indicating which timer message was posted. The system builds the WM_TIMER message when the application retrieves the message from the queue. Although a timer message may be in the queue, if there are any messages with higher priority in the queue, the application retrieves those messages first. If the time elapses again before the message is retrieved, the system does not create a separate record for this timer, meaning that the application should not depend on the timer messages being processed at precise intervals. To check the accuracy of the message, an application can retrieve the actual system time by using the WinGetCurrentTime function. Comparing the actual time with the time of the previous timer message is useful in determining what action to take for the timer. ═══ 20.2. Using Window Timers ═══ There are two methods of using window timers. In the first method, you start the timer by using the WinStartTimer function, supplying the window handle and timer identifier. The function associates the timer with the specified window. The following code fragment starts two timers: the first timer is set for every half second (500 milliseconds); the second, for every two seconds (2000 milliseconds). WinStartTimer(hab, (* Anchor-block handle *) hwnd, (* Window handle *) ID_TIMER1, (* Timer identIfier *) 500); (* 500 milliseconds *) WinStartTimer(hab, (* Anchor-block handle *) hwnd, (* Window handle *) ID_TIMER2, (* Timer identIfier *) 2000); (* 2000 milliseconds *) Once these timers are started, the WinDispatchMsg function dispatches WM_TIMER messages to the appropriate window. To process these messages, add a WM_TIMER case to the window procedure for the given window. By checking the first parameter of the WM_TIMER message, you can identify a particular timer, then carry out the actions related to it. The following code fragment shows how to process WM_TIMER messages: case WM_TIMER: switch (SHORT1FROMMP(mp1)) { (* Obtains timer identIfier *) case ID_TIMER1: . . (* Carry out timer-related tasks. *) . return 0; case ID_TIMER2: . . (* Carry out timer-related tasks. *) . return 0; E In the second method of using a timer, you specify NULL as the hwnd parameter of the WinStartTimer call. The system starts a timer that has no associated window and assigns an arbitrary timer identifier. The following code fragment starts two window timers using this method: Uses Os2Def,Os2Base,Os2PmApi; Var IdTimer1, : ULONG; (* Сsken var tom!! *) Begin IdTimer1, := ULONG idTimer1 := WinStartTimer(hab, (HWND) nil, 0, 500); idTimer2 := WinStartTimer(hab, (HWND) nil, 0, 2000); These timers have no associated window, so the application must check the message queue for WM_TIMER messages and dispatch them to the appropriate window procedure. The following code fragment shows a message loop that handles the window timers: Uses Os2Def,Os2Base,Os2PmApi; Var HwndTimerHandler : HWND; (* Handle of window for timer messages *) Qmsg : QMSG; (* Queue-message structure *) Begin while (WinGetMsg(hab, &qmsg, (HWND) nil, 0, 0)) { If (qmsg.msg = WM_TIMER) qmsg.hwnd := hwndTimerHandler; WinDispatchMsg(hab, &qmsg); End. You can use the WinStopTimer function at any time to stop a timer. The following code fragment demonstrates how to stop a timer: WinStopTimer(hab, hwnd, ID_TIMER1); (* Stops first timer *) ═══ 21. Appendices ═══ This section contains several topics related to Presentation Manager programming. ═══ 21.1. Bit-Map Formats ═══ There are four standard bit-map formats. All device drivers must be able to translate between any of these formats and their own internal formats. The standard formats are: Bitcount Planes 1 1 4 1 8 1 24 1 These formats are chosen because they are identical or similar to all formats commonly used by raster devices. Only single-plane formats are standard, but it is very easy to convert these to any multiple-plane format used internally by a device. ═══ 21.1.1. Bit-Map Data ═══ The pel data is stored in the bit map in the order that the coordinates appear on a display screen. That is, the pel in the lower-left corner is the first in the bit map. Pels are scanned to the right, and upward, from that position. The bits of the first pel are stored, beginning with the most significant bits of the first byte. The data for pels in each scan line is packed together tightly, but all scan lines are padded at the end, so that each one begins on a ULONG boundary. ═══ 21.1.2. Bit-Map Information Tables ═══ Each standard-format bit map must be accompanied by a bit-map information table. Because the standard-format bit maps are intended to be traded between devices, the color indexes in the bit map are meaningless without more information; for a description of this structure, see BITMAPINFO2. Some functions use a structure that is similar to BITMAPINFO2 but does not have the color table array; for a description of this structure, see BITMAPINFOHEADER2. Wherever BITMAPINFO2 is shown, BITMAPINFO is also allowed. Similarly, wherever BITMAPINFOHEADER2 is shown, BITMAPINFOHEADER is also allowed. ═══ 21.1.3. Bit-Map Example ═══ To make the ordering of all the bytes clear, consider this simple example of a 5-by-3 array of colored pels: Red Green Blue Red Green Blue Red Green Blue Red Green Blue Red Green Blue Uses Os2Def,Os2Base,Os2PmApi; Var ExampleBitmap[] : ULONG; (* Сsken var tom!! *) Begin ExampleBitmap[] := ULONG $23,$12,$30,$00 (* bottom line *) $31,$23,$10,$00 (* middle line *) $12,$31,$20,$00 (* top line *) End;; struct BitmapInfoTable ExampleInfo := { 5, (* width *) 3, (* height *) 1, (* planes *) 4, (* bitcount *) BLACK,RED,GREEN,BLUE, (* color table *) BLACK,BLACK,BLACK,BLACK, BLACK,BLACK,BLACK,BLACK, BLACK,BLACK,BLACK,BLACK E ═══ 21.1.4. Bit-Map File Format ═══ The operating system uses the same file format for bit maps, icons, and pointers in resource files. In the following description, "bit map" refers to bit maps, icons, and pointers unless otherwise specified. Two formats are supported. In the first, a single-size version of the bit map is defined. This is used whatever the target device. The second format allows multiple versions of the bit map to be defined, including one or more device-independent versions, and a number of device-dependent versions, each intended for use with a particular device. In the case of icons and pointers, when more than one version of the bit map exists, the preferred version is one that matches the device size of the icon or pointer; otherwise, the device-independent version is used to scale a bit map to the required size. The operating system provides pointers that match the requirements of the display device in use, typically pointers are 32x32 pels, one bit per plane. Icons provided with the operating system are designed to match the requirements of the most common display devices. The following versions of each icon are included in each file: 32x32 4 bpp (16 color) 40x40 4 bpp (16 color) 32x32 1 bpp (black and white) 20x20 1 bpp (black and white) 16x16 1 bpp (black and white) The 32x32 versions are designed for VGA displays and for device-independent use. The 40x40 version is for 8514/A and XGA displays. The 20x20 and 16x16 are half-size icons designed for use as mini-icons. For general bit maps, which may be of arbitrary size, the preferred version is one matching the requested bit map size; otherwise one matching the display size is selected. If neither is available, the device-independent version is used from which to scale a bit map. For both formats, the definition consists of two sections. The first section contains general information about the type, dimensions, and other attributes of the resource. The second section contains data describing the pels that make up the bit map(s), and is in the format specified in Bit-Map Data. In the multiple-version format, the first section contains an array of BITMAPARRAYFILEHEADER or BITMAPARRAYFILEHEADER2 structures. The device-independent version must be the first BITMAPARRAYFILEHEADER or BITMAPARRAYFILEHEADER2 defined. In the single-size format, the BITMAPARRAYFILEHEADER or BITMAPARRAYFILEHEADER2 structure is not present. The definition consists of one or two BITMAPFILEHEADER or BITMAPFILEHEADER2 structures. For icons and pointers, the cy field in bmp is actually twice the pel height of the image that appears on the screen. This is because these types actually contain two full bit-map pel definitions. The first bit-map definition is the XOR mask, which contains invert information (0 = no invert, 1 = invert) for the pointer or icon. The second is the AND mask, which determines whether the pointer or the screen is shown (0 = black/white, 1 = screen/inverse screen). For color icons or pointers, there are two bit-maps involved: one that is black and white and consists of an AND and an XOR mask, and one that is color that defines the color content. The cy field in the BITMAPINFOHEADER2 structure for the color bit-map must be the real height, that is, half the value specified for the black and white bit-map. The cx must be the same. The following table shows how these two bit-maps are used for a color icon or pointer: XOR AND COLOR 1 1 x Invert screen 0 0 x Use color x 0 1 x Transparency 1 0 x Use color x For color icons or pointers, two BITMAPFILEHEADER or BITMAPFILEHEADER2 structures are therefore required: BITMAPFILEHEADER2 with usType BFT_COLORICON or BFT_COLORPOINTER BITMAPINFOHEADER2 (part of BITMAPFILEHEADER2) Uses Os2Def,Os2Base,Os2PmApi; Var Table : COLOR; (* Сsken var tom!! *) Begin Table := Color BITMAPFILEHEADER2 with same usType BITMAPINFOHEADER2 (part of BITMAPFILEHEADER2) Uses Os2Def,Os2Base,Os2PmApi; Var Table : COLOR; (* Сsken var tom!! *) Begin Table := Color ** bits for one bit-map ** ** bits for other bit-map ** The usType for the first BITMAPFILEHEADER2 is either BFT_COLORICON or BFT_COLORPOINTER. This means that a second BITMAPFILEHEADER2 is present as part of the definition of a color icon or pointer. The first The first BITMAPFILEHEADER2 structure contains the information for the black and white AND and XOR masks, while the second BITMAPFILEHEADER2 structure contains the information for the color part of the pointer or icon. BITMAPFILEHEADER and BITMAPINFOHEADER can occur in place of BITMAPFILEHEADER2 and BITMAPINFOHEADER2 in this example. For the multiple version format, the file is as follows: BITMAPARRAYFILEHEADER2 for device-independent version BITMAPFILEHEADER2 (part of BITMAPARRAYFILEHEADER2) BITMAPINFOHEADER2 (part of BITMAPFILEHEADER2) Uses Os2Def,Os2Base,Os2PmApi; Var Table : COLOR; (* Сsken var tom!! *) Begin Table := Color BITMAPFILEHEADER2 ) BITMAPINFOHEADER2 ) only If this is a color icon or pointer Uses Os2Def,Os2Base,Os2PmApi; Var Table : COLOR; (* Сsken var tom!! *) Begin Table := Color BITMAPARRAYFILEHEADER2 for first device-dependent version BITMAPFILEHEADER2 (part of BITMAPARRAYFILEHEADER2) BITMAPINFOHEADER2 (part of BITMAPFILEHEADER2) Uses Os2Def,Os2Base,Os2PmApi; Var Table : COLOR; (* Сsken var tom!! *) Begin Table := Color BITMAPFILEHEADER2 ) BITMAPINFOHEADER2 ) only If this is a color icon or pointer Uses Os2Def,Os2Base,Os2PmApi; Var Table : COLOR; (* Сsken var tom!! *) Begin Table := Color Further BITMAPARRAYFILEHEADER2 groups occur here as required for additional device-dependent versions ** bits for one bit-map ** ** bits for next bit-map ** As before, BITMAPARRAYFILEHEADER, BITMAPFILEHEADER, and BITMAPINFOHEADER, can occur in place of BITMAPARRAYFILEHEADER2, BITMAPFILEHEADER2, and BITMAPINFOHEADER2 ═══ 21.2. Code Pages ═══ The initialization file contains country information relating to date, time, and numeric formats. It does not contain code-page information; this is obtained from the CONFIG.SYS file. Applications start with the default code page. The default code page is set when the operating system is installed. It can be changed subsequently either by reinstalling the operating system or by editing the COUNTRY statement in the CONFIG.SYS file. A GPI presentation space inherits the code page of the process that created it. The code page changes only when the process calls GpiSetCp See the printed version of the Presentation Manager Programming Reference for the ASCII and EBCDIC versions of the code pages. ═══ 21.2.1. Windowed PM Applications ═══ Windowed PM applications allow the code-page calls to use any of the supported ASCII code pages. These are: ┌──────────────────────┬───────────┬───────────┐ │ │Char. Set │Code Page │ ├──────────────────────┼───────────┼───────────┤ │Canadian-French │993 │863 │ ├──────────────────────┼───────────┼───────────┤ │Desktop Publishing │1146 │1004 │ ├──────────────────────┼───────────┼───────────┤ │Iceland │991 │861 │ ├──────────────────────┼───────────┼───────────┤ │Latin 1 Multilingual │980 │850 │ ├──────────────────────┼───────────┼───────────┤ │Latin 2 Multilingual │982 │852 │ ├──────────────────────┼───────────┼───────────┤ │Nordic │995 │865 │ ├──────────────────────┼───────────┼───────────┤ │Portuguese │990 │860 │ ├──────────────────────┼───────────┼───────────┤ │Turkey │987 │857 │ ├──────────────────────┼───────────┼───────────┤ │U.S. (IBM PC) │919 │437 │ └──────────────────────┴───────────┴───────────┘ Code page 1004 is compatible with Microsoft** Windows**. The following EBCDIC code pages, based on character set 697, are also available for output: ┌──────────────────────┬───────────┬───────────┐ │ │Char. Set │Code Page │ ├──────────────────────┼───────────┼───────────┤ │Austrian/German │697 │273 │ ├──────────────────────┼───────────┼───────────┤ │Belgian │697 │500 │ ├──────────────────────┼───────────┼───────────┤ │Brazil │697 │037 │ ├──────────────────────┼───────────┼───────────┤ │Czechoslovakia │959 │870 │ ├──────────────────────┼───────────┼───────────┤ │Danish/Norwegian │697 │277 │ ├──────────────────────┼───────────┼───────────┤ │Finnish/Swedish │697 │278 │ ├──────────────────────┼───────────┼───────────┤ │French │697 │297 │ ├──────────────────────┼───────────┼───────────┤ │Hungary │959 │870 │ ├──────────────────────┼───────────┼───────────┤ │Iceland │697 │871 │ ├──────────────────────┼───────────┼───────────┤ │International │697 │500 │ ├──────────────────────┼───────────┼───────────┤ │Italian │697 │280 │ ├──────────────────────┼───────────┼───────────┤ │Poland │959 │870 │ ├──────────────────────┼───────────┼───────────┤ │Portuguese │697 │037 │ ├──────────────────────┼───────────┼───────────┤ │Spanish │697 │284 │ ├──────────────────────┼───────────┼───────────┤ │Turkey │1152 │1026 │ ├──────────────────────┼───────────┼───────────┤ │U.K.-English │697 │285 │ ├──────────────────────┼───────────┼───────────┤ │U.S.-English │697 │037 │ ├──────────────────────┼───────────┼───────────┤ │Yugoslavia │959 │870 │ └──────────────────────┴───────────┴───────────┘ Note: Code pages 274 (Belgian) and 282 (Portuguese) can be used to provide access to old data. The operating system provides the following additional code-page setting and query calls for the supported ASCII and EBCDIC code pages. These calls work independently of the CONFIG.SYS file. GpiSetCp Sets the code page for GPI. GpiQueryCp Queries the code page for GPI. GpiCreateLogFont Creates fonts in a code page. WinSetCp Sets the code page for a message queue. WinQueryCp Queries the code page for a message queue. WinQueryCpList creates a list of code pages supported by the operating system. Text entered in a dialog box is supplied to the application in the code page of the queue ("queue code page"). If possible, the code page of a resource (for example, a menu or dialog box) should match the code page of the queue. In general, code page 850 is the best choice for both an application and its resources. Applications should be able to process data from a variety of sources. Because code page 850 contains most of the characters in other supported code pages, this is usually the best choice for the queue code page. ═══ 21.2.2. OS/2 Code Page Options for PM Applications ═══ ┌───Application───────────────────────────┐ ┌──────────────┐ │ │─── CONFIG.SYS │ │ ┌─DosSetProcessCp (see note 1)────────┐ │ │ contains the │ │ │ Set code page for this process │ │ │ default code │ │ │ (keyboard/display not changed). │ │ │ page set by │ │ └─────────────────────────────────────┘ │ │ CODEPAGE= │ │ │ └──────────────┘ │ ┌─WinQueryCpList (see note 2)─────────┐ │ │ │ Query list of supported code pages. │ │ │ └─────────────────────────────────────┘ │ │ │ │ ┌─WinSetCp, WinQueryCp (see note 1)───┐ │ │ │ Set or query code page for │┼──────┐ ┌─────Keyboard │ │ translating incoming messages │ │ │   │ │ │ (keystrokes). │ │ │─────│ │ └─────────────────────────────────────┘ │ │─────│ Message │ │ │─────│ queue │ ┌─GpiSetCp, GpiQueryCp (see note 2)───┐ │ └─────┘ │ │ Set or query default GPI code page. │ │ │ └─────────────────────────────────────┘ │ │ │ │ ┌─GpiCreateLogFont (see note 2)───────┐ │ │ │ Create font in a code page. │─┼─────Display │ └─────────────────────────────────────┘ │ │ │ │ ┌─WinCpTranslateChar (see note 2)─────┐ │ │ ├─WinCpTranslateString (see note 2)─── │ │ │ Convert character or string from │──────Disk │ │ one code page to another. │ │ │ └─────────────────────────────────────┘ │ │  │ │ └────────────────────┼─────LAN or host └─────────────────────────────────────────┘ Note 1: Either of the two ASCII code pages specified in CONFIG.SYS. Code page 1004 is also supported. Note 2: Any supported ASCII or EBCDIC code page as reported by WinQueryCpList. Code page 1004 is also supported. ═══ 21.2.3. OS/2 Font Support for Multiple Code Pages ═══ The operating system supports multiple code pages for text input and output. A single font resource is used to support all the code pages. This section describes the font resource format. ═══ 21.2.3.1. Font Code-Page Functions ═══ Many of the characters required by each code page are common; for example, the first 128 characters of all the ASCII code pages are identical. This set of characters is called the Universal Glyph List (UGL). A code page is simply a set of pointers into the UGL. As the characters in every font are in the same order, only one set of code-page translation tables is necessary. Note: The fonts of Microsoft Windows support only code page 1004. ═══ 21.2.3.2. Font Layout ═══ The following table lists the full character set in the order in which the characters occur in the multi-code-page font. Characters are listed in order of their universal glyph list (UGL) number; the graphic character global identifier (GCGID) and a description of each character are also given. ┌─────┬──────────┬────────────────────────────────────────┐ │UGL │GCGID │Description │ ├─────┼──────────┼────────────────────────────────────────┤ │1 │SS000000 │Smiling face │ ├─────┼──────────┼────────────────────────────────────────┤ │2 │SS010000 │Smiling face, reverse image │ ├─────┼──────────┼────────────────────────────────────────┤ │3 │SS020000 │Heart suit symbol │ ├─────┼──────────┼────────────────────────────────────────┤ │4 │SS030000 │Diamond suit symbol │ ├─────┼──────────┼────────────────────────────────────────┤ │5 │SS040000 │Club suit symbol │ ├─────┼──────────┼────────────────────────────────────────┤ │6 │SS050000 │Spade suit symbol │ ├─────┼──────────┼────────────────────────────────────────┤ │7 │SM570000 │Bullet │ ├─────┼──────────┼────────────────────────────────────────┤ │8 │SM570001 │Bullet, reverse image │ ├─────┼──────────┼────────────────────────────────────────┤ │9 │SM750000 │Open circle │ ├─────┼──────────┼────────────────────────────────────────┤ │10 │SM750002 │Open circle, reverse image │ ├─────┼──────────┼────────────────────────────────────────┤ │11 │SM280000 │Male symbol │ ├─────┼──────────┼────────────────────────────────────────┤ │12 │SM290000 │Female symbol │ ├─────┼──────────┼────────────────────────────────────────┤ │13 │SM930000 │Musical note │ ├─────┼──────────┼────────────────────────────────────────┤ │14 │SM910000 │Two musical notes │ ├─────┼──────────┼────────────────────────────────────────┤ │15 │SM690000 │Sun symbol │ ├─────┼──────────┼────────────────────────────────────────┤ │16 │SM590000 │Forward arrow indicator │ ├─────┼──────────┼────────────────────────────────────────┤ │17 │SM630000 │Back arrow indicator │ ├─────┼──────────┼────────────────────────────────────────┤ │18 │SM760000 │Up-down arrow │ ├─────┼──────────┼────────────────────────────────────────┤ │19 │SP330000 │Double exclamation point │ ├─────┼──────────┼────────────────────────────────────────┤ │20 │SM250000 │Paragraph symbol (USA) │ ├─────┼──────────┼────────────────────────────────────────┤ │21 │SM240000 │Section symbol (USA), paragraph (Europe)│ ├─────┼──────────┼────────────────────────────────────────┤ │22 │SM700000 │Solid horizontal rectangle │ ├─────┼──────────┼────────────────────────────────────────┤ │23 │SM770000 │Up-down arrow, perpendicular │ ├─────┼──────────┼────────────────────────────────────────┤ │24 │SM320000 │Up arrow │ ├─────┼──────────┼────────────────────────────────────────┤ │25 │SM330000 │Down arrow │ ├─────┼──────────┼────────────────────────────────────────┤ │26 │SM310000 │Right arrow │ ├─────┼──────────┼────────────────────────────────────────┤ │27 │SM300000 │Left arrow │ ├─────┼──────────┼────────────────────────────────────────┤ │28 │SA420000 │Right angle symbol │ ├─────┼──────────┼────────────────────────────────────────┤ │29 │SM780000 │Left-right arrow │ ├─────┼──────────┼────────────────────────────────────────┤ │30 │SM600000 │Solid triangle │ ├─────┼──────────┼────────────────────────────────────────┤ │31 │SV040000 │Solid triangle, inverted │ ├─────┼──────────┼────────────────────────────────────────┤ │32 │SP010000 │Space │ ├─────┼──────────┼────────────────────────────────────────┤ │33 │SP020000 │Exclamation point │ ├─────┼──────────┼────────────────────────────────────────┤ │34 │SP040000 │Quotation marks │ ├─────┼──────────┼────────────────────────────────────────┤ │35 │SM010000 │Number sign │ ├─────┼──────────┼────────────────────────────────────────┤ │36 │SC030000 │Dollar sign │ ├─────┼──────────┼────────────────────────────────────────┤ │37 │SM020000 │Percent sign │ ├─────┼──────────┼────────────────────────────────────────┤ │38 │SM030000 │Ampersand │ ├─────┼──────────┼────────────────────────────────────────┤ │39 │SP050000 │Apostrophe │ ├─────┼──────────┼────────────────────────────────────────┤ │40 │SP060000 │Left parenthesis │ ├─────┼──────────┼────────────────────────────────────────┤ │41 │SP070000 │Right parenthesis │ ├─────┼──────────┼────────────────────────────────────────┤ │42 │SM040000 │Asterisk │ ├─────┼──────────┼────────────────────────────────────────┤ │43 │SA010000 │Plus sign │ ├─────┼──────────┼────────────────────────────────────────┤ │44 │SP080000 │Comma │ ├─────┼──────────┼────────────────────────────────────────┤ │45 │SP100000 │Hyphen/minus sign │ ├─────┼──────────┼────────────────────────────────────────┤ │46 │SP110000 │Period/full stop │ ├─────┼──────────┼────────────────────────────────────────┤ │47 │SP120000 │Slash │ ├─────┼──────────┼────────────────────────────────────────┤ │48 │ND100000 │Zero │ ├─────┼──────────┼────────────────────────────────────────┤ │49 │ND010000 │One │ ├─────┼──────────┼────────────────────────────────────────┤ │50 │ND020000 │Two │ ├─────┼──────────┼────────────────────────────────────────┤ │51 │ND030000 │Three │ ├─────┼──────────┼────────────────────────────────────────┤ │52 │ND040000 │Four │ ├─────┼──────────┼────────────────────────────────────────┤ │53 │ND050000 │Five │ ├─────┼──────────┼────────────────────────────────────────┤ │54 │ND060000 │Six │ ├─────┼──────────┼────────────────────────────────────────┤ │55 │ND070000 │Seven │ ├─────┼──────────┼────────────────────────────────────────┤ │56 │ND080000 │Eight │ ├─────┼──────────┼────────────────────────────────────────┤ │57 │ND090000 │Nine │ ├─────┼──────────┼────────────────────────────────────────┤ │58 │SP130000 │Colon │ ├─────┼──────────┼────────────────────────────────────────┤ │59 │SP140000 │Semicolon │ ├─────┼──────────┼────────────────────────────────────────┤ │60 │SA030000 │Less than sign/greater than (arabic) │ ├─────┼──────────┼────────────────────────────────────────┤ │61 │SA040000 │Equal Sign │ ├─────┼──────────┼────────────────────────────────────────┤ │62 │SA050000 │Greater than sign/less than (arabic) │ ├─────┼──────────┼────────────────────────────────────────┤ │63 │SP150000 │Question mark │ ├─────┼──────────┼────────────────────────────────────────┤ │64 │SM050000 │At sign │ ├─────┼──────────┼────────────────────────────────────────┤ │65 │LA020000 │A capital │ ├─────┼──────────┼────────────────────────────────────────┤ │66 │LB020000 │B capital │ ├─────┼──────────┼────────────────────────────────────────┤ │67 │LC020000 │C capital │ ├─────┼──────────┼────────────────────────────────────────┤ │68 │LD020000 │D capital │ ├─────┼──────────┼────────────────────────────────────────┤ │69 │LE020000 │E capital │ ├─────┼──────────┼────────────────────────────────────────┤ │70 │LF020000 │F capital │ ├─────┼──────────┼────────────────────────────────────────┤ │71 │LG020000 │G capital │ ├─────┼──────────┼────────────────────────────────────────┤ │72 │LH020000 │H capital │ ├─────┼──────────┼────────────────────────────────────────┤ │73 │LI020000 │I capital │ ├─────┼──────────┼────────────────────────────────────────┤ │74 │LJ020000 │J capital │ ├─────┼──────────┼────────────────────────────────────────┤ │75 │LK020000 │K capital │ ├─────┼──────────┼────────────────────────────────────────┤ │76 │LL020000 │L capital │ ├─────┼──────────┼────────────────────────────────────────┤ │77 │LM020000 │M capital │ ├─────┼──────────┼────────────────────────────────────────┤ │78 │LN020000 │N capital │ ├─────┼──────────┼────────────────────────────────────────┤ │79 │LO020000 │O capital │ ├─────┼──────────┼────────────────────────────────────────┤ │80 │LP020000 │P capital │ ├─────┼──────────┼────────────────────────────────────────┤ │81 │LQ020000 │Q capital │ ├─────┼──────────┼────────────────────────────────────────┤ │82 │LR020000 │R capital │ ├─────┼──────────┼────────────────────────────────────────┤ │83 │LS020000 │S capital │ ├─────┼──────────┼────────────────────────────────────────┤ │84 │LT020000 │T capital │ ├─────┼──────────┼────────────────────────────────────────┤ │85 │LU020000 │U capital │ ├─────┼──────────┼────────────────────────────────────────┤ │86 │LV020000 │V capital │ ├─────┼──────────┼────────────────────────────────────────┤ │87 │LW020000 │W capital │ ├─────┼──────────┼────────────────────────────────────────┤ │88 │LX020000 │X capital │ ├─────┼──────────┼────────────────────────────────────────┤ │89 │LY020000 │Y capital │ ├─────┼──────────┼────────────────────────────────────────┤ │90 │LZ020000 │Z capital │ ├─────┼──────────┼────────────────────────────────────────┤ │91 │SM060000 │Left bracket │ ├─────┼──────────┼────────────────────────────────────────┤ │92 │SM070000 │Backslash │ ├─────┼──────────┼────────────────────────────────────────┤ │93 │SM080000 │Right bracket │ ├─────┼──────────┼────────────────────────────────────────┤ │94 │SD150000 │Circumflex Accent │ ├─────┼──────────┼────────────────────────────────────────┤ │95 │SP090000 │Underline, continuous underscore │ ├─────┼──────────┼────────────────────────────────────────┤ │96 │SD130000 │Grave accent │ ├─────┼──────────┼────────────────────────────────────────┤ │97 │LA010000 │a small │ ├─────┼──────────┼────────────────────────────────────────┤ │98 │LB010000 │b small │ ├─────┼──────────┼────────────────────────────────────────┤ │99 │LC010000 │c small │ ├─────┼──────────┼────────────────────────────────────────┤ │100 │LD010000 │d small │ ├─────┼──────────┼────────────────────────────────────────┤ │101 │LE010000 │e small │ ├─────┼──────────┼────────────────────────────────────────┤ │102 │LF010000 │f small │ ├─────┼──────────┼────────────────────────────────────────┤ │103 │LG010000 │g small │ ├─────┼──────────┼────────────────────────────────────────┤ │104 │LH010000 │h small │ ├─────┼──────────┼────────────────────────────────────────┤ │105 │LI010000 │i small │ ├─────┼──────────┼────────────────────────────────────────┤ │106 │LJ010000 │j small │ ├─────┼──────────┼────────────────────────────────────────┤ │107 │LK010000 │k small │ ├─────┼──────────┼────────────────────────────────────────┤ │108 │LL010000 │l small │ ├─────┼──────────┼────────────────────────────────────────┤ │109 │LM010000 │m small │ ├─────┼──────────┼────────────────────────────────────────┤ │110 │LN010000 │n small │ ├─────┼──────────┼────────────────────────────────────────┤ │111 │LO010000 │o small │ ├─────┼──────────┼────────────────────────────────────────┤ │112 │LP010000 │p small │ ├─────┼──────────┼────────────────────────────────────────┤ │113 │LQ010000 │q small │ ├─────┼──────────┼────────────────────────────────────────┤ │114 │LR010000 │r small │ ├─────┼──────────┼────────────────────────────────────────┤ │115 │LS010000 │s small │ ├─────┼──────────┼────────────────────────────────────────┤ │116 │LT010000 │t small │ ├─────┼──────────┼────────────────────────────────────────┤ │117 │LU010000 │u small │ ├─────┼──────────┼────────────────────────────────────────┤ │118 │LV010000 │v small │ ├─────┼──────────┼────────────────────────────────────────┤ │119 │LW010000 │w small │ ├─────┼──────────┼────────────────────────────────────────┤ │120 │LX010000 │x small │ ├─────┼──────────┼────────────────────────────────────────┤ │121 │LY010000 │y small │ ├─────┼──────────┼────────────────────────────────────────┤ │122 │LZ010000 │z small │ ├─────┼──────────┼────────────────────────────────────────┤ │123 │SM110000 │Left brace │ ├─────┼──────────┼────────────────────────────────────────┤ │124 │SM130000 │Vertical line, logical OR │ ├─────┼──────────┼────────────────────────────────────────┤ │125 │SM140000 │Right brace │ ├─────┼──────────┼────────────────────────────────────────┤ │126 │SD190000 │Tilde │ ├─────┼──────────┼────────────────────────────────────────┤ │127 │SM790000 │House │ ├─────┼──────────┼────────────────────────────────────────┤ │128 │LC420000 │C cedilla capital │ ├─────┼──────────┼────────────────────────────────────────┤ │129 │LU170000 │U diaeresis small │ ├─────┼──────────┼────────────────────────────────────────┤ │130 │LE110000 │E acute small │ ├─────┼──────────┼────────────────────────────────────────┤ │131 │LA150000 │A circumflex small │ ├─────┼──────────┼────────────────────────────────────────┤ │132 │LA170000 │A diaeresis small │ ├─────┼──────────┼────────────────────────────────────────┤ │133 │LA130000 │A grave small │ ├─────┼──────────┼────────────────────────────────────────┤ │134 │LA270000 │A overcircle small │ ├─────┼──────────┼────────────────────────────────────────┤ │135 │LC410000 │C cedilla small │ ├─────┼──────────┼────────────────────────────────────────┤ │136 │LE150000 │E circumflex small │ ├─────┼──────────┼────────────────────────────────────────┤ │137 │LE170000 │E diaeresis small │ ├─────┼──────────┼────────────────────────────────────────┤ │138 │LE130000 │E grave small │ ├─────┼──────────┼────────────────────────────────────────┤ │139 │LI170000 │I diaeresis small │ ├─────┼──────────┼────────────────────────────────────────┤ │140 │LI150000 │I circumflex small │ ├─────┼──────────┼────────────────────────────────────────┤ │141 │LI130000 │I grave small │ ├─────┼──────────┼────────────────────────────────────────┤ │142 │LA180000 │A diaeresis capital │ ├─────┼──────────┼────────────────────────────────────────┤ │143 │LA280000 │A overcircle capital │ ├─────┼──────────┼────────────────────────────────────────┤ │144 │LE120000 │E acute capital │ ├─────┼──────────┼────────────────────────────────────────┤ │145 │LA510000 │AE diphthong small │ ├─────┼──────────┼────────────────────────────────────────┤ │146 │LA520000 │AE diphthong capital │ ├─────┼──────────┼────────────────────────────────────────┤ │147 │LO150000 │O circumflex small │ ├─────┼──────────┼────────────────────────────────────────┤ │148 │LO170000 │O diaeresis small │ ├─────┼──────────┼────────────────────────────────────────┤ │149 │LO130000 │O grave small │ ├─────┼──────────┼────────────────────────────────────────┤ │150 │LU150000 │U circumflex small │ ├─────┼──────────┼────────────────────────────────────────┤ │151 │LU130000 │U grave small │ ├─────┼──────────┼────────────────────────────────────────┤ │152 │LY170000 │Y diaeresis small │ ├─────┼──────────┼────────────────────────────────────────┤ │153 │LO180000 │O diaeresis capital │ ├─────┼──────────┼────────────────────────────────────────┤ │154 │LU180000 │U diaeresis capital │ ├─────┼──────────┼────────────────────────────────────────┤ │155 │LO610000 │O slash small │ ├─────┼──────────┼────────────────────────────────────────┤ │156 │SC020000 │Pound sterling sign │ ├─────┼──────────┼────────────────────────────────────────┤ │157 │LO620000 │O slash capital │ ├─────┼──────────┼────────────────────────────────────────┤ │158 │SA070000 │Multiply sign │ ├─────┼──────────┼────────────────────────────────────────┤ │159 │SC070000 │Florin sign │ ├─────┼──────────┼────────────────────────────────────────┤ │160 │LA110000 │A acute small │ ├─────┼──────────┼────────────────────────────────────────┤ │161 │LI110000 │I acute small │ ├─────┼──────────┼────────────────────────────────────────┤ │162 │LO110000 │O acute small │ ├─────┼──────────┼────────────────────────────────────────┤ │163 │LU110000 │U acute small │ ├─────┼──────────┼────────────────────────────────────────┤ │164 │LN190000 │N tilde small │ ├─────┼──────────┼────────────────────────────────────────┤ │165 │LN200000 │N tilde capital │ ├─────┼──────────┼────────────────────────────────────────┤ │166 │SM210000 │Ordinal indicator, feminine │ ├─────┼──────────┼────────────────────────────────────────┤ │167 │SM200000 │Ordinal indicator, masculine │ ├─────┼──────────┼────────────────────────────────────────┤ │168 │SP160000 │Question mark, inverted │ ├─────┼──────────┼────────────────────────────────────────┤ │169 │SM530000 │Registered trademark symbol │ ├─────┼──────────┼────────────────────────────────────────┤ │170 │SM660000 │Logical NOT, end of line symbol │ ├─────┼──────────┼────────────────────────────────────────┤ │171 │NF010000 │One-half │ ├─────┼──────────┼────────────────────────────────────────┤ │172 │NF040000 │One-quarter │ ├─────┼──────────┼────────────────────────────────────────┤ │173 │SP030000 │Exclamation point, inverted │ ├─────┼──────────┼────────────────────────────────────────┤ │174 │SP170000 │Left angled quotes │ ├─────┼──────────┼────────────────────────────────────────┤ │175 │SP180000 │Right angled quotes │ ├─────┼──────────┼────────────────────────────────────────┤ │176 │SF140000 │Fill character, light │ ├─────┼──────────┼────────────────────────────────────────┤ │177 │SF150000 │Fill character, medium │ ├─────┼──────────┼────────────────────────────────────────┤ │178 │SF160000 │Fill character, heavy │ ├─────┼──────────┼────────────────────────────────────────┤ │179 │SF110000 │Center box bar vertical │ ├─────┼──────────┼────────────────────────────────────────┤ │180 │SF090000 │Right middle box side │ ├─────┼──────────┼────────────────────────────────────────┤ │181 │LA120000 │A acute capital │ ├─────┼──────────┼────────────────────────────────────────┤ │182 │LA160000 │A circumflex capital │ ├─────┼──────────┼────────────────────────────────────────┤ │183 │LA140000 │A grave capital │ ├─────┼──────────┼────────────────────────────────────────┤ │184 │SM520000 │Copyright symbol │ ├─────┼──────────┼────────────────────────────────────────┤ │185 │SF230000 │Right box side double │ ├─────┼──────────┼────────────────────────────────────────┤ │186 │SF240000 │Center box bar vertical double │ ├─────┼──────────┼────────────────────────────────────────┤ │187 │SF250000 │Upper right box corner double │ ├─────┼──────────┼────────────────────────────────────────┤ │188 │SF260000 │Lower right box corner double │ ├─────┼──────────┼────────────────────────────────────────┤ │189 │SC040000 │Cent sign │ ├─────┼──────────┼────────────────────────────────────────┤ │190 │SC050000 │Yen sign │ ├─────┼──────────┼────────────────────────────────────────┤ │191 │SF030000 │Upper right box corner │ ├─────┼──────────┼────────────────────────────────────────┤ │192 │SF020000 │Lower left box corner │ ├─────┼──────────┼────────────────────────────────────────┤ │193 │SF070000 │Middle box bottom │ ├─────┼──────────┼────────────────────────────────────────┤ │194 │SF060000 │Middle box top │ ├─────┼──────────┼────────────────────────────────────────┤ │195 │SF080000 │Left middle box side │ ├─────┼──────────┼────────────────────────────────────────┤ │196 │SF100000 │Center box bar horizontal │ ├─────┼──────────┼────────────────────────────────────────┤ │197 │SF050000 │Box intersection │ ├─────┼──────────┼────────────────────────────────────────┤ │198 │LA190000 │A tilde small │ ├─────┼──────────┼────────────────────────────────────────┤ │199 │LA200000 │A tilde capital │ ├─────┼──────────┼────────────────────────────────────────┤ │200 │SF380000 │Lower left box corner double │ ├─────┼──────────┼────────────────────────────────────────┤ │201 │SF390000 │Upper left box corner double │ ├─────┼──────────┼────────────────────────────────────────┤ │202 │SF400000 │Middle box bottom double │ ├─────┼──────────┼────────────────────────────────────────┤ │203 │SF410000 │Middle box top double │ ├─────┼──────────┼────────────────────────────────────────┤ │204 │SF420000 │Left box side double │ ├─────┼──────────┼────────────────────────────────────────┤ │205 │SF430000 │Center box bar horizontal double │ ├─────┼──────────┼────────────────────────────────────────┤ │206 │SF440000 │Box intersection double │ ├─────┼──────────┼────────────────────────────────────────┤ │207 │SC010000 │International currency symbol │ ├─────┼──────────┼────────────────────────────────────────┤ │208 │LD630000 │eth Icelandic small │ ├─────┼──────────┼────────────────────────────────────────┤ │209 │LD620000 │D stroke capital, Eth Icelandic capital │ ├─────┼──────────┼────────────────────────────────────────┤ │210 │LE160000 │E circumflex capital │ ├─────┼──────────┼────────────────────────────────────────┤ │211 │LE180000 │E diaeresis capital │ ├─────┼──────────┼────────────────────────────────────────┤ │212 │LE140000 │E grave capital │ ├─────┼──────────┼────────────────────────────────────────┤ │213 │LI610000 │I dotless small │ ├─────┼──────────┼────────────────────────────────────────┤ │214 │LI120000 │I acute capital │ ├─────┼──────────┼────────────────────────────────────────┤ │215 │LI160000 │I circumflex capital │ ├─────┼──────────┼────────────────────────────────────────┤ │216 │LI180000 │I diaeresis capital │ ├─────┼──────────┼────────────────────────────────────────┤ │217 │SF040000 │Lower right box corner │ ├─────┼──────────┼────────────────────────────────────────┤ │218 │SF010000 │Upper left box corner │ ├─────┼──────────┼────────────────────────────────────────┤ │219 │SF610000 │Solid fill character │ ├─────┼──────────┼────────────────────────────────────────┤ │220 │SF570000 │Solid fill character, bottom half │ ├─────┼──────────┼────────────────────────────────────────┤ │221 │SM650000 │Vertical line, broken │ ├─────┼──────────┼────────────────────────────────────────┤ │222 │LI140000 │I grave capital │ ├─────┼──────────┼────────────────────────────────────────┤ │223 │SF600000 │Solid fill character, top half │ ├─────┼──────────┼────────────────────────────────────────┤ │224 │LO120000 │O acute capital │ ├─────┼──────────┼────────────────────────────────────────┤ │225 │LS610000 │Sharp s small │ ├─────┼──────────┼────────────────────────────────────────┤ │226 │LO160000 │O circumflex capital │ ├─────┼──────────┼────────────────────────────────────────┤ │227 │LO140000 │O grave capital │ ├─────┼──────────┼────────────────────────────────────────┤ │228 │LO190000 │O tilde small │ ├─────┼──────────┼────────────────────────────────────────┤ │229 │LO200000 │O tilde capital │ ├─────┼──────────┼────────────────────────────────────────┤ │230 │SM170000 │Micro symbol │ ├─────┼──────────┼────────────────────────────────────────┤ │231 │LT630000 │Thorn Icelandic small │ ├─────┼──────────┼────────────────────────────────────────┤ │232 │LT640000 │Thorn Icelandic capital │ ├─────┼──────────┼────────────────────────────────────────┤ │233 │LU120000 │U acute capital │ ├─────┼──────────┼────────────────────────────────────────┤ │234 │LU160000 │U circumflex capital │ ├─────┼──────────┼────────────────────────────────────────┤ │235 │LU140000 │U grave capital │ ├─────┼──────────┼────────────────────────────────────────┤ │236 │LY110000 │y acute small │ ├─────┼──────────┼────────────────────────────────────────┤ │237 │LY120000 │Y acute capital │ ├─────┼──────────┼────────────────────────────────────────┤ │238 │SM150000 │Overline │ ├─────┼──────────┼────────────────────────────────────────┤ │239 │SD110000 │Acute accent │ ├─────┼──────────┼────────────────────────────────────────┤ │240 │SP320000 │Syllable hyphen │ ├─────┼──────────┼────────────────────────────────────────┤ │241 │SA020000 │Plus or minus sign │ ├─────┼──────────┼────────────────────────────────────────┤ │242 │SM100000 │Double underscore │ ├─────┼──────────┼────────────────────────────────────────┤ │243 │NF050000 │Three-quarters │ ├─────┼──────────┼────────────────────────────────────────┤ │244 │SM250000 │Paragraph symbol (USA) │ ├─────┼──────────┼────────────────────────────────────────┤ │245 │SM240000 │Section symbol (USA), paragraph (Europe)│ ├─────┼──────────┼────────────────────────────────────────┤ │246 │SA060000 │Divide sign │ ├─────┼──────────┼────────────────────────────────────────┤ │247 │SD410000 │Cedilla (or sedila) accent │ ├─────┼──────────┼────────────────────────────────────────┤ │248 │SM190000 │Degree symbol │ ├─────┼──────────┼────────────────────────────────────────┤ │249 │SD170000 │Diaeresis, umlaut accent │ ├─────┼──────────┼────────────────────────────────────────┤ │250 │SD630000 │Middle dot │ ├─────┼──────────┼────────────────────────────────────────┤ │251 │ND011000 │One superscript │ ├─────┼──────────┼────────────────────────────────────────┤ │252 │ND031000 │Three superscript │ ├─────┼──────────┼────────────────────────────────────────┤ │253 │ND021000 │Two superscript │ ├─────┼──────────┼────────────────────────────────────────┤ │254 │SM470000 │Solid square, histogram, square bullet │ ├─────┼──────────┼────────────────────────────────────────┤ │255 │SP300000 │Required space │ ├─────┼──────────┼────────────────────────────────────────┤ │256 │SC060000 │Peseta sign │ ├─────┼──────────┼────────────────────────────────────────┤ │257 │SM680000 │Start of line symbol │ ├─────┼──────────┼────────────────────────────────────────┤ │258 │SF190000 │Right box side double to single │ ├─────┼──────────┼────────────────────────────────────────┤ │259 │SF200000 │Right box side single to double │ ├─────┼──────────┼────────────────────────────────────────┤ │260 │SF210000 │Upper right box corner single to double │ ├─────┼──────────┼────────────────────────────────────────┤ │261 │SF220000 │Upper right box corner double to single │ ├─────┼──────────┼────────────────────────────────────────┤ │262 │SF270000 │Lower right box corner single to double │ ├─────┼──────────┼────────────────────────────────────────┤ │263 │SF280000 │Lower right box corner double to single │ ├─────┼──────────┼────────────────────────────────────────┤ │264 │SF360000 │Left box side single to double │ ├─────┼──────────┼────────────────────────────────────────┤ │265 │SF370000 │Left box side double to single │ ├─────┼──────────┼────────────────────────────────────────┤ │266 │SF450000 │Middle box bottom single to double │ ├─────┼──────────┼────────────────────────────────────────┤ │267 │SF460000 │Middle box bottom double to single │ ├─────┼──────────┼────────────────────────────────────────┤ │268 │SF470000 │Middle box top double to single │ ├─────┼──────────┼────────────────────────────────────────┤ │269 │SF480000 │Middle box top single to double │ ├─────┼──────────┼────────────────────────────────────────┤ │270 │SF490000 │Lower left box corner double to single │ ├─────┼──────────┼────────────────────────────────────────┤ │271 │SF500000 │Lower left box corner single to double │ ├─────┼──────────┼────────────────────────────────────────┤ │272 │SF510000 │Upper left box corner single to double │ ├─────┼──────────┼────────────────────────────────────────┤ │273 │SF520000 │Upper left box corner double to single │ ├─────┼──────────┼────────────────────────────────────────┤ │274 │SF530000 │Box intersection single to double │ ├─────┼──────────┼────────────────────────────────────────┤ │275 │SF540000 │Box intersection double to single │ ├─────┼──────────┼────────────────────────────────────────┤ │276 │SF580000 │Solid fill character, left half │ ├─────┼──────────┼────────────────────────────────────────┤ │277 │SF590000 │Solid fill character, right half │ ├─────┼──────────┼────────────────────────────────────────┤ │278 │GA010000 │Alpha small │ ├─────┼──────────┼────────────────────────────────────────┤ │279 │GG020000 │Gamma capital │ ├─────┼──────────┼────────────────────────────────────────┤ │280 │GP010000 │Pi small │ ├─────┼──────────┼────────────────────────────────────────┤ │281 │GS020000 │Sigma capital │ ├─────┼──────────┼────────────────────────────────────────┤ │282 │GS010000 │Sigma small │ ├─────┼──────────┼────────────────────────────────────────┤ │283 │GT010000 │Tau small │ ├─────┼──────────┼────────────────────────────────────────┤ │284 │GF020000 │Phi capital │ ├─────┼──────────┼────────────────────────────────────────┤ │285 │GT620000 │Theta capital │ ├─────┼──────────┼────────────────────────────────────────┤ │286 │GO320000 │Omega capital │ ├─────┼──────────┼────────────────────────────────────────┤ │287 │GD010000 │Delta small │ ├─────┼──────────┼────────────────────────────────────────┤ │288 │SA450000 │Infinity symbol │ ├─────┼──────────┼────────────────────────────────────────┤ │289 │GF010000 │Phi small │ ├─────┼──────────┼────────────────────────────────────────┤ │290 │GE010000 │Epsilon small │ ├─────┼──────────┼────────────────────────────────────────┤ │291 │SA380000 │Intersection, logical product │ ├─────┼──────────┼────────────────────────────────────────┤ │292 │SA480000 │Indentity symbol, almost equal │ ├─────┼──────────┼────────────────────────────────────────┤ │293 │SA530000 │Greater than or equal sign │ ├─────┼──────────┼────────────────────────────────────────┤ │294 │SA520000 │Less than or equal sign │ ├─────┼──────────┼────────────────────────────────────────┤ │295 │SS260000 │Upper integral symbol section │ ├─────┼──────────┼────────────────────────────────────────┤ │296 │SS270000 │Lower integral symbol section │ ├─────┼──────────┼────────────────────────────────────────┤ │297 │SA700000 │Nearly equals symbol │ ├─────┼──────────┼────────────────────────────────────────┤ │298 │SA790000 │Product dot │ ├─────┼──────────┼────────────────────────────────────────┤ │299 │SA800000 │Radical symbol │ ├─────┼──────────┼────────────────────────────────────────┤ │300 │LN011000 │N small superscript │ ├─────┼──────────┼────────────────────────────────────────┤ │301 │SD310000 │Macron accent │ ├─────┼──────────┼────────────────────────────────────────┤ │302 │SD230000 │Breve accent │ ├─────┼──────────┼────────────────────────────────────────┤ │303 │SD290000 │Overdot accent (over small Alpha) │ ├─────┼──────────┼────────────────────────────────────────┤ │304 │SD270000 │Overcircle accent │ ├─────┼──────────┼────────────────────────────────────────┤ │305 │SD250000 │Double acute accent │ ├─────┼──────────┼────────────────────────────────────────┤ │306 │SD430000 │Ogonek accent │ ├─────┼──────────┼────────────────────────────────────────┤ │307 │SD210000 │Caron accent │ ├─────┼──────────┼────────────────────────────────────────┤ │308 │SP190000 │Left single quote │ ├─────┼──────────┼────────────────────────────────────────┤ │309 │SP200000 │Right single quote │ ├─────┼──────────┼────────────────────────────────────────┤ │310 │SP210000 │Left double quotes │ ├─────┼──────────┼────────────────────────────────────────┤ │311 │SP220000 │Right double quotes │ ├─────┼──────────┼────────────────────────────────────────┤ │312 │SS680000 │Endash │ ├─────┼──────────┼────────────────────────────────────────┤ │313 │SM900000 │Emdash │ ├─────┼──────────┼────────────────────────────────────────┤ │314 │SD150000 │Circumflex accent │ ├─────┼──────────┼────────────────────────────────────────┤ │315 │SD190000 │Tilde accent │ ├─────┼──────────┼────────────────────────────────────────┤ │316 │SP260000 │Single quote on baseline (German lower) │ ├─────┼──────────┼────────────────────────────────────────┤ │317 │SP230000 │Left lower double quotes │ ├─────┼──────────┼────────────────────────────────────────┤ │318 │SV520000 │Ellipsis │ ├─────┼──────────┼────────────────────────────────────────┤ │319 │SM340000 │Dagger footnote indicator │ ├─────┼──────────┼────────────────────────────────────────┤ │320 │SM350000 │Double dagger footnote indicator │ ├─────┼──────────┼────────────────────────────────────────┤ │321 │SD150100 │Circumflex accent (over small alpha) │ ├─────┼──────────┼────────────────────────────────────────┤ │322 │SM560000 │Permille symbol │ ├─────┼──────────┼────────────────────────────────────────┤ │323 │LS220000 │S caron capital │ ├─────┼──────────┼────────────────────────────────────────┤ │324 │SP270000 │French single open quote │ ├─────┼──────────┼────────────────────────────────────────┤ │325 │LO520000 │OE ligature capital │ ├─────┼──────────┼────────────────────────────────────────┤ │326 │SD190100 │Tilde accent (over small alpha) │ ├─────┼──────────┼────────────────────────────────────────┤ │327 │SM540000 │Trademark symbol │ ├─────┼──────────┼────────────────────────────────────────┤ │328 │LS210000 │s caron small │ ├─────┼──────────┼────────────────────────────────────────┤ │329 │SP280000 │French single close quote │ ├─────┼──────────┼────────────────────────────────────────┤ │330 │LO510000 │oe ligature small │ ├─────┼──────────┼────────────────────────────────────────┤ │331 │LY180000 │Y diaeresis capital │ ├─────┼──────────┼────────────────────────────────────────┤ │332 │LG230000 │g Breve Small │ ├─────┼──────────┼────────────────────────────────────────┤ │333 │LG240000 │G Breve Capital │ ├─────┼──────────┼────────────────────────────────────────┤ ├─────┼──────────┼────────────────────────────────────────┤ │334 │LI300000 │I Overdot Capital │ ├─────┼──────────┼────────────────────────────────────────┤ │335 │LS410000 │s Cedilla Small │ ├─────┼──────────┼────────────────────────────────────────┤ │336 │LS420000 │S Cedilla Capital │ ├─────┼──────────┼────────────────────────────────────────┤ │337 │LA230000 │a Breve Small │ ├─────┼──────────┼────────────────────────────────────────┤ │338 │LA240000 │A Breve Capital │ ├─────┼──────────┼────────────────────────────────────────┤ │339 │LA430000 │a Ogonek Small │ ├─────┼──────────┼────────────────────────────────────────┤ │340 │LA440000 │A Ogonek Capital │ ├─────┼──────────┼────────────────────────────────────────┤ │341 │LC110000 │c Acute Small │ ├─────┼──────────┼────────────────────────────────────────┤ │342 │LC120000 │C Acute Capital │ ├─────┼──────────┼────────────────────────────────────────┤ │343 │LC210000 │c Caron Small │ ├─────┼──────────┼────────────────────────────────────────┤ │344 │LC220000 │C Caron Capital │ ├─────┼──────────┼────────────────────────────────────────┤ │345 │LD210000 │d Caron Small │ ├─────┼──────────┼────────────────────────────────────────┤ │346 │LD220000 │D Caron Capital │ ├─────┼──────────┼────────────────────────────────────────┤ │347 │LD610000 │d Stroke Small │ ├─────┼──────────┼────────────────────────────────────────┤ │348 │LE210000 │e Caron Small │ ├─────┼──────────┼────────────────────────────────────────┤ │349 │LE220000 │E Caron Capital │ ├─────┼──────────┼────────────────────────────────────────┤ │350 │LE430000 │e Ogenek Small │ ├─────┼──────────┼────────────────────────────────────────┤ │351 │LE440000 │E Ogonek Capital │ ├─────┼──────────┼────────────────────────────────────────┤ │352 │LL110000 │l Acute Small │ ├─────┼──────────┼────────────────────────────────────────┤ │353 │LL120000 │L Acute Capital │ ├─────┼──────────┼────────────────────────────────────────┤ │354 │LL210000 │l Caron Small │ ├─────┼──────────┼────────────────────────────────────────┤ │355 │LL220000 │L Caron Capital │ ├─────┼──────────┼────────────────────────────────────────┤ │356 │LL610000 │l Stroke Small │ ├─────┼──────────┼────────────────────────────────────────┤ │357 │LL620000 │L Stroke Capital │ ├─────┼──────────┼────────────────────────────────────────┤ │358 │LN110000 │n Acute Small │ ├─────┼──────────┼────────────────────────────────────────┤ │359 │LN120000 │N Acute Capital │ ├─────┼──────────┼────────────────────────────────────────┤ │360 │LN210000 │n Caron Small │ ├─────┼──────────┼────────────────────────────────────────┤ │361 │LN220000 │N Caron Capital │ ├─────┼──────────┼────────────────────────────────────────┤ │362 │LO250000 │o Double Acute Small │ ├─────┼──────────┼────────────────────────────────────────┤ │363 │LO260000 │O Double Acute Capital │ ├─────┼──────────┼────────────────────────────────────────┤ │364 │LR110000 │r Acute Small │ ├─────┼──────────┼────────────────────────────────────────┤ │365 │LR120000 │R Acute Capital │ ├─────┼──────────┼────────────────────────────────────────┤ │366 │LR210000 │r Caron Small │ ├─────┼──────────┼────────────────────────────────────────┤ │367 │LR220000 │R Caron Capital │ ├─────┼──────────┼────────────────────────────────────────┤ │368 │LS110000 │s Acute Small │ ├─────┼──────────┼────────────────────────────────────────┤ │369 │LS120000 │S Acute Capital │ ├─────┼──────────┼────────────────────────────────────────┤ │370 │LT210000 │t Caron Small │ ├─────┼──────────┼────────────────────────────────────────┤ │371 │LT220000 │T Caron Capital │ ├─────┼──────────┼────────────────────────────────────────┤ │372 │LT410000 │t Cedilla Small │ ├─────┼──────────┼────────────────────────────────────────┤ │373 │LT420000 │T Cedilla Capital │ ├─────┼──────────┼────────────────────────────────────────┤ │374 │LU250000 │u Double Acute Small │ ├─────┼──────────┼────────────────────────────────────────┤ │375 │LU260000 │U Double Acute Capital │ ├─────┼──────────┼────────────────────────────────────────┤ │376 │LU270000 │u Overcircle Small │ ├─────┼──────────┼────────────────────────────────────────┤ │377 │LU280000 │u Overcircle Capital │ ├─────┼──────────┼────────────────────────────────────────┤ │378 │LZ110000 │z Acute Small │ ├─────┼──────────┼────────────────────────────────────────┤ │379 │LZ120000 │Z Acute Capital │ ├─────┼──────────┼────────────────────────────────────────┤ │380 │LZ210000 │z Caron Small │ ├─────┼──────────┼────────────────────────────────────────┤ │381 │LZ220000 │Z Caron Capital │ ├─────┼──────────┼────────────────────────────────────────┤ │382 │LZ290000 │z Overdot Small │ ├─────┼──────────┼────────────────────────────────────────┤ │383 │LZ300000 │Z Overdot Capital │ └─────┴──────────┴────────────────────────────────────────┘ ═══ 21.3. Fonts Supplied with the OS/2 Operating System ═══ OS/2 outline fonts and Presentation Manager bit map fonts are supplied by the operating system. OS/2 Outline Fonts The following Adobe Type 1 fonts are supplied with OS/2: ┌──────────────────────────────┬──────────────────────────────┐ │Family Name │Face Name │ ├──────────────────────────────┼──────────────────────────────┤ │Times New Roman │Times New Roman │ │ │Times New Roman Bold │ │ │Times New Roman Bold Italic │ │ │Times New Roman Italic │ ├──────────────────────────────┼──────────────────────────────┤ │Helvetica │Helvetica │ │ │Helvetica Bold │ │ │Helvetica Bold Italic │ │ │Helvetica Italic │ ├──────────────────────────────┼──────────────────────────────┤ │Courier │Courier │ │ │Courier Bold │ │ │Courier Bold Italic │ │ │Courier Italic │ ├──────────────────────────────┼──────────────────────────────┤ │Symbol │Symbol │ └──────────────────────────────┴──────────────────────────────┘ The Courier, Tms Rmn, and Swiss family fonts that were supplied with OS/2 release 1.1 and 1.2 are no longer supplied. Using one of the old names results in one of the new fonts listed above being used, as follows: Old Family/Face Name Font Used. Roman/Tms Rmn Times New Roman Swiss/Helv Helvetica These fonts are provided in an efficient binary format for use by the OS/2 Adobe Type Manager. They are also provided in standard Type 1 format (PFB and AFM) for use with the OS/2 PostScript printer device driver. Presentation Manager Bit Map Fonts The following tables list all system bit map fonts available using the Graphics Programming Interface. The first table applies to hardware that does not conform to the International Standards Organization (ISO) 9241. (See International Standards Organization (ISO) 9241 for more information on ISO 9241.) The second table lists the fonts supplied with OS/2 for IBM hardware that does conform to ISO 9241. During system installation, the operating system determines the type of display adapter available on your computer and installs only the fonts which match the device resolution. Since additional device bit map fonts may be available on specific devices, you may have to install the correct bit map fonts if you change your display device after the operating system is installed. Fonts Supplied for ISO 9241 Non-Conforming Hardware The following information for each font is included in the table: Points This is the point size of the font, on a device whose resolution matches that of the font, (see "Device" below). Ave Wid This is the average width in pels of alphabetic characters weighted according to US English letter frequencies. Max Wid This is the maximum width in pels of all characters in the font. This field is not necessarily the maximum width of any character in the code page. It could be used to ensure that the horizontal space allocated on a display or printer is big enough to handle any character. Height This is the height in pels of the font. This is the minimum number of rows of pels needed to output any character of the font on a given baseline. This field may be larger than necessary for a given code page. It could be used to ensure that the vertical space allocated on a display or printer is big enough to handle any character. Device This is the X and Y resolution in pels per inch at which the font is intended to be used. Only those fonts which match the device resolution of the installed display driver are available on the system. If the installed display is changed, the install process will reinstall the proper font sets for the new adapter. The IBM devices whose device drivers report these resolutions are: 96 x 48 CGA 96 x 72 EGA 96 x 96 VGA and XGA (in 640 x 480 mode) 120 x 120 8514/A and XGA (in 1024 x 768 mode) Note: These values are approximate representations of the actual resolution, which in the case of displays depends on which monitor is attached. Consequently the point size of characters on the screen is also approximate. The following table applies to hardware that does not conform to ISO 9241. ┌───────┬───────────────┬───────┬───────┬───────┬──────┬───────┐ │Family │Face Name │Points │Ave Wid│Max Wid│Height│Device │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │Courier│Courier │8 │8 │8 │7 │96x48 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │8 │8 │10 │96x72 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │8 │8 │13 │96x96 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │9 │9 │16 │120x120│ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │10 │9 │9 │8 │96x48 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │9 │9 │12 │96x72 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │9 │9 │16 │96x96 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │12 │12 │20 │120x120│ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │12 │12 │12 │10 │96x48 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │12 │12 │15 │96x72 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │12 │12 │20 │96x96 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │15 │15 │25 │120x120│ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │System │System │8 │6 │20 │8 │96x48 │ │Proport│Proportional │ │ │ │ │ │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │10 │6 │20 │12 │96x96 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │10 │6 │20 │16 │96x96 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │10 │8 │23 │20 │120x120│ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │11 │10 │23 │23 │120x120│ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │System │System │8 │8 │8 │8 │96x48 │ │Mono- │Monospaced │ │ │ │ │ │ │spaced │ │ │ │ │ │ │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │10 │8 │8 │12 │96x72 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │10 │8 │8 │16 │96x96 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │10 │9 │9 │20 │120x120│ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │Helv │Helv │8 │5 │13 │6 │96x48 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │5 │13 │10 │96x72 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │5 │13 │13 │96x96 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │6 │14 │16 │120x120│ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │10 │6 │15 │8 │96x48 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │6 │14 │12 │96x72 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │6 │14 │16 │96x96 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │7 │20 │20 │120x120│ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │12 │7 │17 │10 │96x48 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │7 │17 │15 │96x72 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │7 │17 │20 │96x96 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │9 │21 │25 │120x120│ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │14 │8 │21 │12 │96x48 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │8 │21 │18 │96x72 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │8 │21 │24 │96x96 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │11 │26 │29 │120x120│ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │18 │11 │26 │15 │96x48 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │10 │26 │22 │96x72 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │11 │26 │29 │96x96 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │13 │34 │36 │120x120│ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │24 │14 │35 │19 │96x48 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │14 │35 │28 │96x72 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │14 │35 │37 │96x96 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │18 │45 │46 │120x120│ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │Tms Rmn│Tms Rmn │8 │4 │12 │6 │96x48 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │4 │13 │10 │96x72 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │4 │12 │13 │96x96 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │5 │14 │16 │120x120│ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │10 │6 │15 │8 │96x48 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │5 │14 │12 │96x72 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │5 │14 │16 │96x96 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │7 │19 │20 │120x120│ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │12 │7 │18 │10 │96x48 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │6 │18 │15 │96x72 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │6 │16 │19 │96x96 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │8 │23 │23 │120x120│ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │14 │7 │21 │11 │96x48 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │7 │21 │16 │96x72 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │7 │20 │21 │96x96 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │10 │26 │27 │120x120│ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │18 │10 │26 │14 │96x48 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │10 │26 │20 │96x72 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │10 │26 │27 │96x96 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │12 │34 │33 │120x120│ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │24 │14 │35 │18 │96x48 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │13 │35 │26 │96x72 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │13 │35 │35 │96x96 │ ├───────┼───────────────┼───────┼───────┼───────┼──────┼───────┤ │ │ │ │16 │46 │43 │120x120│ └───────┴───────────────┴───────┴───────┴───────┴──────┴───────┘ Fonts Supplied for ISO 9241 Conforming Hardware The following table lists the fonts and sizes that have been tested and certified as passing the ISO 9241 black text on white background criteria for the three IBM displays that conform to the standard. These displays are:  9515 - A 14 inch XGA display.  9517 - A 17 inch XGA display.  9518 - A 14 inch VGA display. See International Standards Organization (ISO) 9241 for information on ISO 9241. The following information about each font is also included in the table: P The point size of the font. AW The average character width in pels in the font. MW The maximum character width in pels in the font. HE The height in pels of the font (maximum baseline extent). Device The X and Y resolution in pels per inch on the device the font is intended to be used. The IBM devices whose device drivers report these resolutions are: 96 x 96 VGA and XGA (in 640 x 480 mode) 120 x 120 XGA (in 1024 x 768 mode) ┌────────┬────────┬────────────────┬─────────┬─────────────────┐ │Family │Face Nam│P AW MW HE │Device │9515 9517 9518 │ │Name │ │ │ │ │ │ │Face Nam│ │ │ │ ├────────┼────────┼────────────────┼─────────┼─────────────────┤ │Courier │Courier │ 8 8 8 13 │ 96 96 │No No No │ │ │ISO │ 8 10 10 16 │120 120 │No No n/a │ │ │ │ 9 8 8 15 │ 96 96 │Yes Yes Yes │ │ │ │10 10 10 16 │ 96 96 │Yes Yes Yes │ │ │ │10 12 12 20 │120 120 │No No n/a │ │ │ │12 12 12 20 │ 96 96 │Yes Yes Yes │ │ │ │12 15 15 25 │120 120 │Yes Yes n/a │ ├────────┼────────┼────────────────┼─────────┼─────────────────┤ │Helv │Helv ISO│ 8 5 13 13 │ 96 96 │No No No │ │ │ │ 8 7 14 16 │120 120 │No No n/a │ │ │ │ 9 6 13 15 │ 96 96 │Yes Yes Yes │ │ │ │ 9 8 20 21 │120 120 │Yes Yes n/a │ │ │ │10 7 14 16 │ 96 96 │Yes Yes Yes │ │ │ │10 9 20 21 │120 120 │Yes Yes n/a │ │ │ │12 9 17 20 │ 96 96 │Yes Yes Yes │ │ │ │12 10 21 25 │120 120 │Yes Yes n/a │ │ │ │14 10 21 24 │ 96 96 │Yes Yes Yes │ │ │ │14 12 26 29 │120 120 │Yes Yes n/a │ │ │ │18 12 26 29 │ 96 96 │Yes Yes Yes │ │ │ │18 15 34 36 │120 120 │Yes Yes n/a │ │ │ │24 14 34 36 │ 96 96 │Yes Yes Yes │ │ │ │24 19 45 46 │120 120 │Yes Yes n/a │ ├────────┼────────┼────────────────┼─────────┼─────────────────┤ │Tms Rmn │Tms Rmn │ 8 5 12 13 │ 96 96 │No No No │ │ │ISO │ 8 7 15 16 │120 120 │No No n/a │ │ │ │ 9 6 12 15 │ 96 96 │Yes Yes Yes │ │ │ │10 7 14 16 │ 96 96 │Yes Yes Yes │ │ │ │10 8 17 19 │120 120 │No Yes n/a │ │ │ │12 8 16 19 │ 96 96 │Yes Yes Yes │ │ │ │12 10 23 22 │120 120 │Yes Yes n/a │ │ │ │14 9 23 22 │ 96 96 │Yes Yes Yes │ │ │ │14 11 26 27 │120 120 │Yes Yes n/a │ │ │ │18 11 26 27 │ 96 96 │Yes Yes Yes │ │ │ │18 14 34 34 │120 120 │Yes Yes n/a │ │ │ │24 14 34 34 │ 96 96 │Yes Yes Yes │ │ │ │24 17 46 43 │120 120 │Yes Yes n/a │ ├────────┼────────┼────────────────┼─────────┼─────────────────┤ │System │System │ 9 6 13 15 │ 96 96 │Yes Yes Yes │ │Propor- │Propor- │10 6 20 16 │ 96 96 │Yes Yes Yes │ │tional │tional │10 8 23 20 │120 120 │No Yes n/a │ │ │ │12 10 23 22 │120 120 │Yes Yes n/a │ ├────────┼────────┼────────────────┼─────────┼─────────────────┤ │System │System │10 8 8 16 │ 96 96 │Yes Yes Yes │ │Mono- │Mono- │10 10 10 21 │120 120 │Yes Yes n/a │ │spaced │spaced │ │ │ │ └────────┴────────┴────────────────┴─────────┴─────────────────┘ See International Standards Organization (ISO) 9241 for more information on ISO 9241. ═══ 21.3.1. International Standards Organization (ISO) 9241 ═══ ISO 9241 is an international standard covering health and safety in the work place for users of visual display terminals. Part 3 of this standard covers clarity and legibility of text displayed on computer screens; it places requirements on minimum sizes and luminance contrast. The presence of the FM_SEL_ISO9241_TESTED flag in the FONTMETRICS structure indicates that the font has been tested for ISO compliance. Note: While the fonts were primarily tested for meeting the ISO standard, they have also been designed to meet the German standard DIN 66 234. Where the two standards differ, the fonts have been designed to meet the stricter requirement. The FM_ISO_xxx flags indicate the results of the test on the three IBM displays that conform to the standard. These are the IBM 9515, 9517, and 9518 color displays at the supported resolutions of 640 x 480 and 1024 x 768. To determine whether a non-IBM display complies with ISO 9241, contact the manufacturer. The current display type can be established using VioGetConfig. In order for applications to meet the standard, they have to ensure that they use only fonts that have been tested and passed. You can determine this by examining the new FM_SEL_ISO9241_TESTED flag in the fsSelection parameter in the FONTMETRICS structure, the FM_ISO_xxx flags and the sXDeviceRes and sYDeviceRes fields in the structure. See Fonts Supplied with the OS/2 Operating System for the table describing ISO 9241 compliant fonts. ═══ 21.4. Initialization File Information ═══ Initialization files include information about printers, queues, and system preferences set by the user from the control panel. Applications can query this information by using the PrfQueryProfileData, PrfQueryProfileInt, PrfQueryProfileSize, and PrfQueryProfileString functions. All data in initialization files is accessed by a two-level hierarchy of application name, and key name within an application. Presentation Manager system data is keyed off "applications" that have names starting with PM_. The application name/key name combinations that applications may need to use are listed below, together with the definition of the corresponding data. Note: Information that is prefixed with PM_SPOOLERxxxx can not always be modified directly: The spooler validates all attempts to write information to the INI file that it depends on. Application name "PM_ControlPanel" Key name "Beep" Type integer Content/value 1 or 0. Application name "PM_ControlPanel" Key name "LogoDisplayTime" Type integer Content/value -1 <= time <= 32767 milliseconds. Indefinite display -1 No display 0 Timed display >0 Application name "PM_ControlPanel" Key name "cxDoubleClick" Type integer Content/value SV_CXDBLCLK size in pels. Application name "PM_ControlPanel" Key name "cyDoubleClick" Type integer Content/value SV_CYDBLCLK size in pels. Application name "PM_ControlPanel" Key name "cxMotionStart" Type integer Content/value SV_CXMOTIONSTART size in pels. Application name "PM_ControlPanel" Key name "cyMotionStart" Type integer Content/value SV_CYMOTIONSTART size in pels. Application name "PM_National" Key name "iCountry" Type integer Content/value country code: Arabic 785 Australian 61 Belgian 32 Canadian-French 2 Danish 45 Finnish 358 French 33 German 49 Hebrew 972 Italian 39 Japanese 81 Korean 82 Latin-American 3 Netherlands 31 Norwegian 47 Portuguese 351 Simpl. Chinese 86 Spanish 34 Swedish 46 Swiss 41 Trad. Chinese 88 UK-English 44 US-English 1 Other country 0. Application name "PM_National" Key name "iDate" Type integer Content/value 0=MDY; 1=DMY; 2=YMD. Application name "PM_National" Key name "iCurrency" Type integer Content/value Values have the following meanings: 0 Prefix, no separator 1 Suffix, no separator 2 Prefix, 1 character separator 3 Suffix, 1 character separator. Application name "PM_National" Key name "iDigits" Type integer Content/value n = number of decimal digits. Application name "PM_National" Key name "iTime" Type integer Content/value 0 = 12-hour clock; 1 = 24-hour clock. Application name "PM_National" Key name "iLzero" Type integer Content/value 0 = no leading zero; 1 = leading zero. Application name "PM_National" Key name "s1159" Type string Content/value "am" for example. 3 chars max. Application name "PM_National" Key name "s2359" Type string Content/value "pm" for example. 3 chars max. Application name "PM_National" Key name "sCurrency" Type string Content/value "$" for example. 3 chars max. Application name "PM_National" Key name "sThousand" Type string Content/value "," for example. 1 char max. Application name "PM_National" Key name "sDecimal" Type string Content/value "." for example. 1 char max. Application name "PM_National" Key name "sDate" Type string Content/value "/" for example. 1 char max. Application name "PM_National" Key name "sTime" Type string Content/value ":" for example. 1 char max. Application name "PM_National" Key name "sList" Type string Content/value "," for example. 1 char max. Application name PM_Fonts Key name Type string Content/value fully-qualified drive:\path\filename.ext. Application name "PM_SPOOLER" Key name "QUEUE" Type string Content/value ; where: is the name of the default queue (might be NULL). This must be a key name for the PM_SPOOLER_QUEUE application. Application name "PM_SPOOLER" Key name " PRINTER" Type string Content/value ; where: is the name of the default printer (might be NULL). Note: Use the SplQueryDevice and SplQueryQueue functions to retrieve the spooler configuration data. ═══ 21.5. Interchange File Format ═══ A metafile is a file in which graphics are stored. The file is application-created, and it contains the graphics orders generated from those GPI calls that are valid in a metafile. Metafiled graphics can be reused by the application that created them. They can also be made available to other applications at the same, or at a different, workstation. This section describes the restrictions which apply when generating the metafile and gives detail of the overall structure. For the graphics orders descriptions, see "Graphics Orders" in the Graphics Programming Interface Programming Reference. ═══ 21.5.1. Metafile Restrictions ═══ The following restrictions apply to the generation of all metafiles, and also to the generation of a PM_Q_STD print file to a OD_QUEUED device:  If GpiWCBitBlt or GpiBitBlt is used to copy a bit map to a device context in an application, the application should not delete that bit map handle with GpiDeleteBitmap before the device context is closed (metafile is closed).  GpiSetPS must not be used.  GpiSetPageViewport is ignored. The following section lists some general rules that must be followed when creating a metafile that is to be acceptable to SAA-conforming implementations, or replayed into a presentation space that is in draw-and-retain or retain mode (see "GpiSetDrawingMode" in Graphics Programming Interface Programming Reference).  These items must be established or defaulted before any drawing occurs to the graphics presentation space, and not changed subsequently: - The graphics field (GpiSetGraphicsField). For an SAA-conforming metafile, the graphics field must be defaulted or set to no clipping. - The code page for the default character set (GpiSetCp). - The color table or palette (GpiCreateLogColorTable or GpiCreatePalette). The size of the color table must not exceed 31KB (KB equals 1024 bytes). - The default viewing transform (GpiSetDefaultViewMatrix). - The setting of the draw controls (GpiSetDrawControl). DCTL_DISPLAY must be defaulted or set ON. - The default values of attributes (see "GpiSetDefAttrs" in the Graphics Programming Interface Programming Reference), viewing limits (see "GpiSetDefViewingLimits" in the Graphics Programming Interface Programming Reference), primitive tag (see "GpiSetDefTag" in the Graphics Programming Interface Programming Reference) and arc parameters (see "GpiSetDefArcParams" in the Graphics Programming Interface Programming Reference).  These calls should not be used: - GpiBitBlt - GpiDeleteSetId (note that this means that local identifiers cannot be used again within the picture) - GpiErase - GpiExcludeClipRectangle - GpiIntersectClipRectangle - GpiOffsetClipRegion - GpiPaintRegion - GpiResetPS - GpiSetClipRegion - GpiSetPel - GpiSetPS - DevEscape (for an escape which is metafiled).  GpiCreateLogFont must not redefine a local identifier that has previously been used within the picture.  The metafile context must not be reassociated.  If a bit map is used as the source of a GpiWCBitBlt operation, or as an area-fill pattern, it must not be modified or deleted (GpiDeleteBitmap) before the metafile is closed.  Only these foreground mixes must be used (see "GpiSetMix" in the Graphics Programming Interface Programming Reference): - FM_DEFAULT - FM_OR - FM_OVERPAINT - FM_LEAVEALONE  Only these background mixes must be used (see "GpiSetBackMix" in the Graphics Programming Interface Programming Reference): - BM_DEFAULT - BM_OVERPAINT - BM_LEAVEALONE  If palettes are used (see "GpiCreatePalette" in the Graphics Programming Interface Programming Reference): the palette that is metafiled is the one in force when the metafile device context is dissociated from the (final) presentation space. If the palette is changed during the course of the picture (using GpiSetPaletteEntries), it must therefore only be with incremental additions. Note: There is no restriction concerning the use of primitives outside segments. These are metafiled in segment(s) with zero identifier. ═══ 21.5.2. Metafile Data Format ═══ This section describes the format of the data in a metafile, as it would be stored in an OS/2 disk file. Metafile data is stored as a sequence of structured fields. Each structured field starts with an eight-byte header consisting of a two-byte length field and a three-byte identifier field. These are followed by a one-byte flags field and a two-byte segment sequence number field. The length field contains a count of the total number of bytes in the structured field, including the length field. The identifier field uniquely identifies the type of the structured field. The flags and segment sequence number fields are always zero. Following the header are positional parameters that are optional and dependent on the particular structured field. Following the positional parameters are non-positional parameters called triplets. These are self-defining parameters and consist of a one-byte length field, followed by a one-byte identifier field, followed by the data of the parameter. The length field contains a count of the total number of bytes in the triplet, including the length and identifier fields. The identifier field identifies uniquely the type of the triplet. A metafile is structured into a number of different functional components; for example, document and graphics object. Each component comprises a number of structured fields, and is delimited by "begin-component" and "end-component" structured fields. Structured fields marked as required, inside an optional structured field bracket, are required if the containing bracket is present. The graphics orders that describe a picture occur in the graphics data structured field. See Structured Field Formats for more information. ═══ 21.5.3. Structured Field Formats ═══ Following is the format of the various structured fields: Begin Document Structured Field Introducer (BDT): required 0-1 Length 0xn+1E 2-4 BDT 0xD3A8A8 5 Flags 0x00 6-7 Segment sequence number 0x0000 Parameters 0-7 Document name C'0000 0001' 8 Architecture version 0x00 9 Document security 0x00 Triplets (all required) 0 Length 0x05 1 Triplet Id 0x18 2 Interchange set type 0x03 (resource document) 3-4 Base set definition 0x0C00 (level 12, version 0) 0 Length 0x06 1 Triplet Id 0x01 2-5 GCID 0 Length 0xn+1 1 Triplet Id 0x65 2-n Comment, used for metafile description of up to 252 bytes. Begin Resource Group (BRG): required Structured Field Introducer 0-1 Length 0x0010 2-4 BRG 0xD3A8C6 5 Flags 0x00 6-7 Segment sequence number 0x0000 Parameters 0-7 Resource group name C'0000 0002' Begin Color Attribute (BCA) Table: required Structured Field Introducer 0-1 Length 0x0010 2-4 BCA 0xD3A877 5 Flags 0x00 6-7 Segment sequence number 0x0000 Parameters 0-7 Color table name C'0000 0004' Color Attribute Table (CAT): required Structured Field Introducer 0-1 Length 0xn+8 2-4 CAT 0xD3B077 5 Flags 0x00 6-7 Segment sequence number 0x0000 Parameters Base Part (required) 0 Flags 0 Reserved B'0' 1 Reset B'0' Do not reset to default B'1' Do reset to default 2-7 Reserved B'000000' 1 Reserved 0x00 2 LCTID 0x00 Element list(s) (triple generating) are mutually-exclusive. One or other is required. Element List (repeating) 0 Length of this parameter 1 Type 0x01: element list 2 Flags 0x00: reserved 3 Format 0x01 RGB 4-6 Starting Index (Top Byte Truncated) 7 Size of RGB component1 0x08 8 Size of RGB component2 0x08 9 Size of RGB component3 0x08 10 Number of bytes in each following color triple 0x04 11-m Color triples Triple Generating 0 Length of this parameter 0x0A 1 Type 0x02: bit generator 2 Flags 0 ABFlag B'0' Normal 1-7 Reserved B'0000000' 3 Format 0x01 RGB 4-6 Starting index (top byte truncated) 7 Size of RGB component1 0x08 8 Size of RGB component2 0x08 9 Size of RGB component3 0x08 End Color Attribute (ECA) Table: required Structured Field Introducer 0-1 Length 0x0010 2-4 ECA 0xD3A977 5 Flags 0x00 6-7 Segment sequence number 0x0000 Parameters 0-7 Color table name C'0000 0004' Begin Image Object (BIM): optional, repeating Structured Field Introducer 0-1 Length 0x0010 2-4 BIM 0xD3A8FB 5 Flags 0x00 6-7 Segment sequence number 0x0000 Parameters 0-7 Image name C'xxxx xxxx' Begin Resource Group (BRG): optional Structured Field Introducer 0-1 Length 0x0010 2-4 BRG 0xD3A8C6 5 Flags 0x00 6-7 Segment sequence number 0x0000 Parameters 0-7 Resource group name C'xxxx xxxx' Color Attribute Table (BCA): optional Structured Field Introducer 0-1 Length 0x0010 2-4 BCA 0xD3A877 5 Flags 0x00 6-7 Segment sequence number 0x0000 Parameters 0-7 Color table name C'xxxx xxxx' Color Attribute Table (CAT): required Structured Field Introducer 0-1 Length 2-4 CAT 0xD3B077 5 Flags 0x00 6-7 Segment sequence number 0x0000 Parameters Base Part 0 Flags 0x00 1 Reserved 0x00 2 LUTID Element List (repeating) 0 Length of this parameter 1 Type 0x01: element list 2 Flags 0x00: reserved 3 Format 0x01: RGB 4-6 Starting index (top byte truncated) 7 Size of RGB component1 0x08 8 Size of RGB component2 0x08 9 Size of RGB component3 0x08 10 Number of bytes in each following color triple 0x03 11-n Color triples End Color Attribute Table (ECA): required if BCA present Structured Field Introducer 0-1 Length 0x0010 2-4 ECA 0xD3A977 5 Flags 0x00 6-7 Segment sequence number 0x0000 Parameters 0-7 Color Table name C'xxxx xxxx' End Resource Group (ERG): required if BRG present Structured Field Introducer 0-1 Length 0x0010 2-4 ERG 0xD3A9C6 5 Flags 0x00 6-7 Segment sequence number 0x0000 Parameters 0-7 Resource Group name C'xxxx xxxx' Begin Object Environment Group (BOG): optional Structured Field Introducer 0-1 Length 0x0010 2-4 BOG 0xD3A8C7 5 Flags 0x00 6-7 Segment sequence number 0x0000 Parameters 0-7 Object environment group name C'xxxx xxxx' Map Color Attribute (MCA) Table: required Structured Field Introducer 0-1 Length 0x001A 2-4 MCA 0xD3AB77 5 Flags 0x00 6-7 Segment sequence number 0x0000 Parameters 0-1 Length Triplet (required) 0 Length 0x0C 1 Triplet type: fully qualified name 0x02 2 Type: ref to Begin Resource Object 0x84 3 ID 0x00 4-11 Color table name C'xxxx xxxx' lcid (required) 0 Length 0x04 1 Triplet type: resource local ID 0x24 2 Type color table resource 0x07 3 Local identifier (LUT-ID) 0x01 End Object Environment Group (EOG): required if BOG present Structured Field Introducer 0-1 Length 0x0010 2-4 EOG 0xD3A9C7 5 Flags 0x00 6-7 Segment sequence number 0x0000 Parameters 0-7 Object Environment Group name C'xxxx xxxx' Image Data Descriptor (IDD): required Structured Field Introducer 0-1 Length 0x0011 2-4 IDD 0xD3A6FB 5 Flags 0x00 6-7 Segment sequence number 0x0000 Parameters 0 Unit of measure: 0x00 tens of inches 0x01 tens of centimeters 1-2 X resolution image points / UOM 3-4 Y resolution image points / UOM 5-6 X extent of image PS 7-8 Y extent of image PS Image Picture Data (IPD): required Structured Field Introducer 0-1 Length 2-4 IPD 0xD3EEFB 5 Flags 0x00 6-7 Segment sequence number 0x0000 Parameters (all required and in this order, except that only one of Image LUT-ID and IDE structure is present) Begin Segment 0 Type 0x70: begin segment 1 Length of following 0x00 Begin Image Content 0 Type 0x91: Begin Image Content 1 Length of following 0x01 2 Format 0xFF Image Size 0 Type 0x94: image size 1 Length of following 0x09 2 Units of measure 0x02: logical 3-4 Horizontal resolution 5-6 Vertical resolution 7-8 Height in pels 9-10 Width in pels Image Encoding 0 Type 0x95: image encoding 1 Length of following 0x02 2 Compression algorithm 0x03: none 3 Recording algorithm 0x03: bottom-to-top Image IDE-Size 0 Type 0x96: image IDE-Size 1 Length of following 0x01 2 Number of bits per element Image LUT-ID (For bit maps with other than 24 bits per pel) 0 Type 0x97 Image LUT-ID 1 Length of following 0x01 2 LUT-ID IDE Structure (For bit maps with 24 bits per pel) 0 Type 0x9B: IDE structure 1 Length of following 0x08 2 Flags: 0 ABFlag B'0' Normal (Additive) 1-7 Reserved B'0000000' 3 Format 0x01 RGB 4-6 Reserved 0x000000 7 Size of element 1 8 Size of element 2 9 Size of element 3 Image Picture Data (IPD): required, repeating Structured Field Introducer 0-1 Length 2-4 IPD 0xD3EEFB 5 Flags 0x00 6-7 Segment sequence number 0x0000 Parameters Image Data 0-1 Type 0xFE92: image data 2-3 Length of following 4-n Image data (scan lines of bit maps) End Image Content (required, only present in last Image Picture Data) 0 Type 0x93: End Image Content 1 Length of following 0x00 End Segment (required, only present in last Image Picture Data) 0 Type 0x71: end segment 1 Length of following 0x00 End Image Object (EIM): required if BIM present Structured Field Introducer 0-1 Length 0x0010 2-4 EIM 0xD3A9FB 5 Flags 0x00 6-7 Segment sequence number 0x0000 Parameters 0-7 Image name C'xxxx xxxx' Begin Graphics Object (BGR): required Structured Field Introducer 0-1 Length 0x0010 2-4 BGR 0xD3A8BB 5 Flags 0x00 6-7 Segment sequence number 0x0000 Parameters 0-7 Graphics object name C'0000 0007' Begin Object Environment Group (BOG): optional Structured Field Introducer 0-1 Length 0x0010 2-4 LOG 0xD3A8C7 5 Flags 0x00 6-7 Segment sequence number 0x0000 Parameters 0-7 Object Environment Group name C'0000 0007' Map Color Attribute Table (MCA): required Structured Field Introducer 0-1 Length 0x0016 2-4 MCA 0xD3AB77 5 Flags 0x00 6-7 Segment sequence number 0x0000 Parameters 0-1 Length Triplet (required) 0 Length 0x0C 1 Triplet type: fully qualified name 0x02 2 Type: ref to Begin Resource Object 0x84 3 ID 0x00 4-11 Color table name C'0000 0004' Map Coded Font (MCF): required, for default font Structured Field Introducer 0-1 Length 0x20 2-4 MCF 0xD3AB8A 5 Flags 0x00 6-7 Segment sequence number 0x0000 Parameters 0-1 Length Triplets (required) Font name 0 Length 0x0C 1 Triplet type: fully qualified name 0x02 2 Type: ref to coded font 0x84 3 ID 0x00 4-11 Coded font name: C'nnxx xxxx' where n is 0xFF lcid 0 Length 0x04 1 Triplet type: Resource Local ID 0x24 2 Type: Coded Font Resource 0x05 3 Local identifier (LCID) 0x00 Font Binary GCID 0 Length 0x06 1 Triplet type: Font Binary GCID 0x20 2-5 GCID Map Coded Font (MCF): optional, repeating, for loaded fonts Structured Field Introducer 0-1 Length 0x58 2-4 MCF 0xD3AB8A 5 Flags 0x00 6-7 Segment sequence number 0x0000 Parameters 0-1 Length Triplets (required) Font name 0 Length 0x0C 1 Triplet type: fully qualified name 0x02 2 Type: ref to coded font 0x84 3 ID 0x00 4-11 Coded font name lcid 0 Length 0x04 1 Triplet type: Resource Local ID 0x24 2 Type: coded font resource 0x05 3 Local identifier (LCID) Font Attributes 0 Length 0x14 1 Triplet type: Font Descriptor 0x1F 2 Weight Class 3 Width Class 4-5 Font Height 6-7 Char Width 8 Descript Flags 9 Usage Codes 10 Family 11 Activity Class 12 Font Quality 13-14 CAP Height 15-16 X Height 17-18 Line Density 19 Use Flags Font Binary GCID 0 Length 0x06 1 Triplet type: Font Binary GCID 0x20 2-5 GCID Font Typeface 0 Length 0x24 1 Triplet type: fully qualified name 0x02 2 Type: ref to font typeface 0x08 3 ID 0x00 4-35 Font typeface C'xxx..xxx' Map Data Resource (MDR): optional, repeating Structured Field Introducer 0-1 Length 0x1D 2-4 MDR 0xD3ABC3 5 Flags 0x00 6-7 Segment sequence number 0x0000 Parameters 0-1 Length Triplets (required) Bit-map Name 0 Length 0x0C 1 Triplet type: fully qualified name 0x02 2 Type: ref to Image Object 0x84 3 ID 0x00 4-11 Image name C'xxxx xxxx' Extended Resource lcid 0 Length 0x07 1 Triplet type: Extended Resource Local ID 0x22 2 Type: Image Resource 0x10 3-6 Bit-map handle End Object Environment Group (EOG): required if BOG present Structured Field Introducer 0-1 Length 0x0010 2-4 EOG 0xD3A9C7 5 Flags 0x00 6-7 Segment sequence number 0x0000 Parameters 0-7 Object Environment Group name C'0000 0007' Graphics Data Descriptor (GDD): required Structured Field Introducer 0-1 Length 0xnnnn 2-4 GDD 0xD3A6BB 5 Flags 0x00 6-7 Segment sequence number 0x0000 Parameters (all required and in this order) 0 0xF7 Specify GVM Subset 1 Length of following data 0x07 2 0xB0 drawing order subset 3-4 0x0000 5 0x23 Level 3.2 6 0x01 Version 1 7 Length of following field 0x01 8 Coordinate types in data 0x04 Intel16 0x05 Intel32 0 0xF6 Set Picture Descriptor 1 Length of following data 2 Flags 0 B'0' Picture in 2D 1 Picture Dimensions B'0' Not absolute (PU_ARBITRARY PS) B'1' Absolute (example: PU_TWIPS PS) 2 Picture Elements B'0' Not pels B'1' Pels (PU_PELS PS) (Bit 1 must also be set) 3-7 B'00000' 3 0x00 Reserved 4 Picture frame size coordinate type 0x04 Intel16 0x05 Intel32 5 UnitsOfMeasure 0x00 Ten inches 0x01 Decimeter 6-11 or 6-17(2 or 4 bytes) Resolution. GPS Units / UOM on x axis GPS Units / UOM on y axis GPS Units / UOM on z axis 12-23 or 18-41(2 or 4 bytes) Window Size. GPS X left, X right GPS Y bottom, Y top GPS Z near, Z far 0 0x21 Set Current Defaults 1 Length of following data 2 Set Default Parameter Format 0x08 3-4 Mask 0xE000 5 Names 0x8F 6 Coordinates 0x00 Picture in 2D 7 Transforms 0x04 Intel16 0x05 Intel32 8 Geometrics 0x04 Intel16 0x05 Intel32 0 0x21 Set Current Defaults 1 Length of following data 2 Set default viewing transform 0x07 3-4 Mask 0xCC0C 5 Names 0x8F 6-n M11, M12, M21, M22, M41, M42 Matrix elements 0 0x21 Set Current Defaults 1 Length of following data 2 Set default line attributes 0x01 3-4 Mask - OR of as many of the following bits as are required: 0x8000 Line type 0x4000 Line width 0x2000 Line end 0x1000 Line join 0x0800 Stroke width 0x0008 Line color 0x0002 Line mix 5 Flags 0x0F Set indicated default attributes to initial values. (Data field is not present in this instance). 0x8F Set indicated default attributes to specified values. 6-n Data - data values as required, in the following order if present. No space is reserved for attributes for which the corresponding mask flag was not set. (1 byte) - Line type (1 byte) - Line width (1 byte) - Line end (1 byte) - Line join (G bytes) - Stroke width (4 bytes) - Line color (1 byte) - Line mix (G=2 or 4 depending on the Geometrics parameter of Set Default Parameter Format) 0 0x21 Set Current Defaults 1 Length of following data 2 Set Default Character Attributes 0x02 3-4 Mask - OR of as many of the following bits as are required: 0x8000 Character angle 0x4000 Character box 0x2000 Character direction 0x1000 Character precision 0x0800 Character set 0x0400 Character shear 0x0040 Character break extra 0x0020 Character extra 0x0008 Character color 0x0004 Character background color 0x0002 Character mix 0x0001 Character background mix 5 Flags 0x0F Set indicated default attributes to initial values. (Data field is not present in this case). 0x8F Set indicated default attributes to specified values. 6-n Data - data values as required, in the following order if present. No space is reserved for attributes for which the corresponding Mask flag was not set. (2*G bytes) - Character angle (2*G + 4 bytes) - Character box (1 byte) - Character direction (1 byte) - Character precision (1 byte) - Character set (2*G bytes) - Character shear (4 bytes) - Character break extra (4 bytes) - Character extra (4 bytes) - Character color (4 bytes) - Character background color (1 byte) - Character mix (1 byte) - Character background mix (G=2 or 4 depending on the Geometrics parameter of Set Default Parameter Format) 0 0x21 Set Current Defaults 1 Length of following data 2 Set Default Marker Attributes 0x03 3-4 Mask - OR of as many of the following bits as are required: 0x4000 Marker box 0x1000 Marker precision 0x0800 Marker set 0x0100 Marker symbol 0x0008 Marker color 0x0004 Marker background color 0x0002 Marker mix 0x0001 Marker background mix 5 Flags 0x0F Set indicated default attributes to initial values. (Data field is not present in this instance) 0x8F Set indicated default attributes to specified values. 6-n Data - data values as required, in this order if present. No space is reserved for attributes for which the corresponding Mask flag was not set. (2*G bytes) - Marker box (1 byte) - Marker precision (1 byte) - Marker set (1 byte) - Marker symbol (4 bytes) - Marker color (4 bytes) - Marker background color (1 byte) - Marker mix (1 byte) - Marker background mix (G=2 or 4 depending on the Geometrics parameter of Set Default Parameter Format) 0 0x21 Set Current Defaults 1 Length of following data 2 Set Default Pattern Attributes 0x04 3-4 Mask - OR of as many of the following bits as are required: 0x0800 Pattern set 0x0100 Pattern symbol 0x0080 Pattern reference point 0x0008 Pattern color 0x0004 Pattern background color 0x0002 Pattern mix 0x0001 Pattern background mix 5 Flags 0x0F Set indicated default attributes to initial values. (Data field is not present in this instance) 0x8F Set indicated default attributes to specified values. 6-n Data - data values as required, in this order if present. No space is reserved for attributes for which the corresponding Mask flag was not set. (1 byte) - Pattern set (1 byte) - Pattern symbol (2*G bytes) - Pattern reference point (4 bytes) - Pattern color (4 bytes) - Pattern background color (1 byte) - Pattern mix (1 byte) - Pattern background mix (G=2 or 4 depending on the Geometrics parameter of Set Default Parameter Format) 0 0x21 Set Current Defaults 1 Length of following data 2 Set Default Image Attributes 0x06 3-4 Mask - OR of as many of these bits as are required: 0x0008 Image color 0x0004 Image background color 0x0002 Image mix 0x0001 Image background mix 5 Flags 0x0F Set indicated default attributes to initial values. (Data field is not present in this instance) 0x8F Set indicated default attributes to specified values. 6-n Data - data values as required, in this order if present. No space is reserved for attributes for which the corresponding Mask flag was not set. (4 bytes) - Image color (4 bytes) - Image background color (1 byte) - Image mix (1 byte) - Image background mix 0 0x21 Set Current Defaults 1 Length of following data 2 Set Default Viewing Window 0x05 3-4 Mask - OR of as many of the following bits as are required: 0x8000 x left limit 0x4000 x right limit 0x2000 y bottom limit 0x1000 y top limit 5 Flags 0x0F Set indicated default attributes to initial values. (Data field is not present in this case). 0x8F Set indicated default attributes to specified values. 6-n Data - data values as required, in the following order if present. No space is reserved for attributes for which the corresponding Mask flag was not set. (2*G bytes) - x left limit (2*G bytes) - x right limit (2*G bytes) - y bottom limit (2*G bytes) - y top limit (G=2 or 4 depending on the Geometrics parameter of Set Default Parameter Format) 0 0x21 Set Current Defaults 1 Length of following data 2 Set Default Arc Parameters 0x0B 3-4 Mask - OR of as many of the following bits as are required: 0x8000 P value 0x4000 Q value 0x2000 R value 0x1000 S value 5 Flags 0x0F Set indicated default attributes to initial values. (Data field is not present in this case). 0x8F Set indicated default attributes to specified values. 6-n Data - data values as required, in the following order if present. No space is reserved for attributes for which the corresponding Mask flag was not set. (G bytes) - P value (G bytes) - Q value (G bytes) - R value (G bytes) - S value (G=2 or 4 depending on the Geometrics parameter of Set Default Parameter Format) 0 0x21 Set Current Defaults 1 Length of following data 2 Set Default Pick Identifier 0x0C 3-4 Mask - OR of as many of the following bits as are required: 0x8000 Pick identifier 5 Flags 0x0F Set indicated default attributes to initial values. (Data field is not present in this case). 0x8F Set indicated default attributes to specified values. 6-n Data - data values as required, in the following order if present. No space is reserved for attributes for which the corresponding Mask flag was not set. (4 bytes) - Pick identifier 0 0xE7 Set Bit-map Identifier 1 Length of following data 0x07 2-3 Usage Flags 0x8000 4-7 Bit-map handle 8 Lcid Graphics Data (GAD): optional, repeating Structured Field Introducer 0-1 Length 0xn+9 2-4 GAD 0xD3EEBB 5 Flags 0x00 6-7 Segment sequence number 0x0000 Parameters (maximum length in one structured field is 32759) Graphics Segment (optional, repeating) Segment data (including the Begin Segment parameter) can be split at any point between successive Graphics Data structured fields. 0 0x70 Begin Segment 1 Length of following data 0x0E 2-5 Segment identifier 6 Segment attributes (1) 0 B'1' Invisible 1 B'1' Propagate invisibility 2 B'1' Detectable 3 B'1' Propagate detectability 6 B'1' Dynamic 7 B'1' Fast chaining 7 Segment attributes (2) 0 B'1' Non-chained 3 B'1' Prolog 8-9 Segment data length (low-order 2 bytes) 10-13 Reserved 14-15 Segment data length (high-order 2 bytes) 16-n Graphics orders (see the Graphics Programming Interface Programming Reference) End Graphics Object (EGR) Structured Field Introducer 0-1 Length 0x0010 2-4 EGR 0xD3A9BB 5 Flags 0x00 6-7 Segment sequence number 0x0000 Parameters 0-7 Graphics object name C'0000 0007' End Resource Group (ERG): required Structured Field Introducer 0-1 Length 0x0010 2-4 ERG 0xD3A9C6 5 Flags 0x00 6-7 Segment sequence number 0x0000 Parameters 0-7 Resource Group name C'0000 0002' End Document (EDT): required Structured Field Introducer 0-1 Length 0x0010 2-4 EDT 0xD3A9A8 5 Flags 0x00 6-7 Segment sequence number 0x0000 Parameters 0-7 Document name C'0000 0001' ═══ 21.6. Resource Files ═══ This section describes the syntax for the resource language using railroad syntax, and describes the formats used. Resource files are used to build dialog templates, menu templates, accelerator tables, extended attribute association tables, keyboard scancode mapping tables, keyboard names and fonts. The files must be compiled before they can be used by application programs. How to Read the Syntax Definitions Throughout this reference, syntax is described using the following structure.  Read the syntax diagrams from left to right, from top to bottom, following the path of the line. The ─── symbol indicates the beginning of a statement. The ─── symbol indicates that the statement syntax is continued on the next line. The ─── symbol indicates that a statement is continued from the previous line. The ─── symbol indicates the end of a statement. Diagrams of syntactical units other than complete statements start with the ─── symbol and end with the ─── symbol.  Required items appear on the horizontal line (the main path). ───STATEMENT───────required_item───────────  Optional items appear below the main path. ───STATEMENT─────├───────────────├───────── └─optional_item─┘  If a choice can be made from two or more items, they appear vertically, in a stack. If one of the items must be chosen, one item of the stack appears on the main path. ───STATEMENT───├──required_choice1──├────── └──required_choice2──┘ If choosing one of the items is optional, the entire stack appears below the main path. ───STATEMENT───├────────────────────├────── ├──optional_choice1── └──optional_choice2──┘  An arrow returning to the left above the main path indicates an item that can be repeated. ┌──────────────────┐  │ ───STATEMENT─────repeatable_item──├──────── A repeat arrow above a stack indicates that a choice can be made from the stacked items, or a single choice can be repeated.  Keywords appear in uppercase, for example: PARM1 They must be spelled exactly as shown. Variables appear in all lowercase letters, for example: parmx They represent user-supplied names or values.  If punctuation marks, parentheses, arithmetic operators, or such symbols are shown, they must be entered as part of the syntax. ═══ 21.6.1. Definitions Used in all Resources ═══ The definitions used in all resources are defined in Specification of Values and Resource Load and Memory Options. ═══ 21.6.1.1. Specification of Values ═══ These rules apply to values specified in resources:  Coordinates must be integers. There must be no space between the sign of the value and the value itself. For example, "-1" is allowed but "- 1" is not.  Resource identifiers may be any of the following: - Positive integers - Names that resolve to positive integers - Strings (for some resources)  Real values, containing a decimal point, cannot be used. ═══ 21.6.1.2. Resource Load and Memory Options ═══ The following options define when each resource is loaded and how memory is allocated for each resource. LOADOPTION Resource loading options. PRELOAD Resource is loaded immediately. LOADONCALL Resource is loaded when called. MEMOPTION Resource memory options. FIXED Resource remains at a fixed memory location. MOVEABLE Resource can be moved if necessary to compact. DISCARDABLE Resource can be discarded if no longer needed. SEGALIGN Resources are aligned on 64K byte boundaries. ═══ 21.6.2. Resource Script File Specification ═══ The resource script file defines the names and attributes of the resources to be added to the executable file of the application. The file consists of one or more resource statements that define the resource type and original file, if any. See the following for a description of the resource statements:  Single-Line Statements  User-Defined Resources  Directives  Multiple-Line Statements. ═══ 21.6.2.1. Single-Line Statements ═══ The general form for all single-line statements is: ──resourcetype──nameid──├────────────├───── └─loadoption─┘ ──├───────────├──filename── └─memoption─┘ resourcetype (USHORT) One of the following keywords, specifying the type of resource to be loaded: Keyword Resource type BITMAP A bit-map resource is a custom bit map that an application intends to use in its screen display or as an item in a menu. DEFAULTICON This keyword installs the filename.ico icon definition under the ICON EA of the program file. Example: Uses Os2Def,Os2Base,Os2PmApi; Var : DEFAULTICON; (* Сsken var tom!! *) Begin := DEFAULTICON DLGINCLUDE This statement tells the dialog editor which file to use as an include file for the dialogs in the resource file. The nameid is not applicable. FONT A font resource is a file containing a font. ICON An icon resource is a bit map defining the shape of the icon to be used for a given application. POINTER A pointer resource is a bit map defining the shape of the pointing device pointer on the display screen. nameid (USHORT) is either a unique name or an integer number identifying the resource. For a FONT resource, the nameid must be a number; it cannot be a name. loadoption (LOADOPTION) The default is LOADONCALL. See Resource Load and Memory Options for a description of LOADOPTION. memoption (MEMOPTION) The default is MOVEABLE and DISCARDABLE for POINTER, ICON, and FONT resources. The default for BITMAP resources is MOVEABLE. The FIXED option overrides both MOVEABLE and DISCARDABLE. The SEGALIGN option can be specified independently of other options, if it is not present the default (for all resources) is that the resource is not aligned on a 64KB boundary. See Resource Load and Memory Options for a description of MEMOPTION. filename (PCH) An ASCII string specifying the OS/2* name of the file containing the resource. A full path must be given if the file is not in the current working directory. Example Uses Os2Def,Os2Base,Os2PmApi; Var "pointer" : POINTER; (* Сsken var tom!! *) "discardable : POINTER; (* Сsken var tom!! *) 10 : POINTER; (* Сsken var tom!! *) Begin "pointer" := POINTER "discardable := POINTER 10 := POINTER Uses Os2Def,Os2Base,Os2PmApi; Var "desk" : ICON; (* Сsken var tom!! *) "discardable : ICON; (* Сsken var tom!! *) 11 : ICON; (* Сsken var tom!! *) Begin "desk" := ICON "discardable := ICON 11 := ICON Uses Os2Def,Os2Base,Os2PmApi; Var "disk" : BITMAP; (* Сsken var tom!! *) "discardable : BITMAP; (* Сsken var tom!! *) 12 : BITMAP; (* Сsken var tom!! *) Begin "disk" := BITMAP "discardable := BITMAP 12 := BITMAP Uses Os2Def,Os2Base,Os2PmApi; Var 5 : FONT; (* Сsken var tom!! *) Begin 5 := FONT ═══ 21.6.2.2. User-Defined Resources ═══ An application can also define its own resource. The resource can be any data that the application intends to use. A user-defined resource statement has the form: ───resource-type───typeID───nameID──────────────────────────── ────├──────────────├───├─────────────├───filename──── └──loadoption──┘ └──memoption──┘ typeID Either a unique name or an integer number identifying the resource type. If a number is given, it must be greater than 255. The type numbers 1 through 255 are reserved for existing and future predefined resource types. Value 1000 is reserved for custom fonts. nameID Either a unique name or an integer number identifying the resource. loadoption (LOADOPTION) The default is LOADONCALL. See Resource Load and Memory Options for a description of LOADOPTION. memoption (MEMOPTION) The default is MOVEABLE. See Resource Load and Memory Options for a description of MEMOPTION. filename Can be either:  An ASCII string specifying the OS/2* name of the file containing the cursor bit map. A full path must be given if the file is not in the current working directory.  A BEGIN END data definition construct as follows: BEGIN data - definition [ , data - definition ] & period . & period . & period . & period . & period . & period . END For example, the RESOURCE statement might be written as follows: Uses Os2Def , Os2Base , Os2PmApi ; Var MYRES : RESOURCE ; ( * С sken var tom ! ! * ) Begin MYRES : = RESOURCE BEGIN 13L , 26L END : elines . When the resource compiler (RC.EXE) encounters one or more font resources, or any custom resource having type-id of 1000, it creates a font directory resource which it adds to the output binary data. Example ═══ 21.6.2.2.1. RCDATA statement ═══ The RCDATA statement is provided to allow an application to define a simple data resource. ─RCDATA───id────loadoption─────memoption─── ┌─├────,────├─┐  └─newline─┘ │ ───BEGIN─────────data────├────END────── id Either a unique name or an integer number identifying the resource. loadoption (LOADOPTION) The default is LOADONCALL. See Resource Load and Memory Options for a description of LOADOPTION. memoption (MEMOPTION) The default is MOVEABLE. See Resource Load and Memory Options for a description of MEMOPTION. data A number or string. Example: Uses Os2Def,Os2Base,Os2PmApi; Var 4 : RCDATA; (* Сsken var tom!! *) Begin 4 := RCDATA BEGIN "Sample string." "TEST DATA." "A message." END ═══ 21.6.2.3. Directives ═══ The resource directives are special statements that define actions to perform on the file before it is compiled. The directives can assign values to names, include the contents of files, and control compilation of the file. #include filename rcinclude filename These directives copy the contents of the file specified by filename into the resource before it is compiled. If rcinclude is used, the entire file is copied. If #include is used, only #define statements are copied. Note: If an rcinclude is to be commented out, the open comment (/*) must appear on the same line as the directive. Filename is an ASCII string. A full path must be given if the file is not in the current directory or in the directory specified by the INCLUDE environment variable. The file extensions .I and .TMP must not be used as these are reserved for system use. The filename parameter is handled as a C string, and two back-slashes must be given wherever one is expected in the path name (for example, root\\sub.) or, a single forward slash (/) can be used instead of double back-slashes (for example, root/sub.) Example: Uses Os2Def,Os2Base,Os2PmApi; Var PenSelect : MENU; (* Сsken var tom!! *) Begin PenSelect := MENU BEGIN Uses Os2Def,Os2Base,Os2PmApi; Var "black : MENUITEM; (* Сsken var tom!! *) Begin "black := MENUITEM END Files included in resource script files constants that use #define statements may not include any casting of those constants that are used in the resource script. The resource compiler does not parse this casting syntax. For example, the following statement may not be included: If casting is required for C source compilation, you may use two statements such as: #define name value This directive assigns the given value to name. All subsequent occurrences of name are replaced by the value. name is any combination of letters, digits, or punctuation. value is any integer, character string, or line of text. Example: #undef name This directive removes the current definition of name. All subsequent occurrences of name are processed without replacement. name is any combination of letters, digits, or punctuation. Example: #undef nonzero #undef USERCLASS #ifdef name This directive performs a conditional compilation of the resource file by checking the specified name. If the name has been defined using a #define directive, #ifdef directs the resource compiler to continue with the statement immediately after it. If the name has not been defined, #ifdef directs the compiler to skip all statements up to the next #endif directive. name is the name to be checked by the directive. Example: #Ifdef Debug Uses Os2Def,Os2Base,Os2PmApi; Var 4 : FONT; (* Сsken var tom!! *) Begin 4 := FONT .******** #endIf #ifndef name This directive performs a conditional compilation of the resource file by checking the specified name. If the name has not been defined or if its definition has been removed using the #undef directive, #ifndef directs the resource compiler to continue processing statements up to the next #endif, #else, or #elif directive, then skip to the statement after the #endif. If the name is defined, #ifndef directs the compiler to skip to the next #endif, #else, or #elif directive. name is the name to be checked by the directive. Example: #Ifndef Optimize Uses Os2Def,Os2Base,Os2PmApi; Var 4 : FONT; (* Сsken var tom!! *) Begin 4 := FONT .******** #endIf #if constant expression This directive performs a conditional compilation of the resource file by checking the specified constant-expression. If the constant-expression is nonzero, #if directs the resource compiler to continue processing statements up to the next #endif, #else, or #elif directive, then skip to the statement after the #endif. If the constant-expression is zero, #if directs the compiler to skip to the next #endif, #else, or #elif directive. constant expression is a defined name, an integer constant, or an expression consisting of names, integers, and arithmetic and relational operators. Example: #If Version<3 Uses Os2Def,Os2Base,Os2PmApi; Var 4 : FONT; (* Сsken var tom!! *) Begin 4 := FONT .******** #endIf #elif constant expression This directive marks an optional clause of a conditional compilation block defined by an #ifdef, #ifndef, or #if directive. The directive carries out conditional compilation of the resource file by checking the specified constant-expression. If the constant-expression is nonzero, #elif directs the resource compiler to continue processing statements up to the next #endif, #else, or #elif directive, then skip to the statement after the #endif. If the constant-expression is zero, #elif directs the compiler to skip to the next #endif, #else, or #elif directive. Any number of #elif directives can be used in a conditional block. constant expression Is a defined name, an integer constant, or an expression consisting of names, integers, and arithmetic and relational operators. Example: #If Version<3 Uses Os2Def,Os2Base,Os2PmApi; Var 4 : FONT; (* Сsken var tom!! *) Begin 4 := FONT .******** #elIf Version<7 Uses Os2Def,Os2Base,Os2PmApi; Var 4 : FONT; (* Сsken var tom!! *) Begin 4 := FONT .******** #endIf #else This directive marks an optional clause of a conditional compilation block defined by an #ifdef, #ifndef, or #if directive. The #else directive must be the last directive before #endif. Example: #Ifdef Debug Uses Os2Def,Os2Base,Os2PmApi; Var 4 : FONT; (* Сsken var tom!! *) Begin 4 := FONT .******** #Else Uses Os2Def,Os2Base,Os2PmApi; Var 4 : FONT; (* Сsken var tom!! *) Begin 4 := FONT .******** #endIf #endif This directive marks the end of a conditional compilation block defined by an #ifdef, #ifndef, or #if directive. One #endif is required for each #ifdef, #ifndef, and #if directive. ═══ 21.6.2.4. Multiple-Line Statements ═══ This sections covers Code Page Flagging, Keyboard Resources, and the following multiple-line statements:  ACCELTABLE Statement  ASSOCTABLE Statement  MENU Statement  STRINGTABLE Statement  Dialog and Window Template Statements ═══ 21.6.2.4.1. Code Page Flagging ═══ The CODEPAGE statement may be placed within the source, to set the code page used for these resources:  ACCELTABLE  MENU  STRINGTABLE  DIALOGTEMPLATE and WINDOWTEMPLATE. The CODEPAGE statement cannot be encoded within any other statement. All items following a CODEPAGE statement are assumed to be in that code page. The code page is encoded in the resource, and the data in the resource is assumed to be in the specified code page. However, no checking is performed. These code pages can be specified:  437  850  860  863  865. If the code page is not specified, code page 850 is assumed. ═══ 21.6.2.4.2. Keyboard Resources ═══ RT_FKALONG (=17), is defined in BSEDOS.H, and the resource compiler (RC.EXE) recognizes FKALONG. This type identifies a 256-byte table, that can be used for either primary or secondary scan-code mapping. The resource ID contains three bytes, the least significant byte identifying the type of scan-code mapping table as follows: 0 Primary scan-code mapping 1 Secondary scan-code mapping. The other two bytes are 0 for the primary mapping table, and the keyboard ID (as defined in PMWINP.H) for secondary mapping tables. This is to enable simple support to be provided for future keyboards with conflicting scan codes. The primary scan-code mapping table in the interrupt handler is stored as a resource of this type. The secondary scan-code mapping table in the interrupt handler is also stored as a resource of this type. Depending on which keyboard is attached, the resources are loaded when the system is initialized, and transferred to RING-0 byte arrays, where they can be accessed by the interrupt handler as necessary. A default primary scan-code mapping table is transferred if the resource cannot be loaded. ═══ 21.6.2.4.3. ACCELTABLE Statement ═══ The ACCELTABLE statement defines a table of accelerator keys for an application. An accelerator is a keystroke defined by the application to give the user a quick way to perform a task. The WinGetMsg function automatically translates accelerator messages from the application queue into WM_COMMAND, WM_HELP, or WM_SYSCOMMAND messages. The ACCELTABLE statement has the form: ───ACCELTABLE──├──────├────├───────────├─── └──id──┘ └─memoption─┘ ────BEGIN─────────────────────────────────── ┌────────────────────────────────────────┐ │ ┌──────,───────┐│   ││ ──├───────├─,─├─────├──,────acceloption──├├─ └keyval─┘ └─cmd─┘ ────END─── id (USHORT) The resource identifier. This is either an integer in the range of 1 through 65535 or a unique string enclosed in double quote marks. memoption Optional. It consists of the following keyword or keywords, specifying whether the resource is fixed or movable, and whether it can be discarded: FIXED Resource remains at a fixed memory location. MOVEABLE Resource can be moved if necessary to compact memory. DISCARDABLE Resource can be discarded if no longer needed. See Resource Load and Memory Options for a description of LOADOPTION. keyval (USHORT) The accelerator character code. This can be either a constant or a quoted character. If it is a quoted character, the CHAR acceloption is assumed. If the quoted character is preceded with a caret character (^), a control character is specified as if the CONTROL acceloption had been used. cmd (USHORT) The value of the WM_COMMAND, WM_HELP, or WM_SYSCOMMAND message generated from the accelerator for the indicated key. acceloption (BIT_16) Defines the kind of accelerator. The following options are available: ALT CHAR CONTROL HELP LONEKEY SCANCODE SHIFT SYSCOMMAND VIRTUALKEY. The VIRTUALKEY, SCANCODE, LONEKEY, and CHAR acceloptions specify the type of message that matches the accelerator. Only one of these options can be specified for each accelerator. For information on the corresponding KC_* values, see WM_CHAR. The acceloptions SHIFT, CONTROL, and ALT, cause a match of the accelerator only if the corresponding key is down. If there are two accelerators that use the same key with different SHIFT, CONTROL, or ALT options, the more restrictive accelerator should be specified first in the table. For example, Shift-Enter should be placed before Enter. The SYSCOMMAND acceloption causes the keystroke to be passed to the application as a WM_SYSCOMMAND message. The HELP acceloption causes the keystroke to be passed to the application as a WM_HELP message. If neither is specified, a WM_COMMAND message is used. Example: Uses Os2Def,Os2Base,Os2PmApi; Var "MainAcc" : ACCELTABLE; (* Сsken var tom!! *) Begin "MainAcc" := ACCELTABLE BEGIN VK_F1,101,HELP VK_F3,102,SYSCOMMAND END This generates a WM_HELP with value 101 from VIRTUALKEY accelerator F1 and a WM_SYSCOMMAND with value 102 from VIRTUALKEY accelerator F3. ═══ 21.6.2.4.4. ASSOCTABLE Statement ═══ The ASSOCTABLE statement defines the extended attributes (EA) for an application. The ASSOCTABLE statement has the form: ────ASSOCTABLE──assoctableid──────────────── ────BEGIN─────────────────────────────────── ┌───────────────────────────────────────┐  │ ───assocname,extensions─├──────├─,──├────├├─ └─flags┘ └icon┘ ────END─── The source for the ASSOCTABLE description is contained in the resource file for a particular project: Uses Os2Def,Os2Base,Os2PmApi; Var Assoctableid : ASSOCTABLE; (* Сsken var tom!! *) Begin Assoctableid := ASSOCTABLE BEGIN "association name", "extension", flags, icon filename "association name", "extension", flags, icon filename ... END association name Program recognizes data files of this EA TYPE. This is the same name found in the TYPE field of data files. assoctableid A name or number used to identify the assoctable resource. extension 3 letter file extension that is used to identify files of this type if they have no EA TYPE entry. (This may be empty.) flags EAF_DEFAULTOWNER The default application for the file. EAF_UNCHANGEABLE This flag is set if the entry in the ASSOCTABLE is not to be edited. EAF_REUSEICON This flag is specified if a previously defined icon in the ASSOCTABLE is to be reused. Entries with this flag set have no icon data defined. The icon used for this entry is the icon used for the previous entry (see below). Note that EAF_* flags may be ORed together when specified in the ASSOCTABLE. icon filename Filename of the icon used to represent this file type. (This may be empty.) Example Uses Os2Def,Os2Base,Os2PmApi; Var 3000 : ASSOCTABLE; (* Сsken var tom!! *) Begin 3000 := ASSOCTABLE BEGIN "Product XYZ Spreadsheet", "xys", EAF_DEFAULTOWNER, xyzspr.ico "Product XYZ Chart", "xyc", EAF_DEFAULTOWNER Or EAF_REUSEICON END ═══ 21.6.2.4.5. Dialog and Window Template Statements ═══ This section describes how to define dialog and window templates. It also describes the control data and presentation parameter structures that the application needs to create windows and define dialog templates. DLGTEMPLATE and WINDOWTEMPLATE statements are used by an application to create predefined window and dialog resource templates. These statements are treated identically by the resource compiler and have the following format: ───├─DLGTEMPLATE─────├──resourceid───────── └─WINDOWTEMPLATE──┘ ────├───────────├├───────────├├──────────├── └loadoption─┘└─memoption─┘└─codepage─┘ ───BEGIN──├──DIALOG statement───├───END─── ├──CONTROL statement── └──WINDOW statement───┘ In the following description of the parts of the DLGTEMPLATE and WINDOWTEMPLATE statements, data types are shown after each parameter or option. These are the data types that the parameter or option is converted to when it is compiled. Purpose The DLGTEMPLATE or WINDOWTEMPLATE statement marks the beginning of a window template. It defines the name of the window, and its memory and load options. resourceid (USHORT) This is either:  An integer (or a name that resolves to an integer) in the range of 1 through 65535  A unique string enclosed in double quote marks loadoption (LOADOPTION) The default is LOADONCALL. See Resource Load and Memory Options for a description of LOADOPTION. memoption (MEMOPTION) The default is MOVEABLE. See Resource Load and Memory Options for a description of MEMOPTION. code page (USHORT) The code page of the text in the template. Alternatively, ({) can be used in place of BEGIN and (}) in place of END. The DLGTEMPLATE and WINDOWTEMPLATE keywords are synonymous. The DIALOG statement defines a dialog-box window that can be created by an application and has the following format: ───DIALOG───text─,─id─,─x─,─y─,─cx─,─cy──── ───────├───────────────────├──────────────── └─,style─├────────── └─,control─┘ ──────────────────├├───────────────────────├ │ ││┌─────────────────────┐│ │ ││ ││ └CTLDATA─statement┘└─PRESPARAMS─statement─├┘ ┌────────────────────────┐  │ ─BEGIN─────├──DIALOG─statement──├─├──END─── ├──CONTROL─statement─ └──WINDOW─statement──┘ Control Data Statement Presentation Parameters Statement The WINDOW and CONTROL statements have the format: ─├─WINDOW─├─text,─id,─x,─y,─cx,─cy,─class── └─CONTROL┘ ──├──────────────────────────├──── └───,style───├───────────── └──,control───┘ ──────────────────├├───────────────────────├ │ ││┌─────────────────────┐│ │ ││ ││ └CTLDATA─statement┘└─PRESPARAMS─statement─├┘ ┌────────────────────────┐  │ ─BEGIN─────├──DIALOG─statement──├─├──END─── ├──CONTROL─statement─ └──WINDOW─statement──┘ Control Data Statement Presentation Parameters Statement Note: The WINDOW and CONTROL keywords are synonymous. The DIALOG, CONTROL, and WINDOW statements between the BEGIN and END statements are defined as child windows. Presentation parameters always apply to the whole control. They cannot be changed for the individual items within the control. Following is the description of the parameters for these statements. Purpose These statements mark the beginning of a window. They define the starting location on the display screen, its width, its height, and other details such as style. Note: Not all values may be specified for each statement type. For details, see the call syntax diagrams. text (PCH) A string, enclosed in double quotes, that is displayed in the title-bar control, if it exists. To insert a double-quote character (") in the text, use two double-quote characters (""). id (USHORT) Item identifier. x,y (SHORT) Integer numbers specifying the x- and y-coordinates on the display screen of the lower left corner of the dialog. X and y are in dialog coordinates. The exact meaning of the coordinates depends on the style defined by the style argument. For normal dialogs, the coordinates are relative to the origin of the parent window. For FCF_SCREENALIGN style boxes, the coordinates are relative to the origin of the display screen. With FCF_MOUSEALIGN, the coordinates are relative to the position of the pointer at the time the dialog is created. cx,cy (SHORT) Integer numbers specifying the width and height of the window. class (PCH) The class of the window or control to be created. Note: For a DIALOG statement the class is fixed as WC_FRAME and cannot be specified. style (ULONG) Any additional window style, frame style, or other class-specific style. The default style is WS_SYNCPAINT Or WS_CLIPSIBLINGS Or WS_SAVEBITS Or FS_DLGBORDER. If the FS_DLGBORDER or WS_SAVEBITS styles are not required, they should be preceded by the keyword "NOT". For example: Uses Os2Def,Os2Base,Os2PmApi; Var FS_DLGBORDER : NOT; (* Сsken var tom!! *) Begin FS_DLGBORDER := NOT replaces the FS_DLGBORDER default style by the FS_BORDER style and removes the WS_SAVEBITS style. Note that the logic of the NOT keyword is different from the corresponding operator in the C language. It is not possible to remove the default WS_SYNCPAINT and WS_CLIPSIBLINGS styles. control (ULONG) Frame Creation Flags (FCF_*) for the window. This data is placed in the control data field in the correct format for a window of class WC_FRAME. Note: FCF_SHELLPOSITION has no effect if specified in a template. CTLDATA Statement A statement used to define control data for the control. For more information on this statement, see Control Data Statement PRESPARAMS Statement A statement used to define presentation parameters. For more information on this statement, see Presentation Parameters Statement ═══ 21.6.2.4.6. MENU Statement ═══ The MENU statement defines the contents of a menu resource. A menu resource is a collection of information that defines the appearance and function of an application menu. A menu can be used to create an action bar. The MENU statement has the form: ─MENU-menuid──├────────────├├───────────├── └─loadoption─┘└─memoption─┘ ────├────────────├────────────────────────── └──codepage──┘ ┌─────────────────────┐  │ ┌──PRESPARAMS─statement─├┐ ────BEGIN──├────────────────────────├─────── ┌────────────────────────┐  │ ────────├───MENUITEM─statement───┼──END──── │ │ └───SUBMENU─statement────┘ Menu Item Statements Submenu Statements Presentation Parameters Statement. menuid (USHORT) This is either:  An integer (or a name that resolves to an integer) in the range of 1 through 65535  A unique string enclosed in double quote marks loadoption (LOADOPTION) The default is LOADONCALL. SeeResource Load and Memory Options for a description of LOADOPTION. memoption (MEMOPTION) The default is MOVEABLE. See Resource Load and Memory Options for a description of MEMOPTION. codepage (USHORT) The code page of the text. PRESPARAMS statement A special resource statement used to define presentation parameters. These are discussed in more detail in Presentation Parameters Statement. MENUITEM statement A special resource statement used to define the items in the menu. These are discussed in more detail in Menu Item Statements. SUBMENU statement A special resource statement used to define a submen. SUBMENU statements are discussed in more detail in Submenu Statements. Example Following is an example of a complete MENU statement: Uses Os2Def,Os2Base,Os2PmApi; Var "sample" : MENU; (* Сsken var tom!! *) Begin "sample" := MENU BEGIN Uses Os2Def,Os2Base,Os2PmApi; Var "&tilde.Alpha", : MENUITEM; (* Сsken var tom!! *) "&tilde.Beta", : SUBMENU; (* Сsken var tom!! *) Begin "&tilde.Alpha", := MENUITEM "&tilde.Beta", := SUBMENU BEGIN Uses Os2Def,Os2Base,Os2PmApi; Var "&tilde.Green", : MENUITEM; (* Сsken var tom!! *) "&tilde.Blue", : MENUITEM; (* Сsken var tom!! *) Begin "&tilde.Green", := MENUITEM "&tilde.Blue", := MENUITEM END END ═══ 21.6.2.4.6.1. Menu Item Statements ═══ MENUITEM statements are used in the item-definition section of a MENU statement to define the names and attributes of the actual menu items. Any number of statements can be given; each defines a unique item. The order of the statements defines the order of the menu items. Note: The MENUITEM statements can only be used within an item-definition section of a MENU statement. ──MENUITEM───────────────────────────────── ─├──string──,├────├,├──────├─,├──────────├├ │ └cmd─┘ └styles┘ └attributes┘│ │ │ └───────────────────SEPARATOR────────────┘ string (PCH) A string, enclosed in double quotation marks, specifying the text of the menu item. To insert a double-quote character (") in the text, use two double-quote characters (""). If the styles parameter does not contain MIS_TEXT, the string is ignored but must still be specified. An empty string ("") should be specified in this instance. To indicate the mnemonic for each item, insert the tilde character (~) in the string preceding the mnemonic character. For MENUITEM statements within a SUBMENU (that is, pull-down menus) text may be split into a second column with an alignment substring. To right-align items insert "\a" in the text where alignment should begin. To left-align a second column of text insert "\t" in the text where alignment should begin. For each SUBMENU the longest item in the second column determines the width of that column. Only one alignment substring should be used in a menu item. cmd (USHORT) The value of the WM_COMMAND, WM_HELP, or WM_SYSCOMMAND message generated by the item when it is selected. It identifies the selection made and should be unique within one menu definition. styles (USHORT) One or more menu options defined by the MIS_* constants, ORed together with the "Or" operator. For definitions of the MIS_* constants, see Menu Item Styles. attributes (USHORT) One or more menu options defined by the MIA_* constants, ORed together with the "Or" operator. For definitions of the MIA_* constants, see Menu Item Attributes. The style MIS_SUBMENU must not be used with this statement. See Submenu Statements for the SUBMENU statement. Examples: Uses Os2Def,Os2Base,Os2PmApi; Var "Alpha", : MENUITEM; (* Сsken var tom!! *) "Beta", : MENUITEM; (* Сsken var tom!! *) Begin "Alpha", := MENUITEM "Beta", := MENUITEM ═══ 21.6.2.4.6.2. Submenu Statements ═══ In addition to simple items, a menu definition can contain the definition of a submenu. A submenu can itself invoke a lower level submenu. ──SUBMENU────────────────────────────────── ────string──,├────├,├──────├─,├──────────├─ └cmd─┘ └styles┘ └attributes┘ ┌─────────────────────┐  │ ┌──PRESPARAMS─statement─├┐ ────BEGIN──├────────────────────────├─────── ┌────────────────────────┐  │ ────────├───MENUITEM─statement───┼──END──── │ │ └───SUBMENU─statement────┘ string (PCH) A string, enclosed in double quotation marks, specifying the text of the menu item. To insert a double-quote character (") in the text, use two double-quote characters (""). If the styles parameter does not contain MIS_TEXT, the string is ignored but must still be specified. An empty string ("") should be specified in this instance. cmd (USHORT) The value of the WM_COMMAND, WM_HELP, or WM_SYSCOMMAND message generated by the item when it is selected. It identifies the selection made and should be unique within one menu definition. styles (USHORT) One or more menu options defined by the MIS_ constants, ORed together with the "Or" operator. In the SUBMENU statement, the style MIS_SUBMENU is always ORed with the styles given. If no value is supplied, the default value of MIS_TEXT and MIS_SUBMENU is used. attributes (USHORT) One or more menu options defined by the MIA_ constants, ORed together with the Or operator. Example: Uses Os2Def,Os2Base,Os2PmApi; Var "chem" : MENU; (* Сsken var tom!! *) Begin "chem" := MENU BEGIN Uses Os2Def,Os2Base,Os2PmApi; Var "&tilde.Elements", : SUBMENU; (* Сsken var tom!! *) Begin "&tilde.Elements", := SUBMENU BEGIN Uses Os2Def,Os2Base,Os2PmApi; Var "&tilde.Oxygen", : MENUITEM; (* Сsken var tom!! *) "&tilde.Carbon", : MENUITEM; (* Сsken var tom!! *) "&tilde.Hydrogen", : MENUITEM; (* Сsken var tom!! *) Begin "&tilde.Oxygen", := MENUITEM "&tilde.Carbon", := MENUITEM "&tilde.Hydrogen", := MENUITEM END Uses Os2Def,Os2Base,Os2PmApi; Var "&tilde.Compounds", : SUBMENU; (* Сsken var tom!! *) Begin "&tilde.Compounds", := SUBMENU BEGIN Uses Os2Def,Os2Base,Os2PmApi; Var "&tilde.Glucose", : MENUITEM; (* Сsken var tom!! *) "&tilde.Sucrose", : MENUITEM; (* Сsken var tom!! *) "&tilde.Lactose", : MENUITEM; (* Сsken var tom!! *) "&tilde.Fructose", : MENUITEM; (* Сsken var tom!! *) Begin "&tilde.Glucose", := MENUITEM "&tilde.Sucrose", := MENUITEM "&tilde.Lactose", := MENUITEM "&tilde.Fructose", := MENUITEM END END ═══ 21.6.2.4.6.3. SEPARATOR Menu Item ═══ There is a special form of the MENUITEM statement that is used to create a horizontal dividing bar between two active menu items in a pull-down menu. The SEPARATOR menu item is itself inactive and has no text associated with it nor a cmd value. Example Uses Os2Def,Os2Base,Os2PmApi; Var "&tilde.Roman", : MENUITEM; (* Сsken var tom!! *) SEPARATOR : MENUITEM; (* Сsken var tom!! *) "20 : MENUITEM; (* Сsken var tom!! *) Begin "&tilde.Roman", := MENUITEM SEPARATOR := MENUITEM "20 := MENUITEM ═══ 21.6.2.4.6.4. Menu Template ═══ Menu templates are data structures used to define menus. Menu templates can be loaded as resources or created dynamically, or embedded in dialog templates, which in turn can be loaded as resources or created dynamically. Templates loaded as resources cannot contain references to bit maps or owner-drawn items. A menu template consists of a sequence of variable-length records. Each record in a menu template defines a menu item. If a menu item contains a reference to a submenu, the menu template that defines that submenu is placed after the definition of that particular menu item. ═══ 21.6.2.4.6.5. Template Format ═══ A menu template has the following format: Length (USHORT) The length of the menu template. Version (USHORT) The template version. Versions 0 and 1 are valid. Code page (USHORT) The identifier of the code page used for the text items within the menu (but not any submenus, which each have their own code pages). Item offset (USHORT) The offset of the items from the start of the template, in bytes. Count (USHORT) The count of menu items. Presentation parameters offset (USHORT) Offset of presentation parameters from the start of the template, in bytes. This field is only present for version 1 of the template. Menu Items A variable-sized array of menu items as follows: Style (USHORT) Menu item styles (MIS_*; see Menu Item Styles) combined with the logical-OR operator. Attributes (USHORT) Menu item attributes (MIA_*; see Menu Item Attributes) combined with the logical-OR operator. Item (USHORT) An application-provided identifier for the menu item. Variable data Following the identifier is a variable data structure whose format depends upon the value of Style: MIS_TEXT Text (PSZ) Null-terminated text string. MIS_SUBMENU A menu template structure. MIS_BITMAP Text (PCH) Null-terminated text string. For MIS_BITMAP menu items, the item text string can be used to derive the resource identifier from which a bit map is loaded. There are three instances:  The first byte is null; that is, no resource is defined and it is assumed that the application subsequently provides a bit-map handle for the item.  The first byte is 0xFF, the second byte is the low byte of the resource identifier, and the third byte is the high byte of the resource identifier.  The first character is "#", and subsequent characters make up the decimal text representation of the resource identifier. The resource is assumed to reside in the resource file of the current process. If the string is empty or does not follow the format above, no resource is loaded. ═══ 21.6.2.4.7. STRINGTABLE Statement ═══ The STRINGTABLE statement defines one or more string resources for an application. String resources are null-terminated ASCII strings that can be loaded, when needed, from the executable file, using the WinLoadString function. Note: The ASCII strings can include no more than 256 characters, including the NULL termination character. The STRINGTABLE statement has the form: ─STRINGTABLE─├────────────├├───────────├─── └─loadoption─┘└─memoption─┘ ────BEGIN───string-definitions───END─── String-definitions ┌─────────────────────────────────┐ │ │  │ ─────integer─────string─────────────├── loadoption (LOADOPTION) An optional keyword specifying when the resource is to be loaded. It must be one of: PRELOAD Resource is loaded immediately. LOADONCALL Resource is loaded when called. The default is LOADONCALL. See Resource Load and Memory Options for a description of LOADOPTION. memoption (MEMOPTION) Consists of the following keyword or keywords, specifying whether the resource is fixed or movable and whether it is discardable: FIXED Resource remains at a fixed memory location. MOVEABLE Resource can be moved if necessary to compact memory. DISCARDABLE Resource can be discarded if no longer needed. The default is MOVEABLE and DISCARDABLE. See Resource Load and Memory Options for a description of MEMOPTION. string (PCH) A string, enclosed in double quotation marks. To insert a double-quote character (") in the text, use two double-quote characters (""). Note: A string may be defined on more than one line if each line begins and ends with a double-quote. If newline characters are desired after each line, there should be a double-quote at the beginning of the first line and at the end of the last line only. The string may contain any ASCII characters. Because (\) is interpreted as an escape character, use (\\) to generate a (\). The following escape sequences may be used: Escape Sequence Name \t Horizontal tab \a Bell (alert) \nnn ASCII character (octal) \xdd ASCII character (hexadecimal). The sequences \ddd and \xdd allow any character in the ASCII character set to be inserted in the character string. Thus, the horizontal tab could be entered as \X09, \011 or \t. Example STRINGTABLE BEGIN IDS_STRING1, "The first two strings in this table are identical." IDS_STRING2, "The first two strings " "in this table are identical." IDS_STRING3, "This string will contain a newline character before it continues on this line." END ═══ 21.6.3. Templates, Control Data, and Presentation Parameters ═══ This section describes:  Dialog Template  Dialog Coordinates  Dialog Template Format and Contents  Header  Items  Data Area  Control Data Statement  Presentation Parameters Statement  Parent/Child/Owner Relationship  Predefined Window Classes  Predefined Control Statements ═══ 21.6.3.1. Dialog Template ═══ A dialog template is a data structure used to define a dialog box. Dialog templates can be loaded from resources or created dynamically in memory. Dialog templates define windows of any window class that contain child windows of any class. For standard dialog windows, the dialog window itself is created with the WC_FRAME class, and its children are any of the preregistered control classes. The dialog template specifies all the information required to create a dialog box and its children. ═══ 21.6.3.2. Dialog Coordinates ═══ Coordinates in a dialog template are specified in dialog coordinates. These are based on the default character cell size; a unit in the horizontal direction is 1/4 the default character-cell width, and a unit in the vertical direction is 1/8 the default character-cell height. The origin is the bottom left-hand corner of the dialog box. ═══ 21.6.3.3. Dialog Template Format and Contents ═══ A dialog template has these sections: Header Defines the type of template format and contains information about the location of the other sections of the template. It also contains a summary of the status of the individual controls contained within the dialog box. Items Defines each of the controls that comprise the dialog box. Data area Contains the data values associated with each control. Each control defined in the item section contains pointers to the data area section. The data area also contains presentation parameter definitions. The data area is not necessarily a contiguous portion of the template. User data can be placed anywhere in the template if it does not interfere with other defined information. The sections of a dialog template are illustrated in the following figure. Notes 1. Throughout the dialog template all lengths are in bytes. String lengths do not include any null terminator that may be present. When strings are passed to the Presentation Interface, the length specifications are used and any null terminators are ignored. When strings are returned by the Presentation Interface, length specifications and null terminators are both supplied; therefore, space must be allowed for a null terminator. 2. All offsets are in bytes from the start of the dialog template structure. ═══ 21.6.3.4. Header ═══ The dialog template header consists of: Template length (USHORT) The overall length of the dialog template. Template type (USHORT) The dialog template format type. The format defined is type 0. Code page (USHORT) The code page of the text in the dialog template. Items offset (USHORT) The offset of the array of dialog items. Reserved (USHORT) Must be 0. Focus item (USHORT) The index in the array of dialog items of the control to receive the focus. If this value is 0, or if the identified control cannot receive the focus, for example because it is a static control, the focus is passed to the first item within the template that can receive the focus. Reserved (USHORT) Must be 0. ═══ 21.6.3.5. Items ═══ The dialog template items are specified as elements of an array that also defines the hierarchy of the control windows of the dialog box. Each element of the array is a control window descriptor and defines some control or a child of some control, so that every control within the dialog box is described by this array. The first descriptor is the specification of the dialog box itself. The dialog template items consist of: Reserved (USHORT) (BOOL16) Must be 0. Children (USHORT) The number of dialog item child windows that are owned by this dialog item. This is the number of elements following in the array that are created as child windows of this window. Each window can have any number of child windows, which allows for a tree-structured arrangement. For example, in the figure in Dialog Template Format and Contents, assuming that there are no more dialog items than are shown, the first item, the dialog box control window descriptor, has three children. The second item has no children, the third item has two children, and the remaining three items have no children. Class name length (USHORT) The length of the window class name string. Class name offset (USHORT) The offset of the window class name string. Text length (USHORT) The length of the text string. For controls that allow input of text, this is the current text length, not the maximum text length, and so this value changes when text is put into the control. Text offset (USHORT) The offset of the text string. Style (ULONG) (BOOL32) The window style of the control. The standard style bits are 16 bits. The use of the remaining 16 bits depends on the class of the control. x (SHORT) y (SHORT) The position of the origin of the dialog item. This is specified in dialog coordinates, with x and y relative to the origin of the parent window. cx (SHORT) cy (SHORT) The size of the dialog item in dialog coordinates; it must be greater than 0. Identifier (USHORT) An application-defined identifier for the dialog item. Reserved (USHORT) Must be zero. Control data offset (USHORT) The offset of the control-specific data for this dialog item. A value of 0 indicates that there is no control data for this dialog item. ═══ 21.6.3.6. Data Area ═══ The dialog template data area contains the following different types of objects: text, class name, presentation parameters, and control data. These objects can be placed anywhere within the data area. They do not have to be in contiguous storage, and so an application can place data for its own use between these objects. The dialog template data area contains: Text (PCH) The textual data associated with a dialog item. Class name (PCH) The name of the window class. Presentation parameters (PRESPARAMS) Presentation parameters are defined in Presentation Parameters Statement. Control data (CTLDATA) For more information, see Control Data Statement. ═══ 21.6.3.7. Control Data Statement ═══ The optional CTLDATA statement is used to define control data for the control. Hexadecimal or decimal word constants follow the CTLDATA statement, separated with commas. ┌────────────,─────────────┐ │ │  │ ──CTLDATA─────├──decimal─value──────├─├─ │ │ ├──hexadecimal─value── │ │ └──string─────────────┘ In addition to hexadecimal or decimal data, the CTLDATA statement can be followed by the MENU keyword, followed by a menu template in a BEGIN/END block. This creates a menu template as the control data of the window. ═══ 21.6.3.8. Presentation Parameters Statement ═══ The optional PRESPARAMS statement is used to define presentation parameters. The syntax of the PRESPARAMS statement is as follows. ┌─────,───┐ │ │  │ ───PRESPARAMS────type───,────────value──├─ A presentation parameter consists of: type (ULONG) The presentation parameter attribute type. See the PARAM data type for a description of valid types. A string can be used to specify the type for a user type. If this is done, the string type is converted into a string atom when the dialog template is read into memory. Thereafter, this presentation parameter is referred to by this string atom. The application can use the atom manager API to match the string and the string atom. value (LONG or PSZ) One or more values depending upon the attribute type. If the value is enclosed in quotes it is a zero-terminated string. Otherwise, it is converted to a LONG. There may be more than one value, depending upon the type. See PARAM data type for a description of the values required for system-defined presentation parameters. Examples The following are examples of PRESPARAMS statements: Uses Os2Def,Os2Base,Os2PmApi; Var PP_BORDERCOLOR, : PRESPARAMS; (* Сsken var tom!! *) PP_FONTNAMESIZE, : PRESPARAMS; (* Сsken var tom!! *) "my : PRESPARAMS; (* Сsken var tom!! *) "my : PRESPARAMS; (* Сsken var tom!! *) Begin PP_BORDERCOLOR, := PRESPARAMS PP_FONTNAMESIZE, := PRESPARAMS "my := PRESPARAMS "my := PRESPARAMS ═══ 21.6.3.9. Parent/Child/Owner Relationship ═══ The format of the DLGTEMPLATE and WINDOWTEMPLATE resources is very general to allow tree-structured relationships within the resource format. The general layout of the templates is: Uses Os2Def,Os2Base,Os2PmApi; Var Id : WINDOWTEMPLATE; (* Сsken var tom!! *) Begin Id := WINDOWTEMPLATE BEGIN Uses Os2Def,Os2Base,Os2PmApi; Var WinTop : WINDOW; (* Сsken var tom!! *) Begin WinTop := WINDOW BEGIN Uses Os2Def,Os2Base,Os2PmApi; Var Wind1 : WINDOW; (* Сsken var tom!! *) Wind2 : WINDOW; (* Сsken var tom!! *) Wind3 : WINDOW; (* Сsken var tom!! *) Begin Wind1 := WINDOW Wind2 := WINDOW Wind3 := WINDOW BEGIN Uses Os2Def,Os2Base,Os2PmApi; Var Wind4 : WINDOW; (* Сsken var tom!! *) Begin Wind4 := WINDOW END Uses Os2Def,Os2Base,Os2PmApi; Var Wind5 : WINDOW; (* Сsken var tom!! *) Begin Wind5 := WINDOW END END In this example, the top-level window is identified by winTop. It has four child windows: wind1, wind2, wind3, and wind5. wind3 has one child window, wind4. When each of these windows is created, the parent and the owner are set to be the same. The only time when the parent and owner windows are not the same is when frame controls are automatically created by a frame window. Note that the WINDOW statements in the example above could also have been CONTROL or DIALOG statements. ═══ 21.6.3.10. Predefined Window Classes ═══ The CONTROL statement can be used to define a window control of any class. Window classes may be user defined of one of a predefined set provided by the operating system. The following classes are provided in the OS/2 operating system. WC_FRAME Application frame control. WC_STATIC Text and group boxes. WC_BUTTON Push button, check box or radio button. WC_COMBOBOX Combination of an entry field and list box. WC_ENTRYFIELD Single line entry field. WC_MLE Multiple line entry field. WC_LISTBOX List box. WC_MENU Application action bar, menus and popup menus. WC_SCROLLBAR Horizontal or vertical scroll bar. WC_TITLEBAR Application title bar. WC_SPINBUTTON Spin button entry field. WC_CONTAINER Container list. WC_SLIDER Horizontal or vertical slider control. WC_VALUESET Value set control. WC_NOTEBOOK Notebook control. These controls make up the standard user interface components for applications. The following example shows a simple listbox control. Uses Os2Def,Os2Base,Os2PmApi; Var "", : CONTROL; (* Сsken var tom!! *) Begin "", := CONTROL ═══ 21.6.3.11. Predefined Control Statements ═══ In addition to the general form of the CONTROL statement, there are special control statements for commonly used controls. These statements define the attributes of the child control windows that appear in the window. Control statements have this general form: ─controltype─text─,─id─,─x─,─y─,─cx─,─cy─── ───├──────────────────├──────────── └──,───style───────┘ ┌─────────────────────────┐  │ ───BEGIN────├──DIALOG statement───├─├─END─── ├──CONTROL statement── └──WINDOW statement───┘ The following six controls are exceptions to this form because they do not take a text field. See the LISTBOX control statement for the form of these six controls.  CONTAINER  LISTBOX  NOTEBOOK  SLIDER  SPINBUTTON  VALUESET controltype is one of the keywords described below, defining the type of the control. text (PCH) is a string specifying the text to be displayed. The string must be enclosed in double quotation marks. The manner in which the text is displayed depends on the particular control, as detailed below. To indicate the mnemonic for each item, insert the tilde character (~) in the string preceding the mnemonic character. The double quotation marks are required for the COMBOBOX title even if no title is used. id (USHORT) is a unique integer number identifying the control. x,y (SHORT) are integer numbers specifying the x- and y-coordinates of the lower left corner of the control, in dialog coordinates. The coordinates are relative to the origin of the dialog. cx,cy (SHORT) are integer numbers specifying the width and height of the control. The x, y, cx, and cy fields can use addition and subtraction operators (+ and -). For example, 15 + 6 can be used for the x-field. Styles can be combined using the (Or) operator. The control type keywords are shown below, with their classes and default styles: AUTOCHECKBOX Class WC_BUTTON Default style WS_TABSTOP, WS_VISIBLE, BS_AUTOCHECKBOX AUTORADIOBUTTON Class WC_BUTTON Default style BS_AUTORADIOBUTTON, WS_TABSTOP, WS_VISIBLE CHECKBOX Class WC_BUTTON Default style BS_CHECKBOX, WS_TABSTOP, WS_VISIBLE COMBOBOX Format The form of the COMBOBOX control statement is shown below. The fields have the same meaning as in the other control statements. ───COMBOBOX──"title"──,──id───,───x───,───y───,───cx─ ───,───cy──├─────────────├── └──,───style──┘ Class WC_COMBOBOX Default style CBS_SIMPLE, WS_TABSTOP, WS_VISIBLE CONTAINER Format The CONTAINER control statement does not contain a text field, so it has the same format as the LISTBOX statement. Class WC_CONTAINER Default style WS_TABSTOP, WS_VISIBLE, CCS_SINGLESEL CTEXT Class WC_STATIC Default style SS_TEXT, DT_CENTER, WS_GROUP, WS_VISIBLE DEFPUSHBUTTON Class WC_BUTTON Default style BS_DEFAULT, BS_PUSHBUTTON, WS_TABSTOP, WS_VISIBLE EDITTEXT Class WC_ENTRYFIELD Default style WS_ENTRYFIELD, WS_TABSTOP, WS_VISIBLE, ES_AUTOSCROLL ENTRYFIELD Class WC_ENTRYFIELD Default style WS_TABSTOP, ES_LEFT, WS_VISIBLE FRAME Class WC_FRAME Default style WS_VISIBLE GROUPBOX Class WC_STATIC Default style SS_GROUPBOX, WS_TABSTOP, WS_VISIBLE ICON Class WC_STATIC Default style SS_ICON, WS_VISIBLE LISTBOX Format The form of the LISTBOX control statement is different from the general form because it does not take a text field, however the fields have the same meaning as in the other control statements. The form of the LISTBOX control statement is shown below. ──controltype───id───,───x───,───y───,───cx── ───,───cy──├─────────────├── └──,───style──┘ Class WC_LISTBOX Default style LBS_NOTIFY, LBS_SORT, WS_VSCROLL, WS_BORDER, WS_VISIBLE LTEXT Class WC_STATIC Default style SS_TEXT, DT_LEFT, WS_GROUP, WS_VISIBLE MLE Class WC_MLE Default style WS_MLE, WS_TABSTOP, WS_VISIBLE, MLS_BORDER NOTEBOOK Format The NOTEBOOK control statement does not contain a text field, so it has the same format as the LISTBOX statement. Class WC_NOTEBOOK Default style WS_NOTEBOOK, WS_TABSTOP, WS_VISIBLE PUSHBUTTON Class WC_BUTTON Default style BS_PUSHBUTTON, WS_TABSTOP, WS_VISIBLE RADIOBUTTON Class WC_BUTTON Default style BS_RADIOBUTTON, WS_TABSTOP, WS_VISIBLE RTEXT Class WC_STATIC Default style SS_TEXT, DT_RIGHT, WS_GROUP, WS_VISIBLE SLIDER Format The SLIDER control statement does not contain a text field, so it has the same format as the LISTBOX statement. Class WC_SLIDER Default style WS_SLIDER, WS_TABSTOP, WS_VISIBLE SPINBUTTON Format The SPINBUTTON control statement does not contain a text field, so it has the same format as the LISTBOX statement. Class WC_SPINBUTTON Default style WS_TABSTOP, WS_VISIBLE, SPBS_MASTER VALUESET Format The VALUESET control statement does not contain a text field, so it has the same format as the LISTBOX statement. Class WC_VALUESET Default style WS_VALUESET, WS_TABSTOP, WS_VISIBLE Examples The following is a complete example of a DIALOG statement: Uses Os2Def,Os2Base,Os2PmApi; Var "errmess" : DLGTEMPLATE; (* Сsken var tom!! *) Begin "errmess" := DLGTEMPLATE BEGIN Uses Os2Def,Os2Base,Os2PmApi; Var "Disk : DIALOG; (* Сsken var tom!! *) Begin "Disk := DIALOG BEGIN Uses Os2Def,Os2Base,Os2PmApi; Var "Select : CTEXT; (* Сsken var tom!! *) "Retry", : RADIOBUTTON; (* Сsken var tom!! *) "Abort", : RADIOBUTTON; (* Сsken var tom!! *) "Ignore", : RADIOBUTTON; (* Сsken var tom!! *) Begin "Select := CTEXT "Retry", := RADIOBUTTON "Abort", := RADIOBUTTON "Ignore", := RADIOBUTTON END END This is an example of a WINDOWTEMPLATE statement that is used to define a specific kind of window frame. Calling Load Dialog with this resource automatically creates the frame window, the frame controls, and the client window (of class MyClientClass). Uses Os2Def,Os2Base,Os2PmApi; Var "wind1" : WINDOWTEMPLATE; (* Сsken var tom!! *) Begin "wind1" := WINDOWTEMPLATE BEGIN Uses Os2Def,Os2Base,Os2PmApi; Var "My : FRAME; (* Сsken var tom!! *) Begin "My := FRAME FCF_STANDARD Or FCF_VERTSCROLL BEGIN Uses Os2Def,Os2Base,Os2PmApi; Var "", : WINDOW; (* Сsken var tom!! *) Begin "", := WINDOW style END END This example creates a resource template for a parallel dialog identified by the constant parallel1. It includes a frame with a title bar, a system menu, and a dialog-style border. The parallel dialog has three auto radio buttons in it. Uses Os2Def,Os2Base,Os2PmApi; Var Parallel1 : DLGTEMPLATE; (* Сsken var tom!! *) Begin Parallel1 := DLGTEMPLATE BEGIN Uses Os2Def,Os2Base,Os2PmApi; Var "Parallel : DIALOG; (* Сsken var tom!! *) FCF_TITLEBAR : CTLDATA; (* Сsken var tom!! *) Begin "Parallel := DIALOG FCF_TITLEBAR := CTLDATA BEGIN Uses Os2Def,Os2Base,Os2PmApi; Var "Retry", : AUTORADIOBUTTON; (* Сsken var tom!! *) "Abort", : AUTORADIOBUTTON; (* Сsken var tom!! *) "Ignore", : AUTORADIOBUTTON; (* Сsken var tom!! *) Begin "Retry", := AUTORADIOBUTTON "Abort", := AUTORADIOBUTTON "Ignore", := AUTORADIOBUTTON END END ═══ 21.6.4. Resource (.RES) File Specification ═══ The format for the .RES file is: (/TYPE NAME FLAGS SIZE BYTES/)+ Where: TYPE is either a null-terminated string or an ordinal, in which instance the first byte is 0xFF followed by an INT that is the ordinal. (* Predefined resource types *) NAME is the same format as TYPE. There are no predefined names. FLAGS is an unsigned value containing the memory manager flags: /* or read-only (data segment) */ (* OR READ-ONLY (DATA SEGMENT) *) SIZE is a LONG value defining how many bytes follow in the resource. BYTES is the stream of bytes that makes up the resource. Any number of resources can appear one after another in the .RES file. ═══ 21.7. Virtual Key Definitions ═══ The PC VKEY set is shown in the following table: ┌───────────────┬───────────────────────┬─────────────────────────┐ │Symbol │Personal Computer AT │Enhanced Keyboard │ │ │Keyboard │ │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_BUTTON1 │These values are only │These values are only │ │VK_BUTTON2 │used to access the │used to access the │ │VK_BUTTON3 │up/down and toggled │up/down and toggled │ │ │states of the pointing │states of the pointing │ │ │device buttons; they │device buttons; they │ │ │never actually appear │never actually appear in │ │ │in a WM_CHAR message. │a WM_CHAR message. │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_BREAK │Ctrl + Scroll Lock │Ctrl + Pause │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_BACKSPACE │Backspace │Backspace │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_TAB │Tab │Tab │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_BACKTAB │Shift + Tab │Shift + Tab │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_NEWLINE │Enter │Enter │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_SHIFT * │Left and Right Shift │Left and Right Shift │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_CTRL * │Ctrl │Left and Right Ctrl │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_ALT * │Alt │Left and Right Alt │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_ALTGRAF * │None │Alt Graf (if available) │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_PAUSE │Ctrl + Num Lock │Pause │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_CAPSLOCK │Caps Lock │Caps Lock │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_ESC │Esc │Esc │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_SPACE * │Space │Space │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_PAGEUP * │Numpad 9 │Pg Up and Numpad 9 │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_PAGEDOWN * │Numpad 3 │Pg Dn and Numpad 3 │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_END * │Numpad 1 │End and Numpad 1 │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_HOME * │Numpad 7 │Home and Numpad 7 │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_LEFT * │Numpad 4 │Left and Numpad 4 │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_UP * │Numpad 8 │Up and Numpad 8 │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_RIGHT * │Numpad 6 │Right and Numpad 6 │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_DOWN * │Numpad 2 │Down and Numpad 2 │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_PRINTSCRN │Shift + Print Screen │Print Screen │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_INSERT * │Numpad 0 │Ins and Numpad 0 │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_DELETE * │Numpad │Del and Numpad │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_SCRLLOCK │Scroll Lock │Scroll Lock │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_NUMLOCK │Num Lock │Num Lock │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_ENTER │Shift + Enter │Shift + Enter and Numpad │ │ │ │Enter │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_SYSRQ │SysRq │Alt + Print Screen │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_F1 * │F1 │F1 │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_F2 * │F2 │F2 │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_F3 * │F3 │F3 │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_F4 * │F4 │F4 │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_F5 * │F5 │F5 │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_F6 * │F6 │F6 │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_F7 * │F7 │F7 │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_F8 * │F8 │F8 │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_F9 * │F9 │F9 │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_F10 * │F10 │F10 │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_F11 * │None │F11 │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_F12 * │None │F12 │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_F13 │None │None │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_F14 │None │None │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_F15 │None │None │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_F16 │None │None │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_F17 │None │None │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_F18 │None │None │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_F19 │None │None │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_F20 │None │None │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_F21 │None │None │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_F22 │None │None │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_F23 │None │None │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_F24 │None │None │ ├───────────────┼───────────────────────┼─────────────────────────┤ │VK_MENU * │F10 │F10 │ └───────────────┴───────────────────────┴─────────────────────────┘ Notes 1. VKEYs marked with an asterisk (*) are generated irrespective of other shift states (Shift, Ctrl, Alt, and Alt Graf). 2. VK_CAPSLOCK is not generated for any of the Ctrl shift states, for PC-DOS compatibility. 3. Wherever possible, the VK_ name is derived from the legend on the key top of the 101-key Enhanced PC keyboard. ═══ 22. Notices ═══ Second Edition (January 1996) The following paragraph does not apply to the United Kingdom or any country where such provisions are inconsistent with local law: INTERNATIONAL BUSINESS MACHINES CORPORATION PROVIDES THIS PUBLICATION "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Some states do not allow disclaimer of express or implied warranties in certain transactions, therefore, this statement may not apply to you. This publication could include technical inaccuracies or typographical errors. Changes are periodically made to the information herein; these changes will be incorporated in new editions of the publication. IBM may make improvements and/or changes in the product(s) and/or the program(s) described in this publication at any time. It is possible that this publication may contain reference to, or information about, IBM products (machines and programs), programming, or services that are not announced in your country. Such references or information must not be construed to mean that IBM intends to announce such IBM products, programming, or services in your country. Requests for technical information about IBM products should be made to your IBM reseller or IBM marketing representative. ═══ 22.1. Copyright Notices ═══ COPYRIGHT LICENSE: This publication contains printed sample application programs in source language, which illustrate OS/2 programming techniques. You may copy, modify, and distribute these sample programs in any form without payment to IBM, for the purposes of developing, using, marketing or distributing application programs conforming to the OS/2 application programming interface. Each copy of any portion of these sample programs or any derivative work, which is distributed to others, must include a copyright notice as follows: "(C) (your company name) (year). All rights reserved." (C) Copyright International Business Machines Corporation 1994, 1996. All rights reserved. Note to U.S. Government Users - Documentation related to restricted rights - Use, duplication or disclosure is subject to restrictions set forth in GSA ADP Schedule Contract with IBM Corp. ═══ 22.2. Disclaimers ═══ References in this publication to IBM products, programs, or services do not imply that IBM intends to make these available in all countries in which IBM operates. Any reference to an IBM product, program, or service is not intended to state or imply that only that IBM product, program, or service may be used. Subject to IBM's valid intellectual property or other legally protectable rights, any functionally equivalent product, program, or service may be used instead of the IBM product, program, or service. The evaluation and verification of operation in conjunction with other products, except those expressly designated by IBM, are the responsibility of the user. IBM may have patents or pending patent applications covering subject matter in this document. The furnishing of this document does not give you any license to these patents. You can send license inquiries, in writing, to: IBM Director of Licensing IBM Corporation 500 Columbus Avenue Thornwood, NY 10594 U.S.A. Licensees of this program who wish to have information about it for the purpose of enabling: (i) the exchange of information between independently created programs and other programs (including this one) and (ii) the mutual use of the information which has been exchanged, should contact IBM Corporation, Department RM1A, 1000 N.W. 51st Street, Boca Raton, FL 33431, U.S.A. Such information may be available, subject to appropriate terms and conditions, including in some cases, payment of a fee. ═══ 22.3. Trademarks ═══ The following terms are trademarks of the IBM Corporation in the United States or other countries or both: Common User Access CUA IBM Information Presentation Facility IPF Operating System/2 OS/2 PM Presentation Manager SAA System Application Architecture Workplace Shell The following terms are trademarks of other companies: Adobe Adobe Systems Incorporated Helvetica Linotype Intel Intel Corporation PostScript Adobe Systems Incorporated Times New Roman Monotype Other company, product, and service names, which may be denoted by a double asterisk (**), may be trademarks or service marks of others. ═══ 23. Glossary ═══ This glossary defines many of the terms used in this book. It includes terms and definitions from the IBM Dictionary of Computing, as well as terms specific to the OS/2 operating system and the Presentation Manager. It is not a complete glossary for the entire OS/2 operating system; nor is it a complete dictionary of computer terms. Other primary sources for these definitions are:  The American National Standard Dictionary for Information Systems, ANSI X3.172-1990, copyrighted 1990 by the American National Standards Institute, 11 West 42nd Street, New York, New York 10036. These definitions are identified by the symbol (A) after the definition.  The Information Technology Vocabulary, developed by Subcommittee 1, Joint Technical Committee 1, of the International Organization for Standardization and the International Electrotechnical Commission (ISO/IEC JTC1/SC1). Definitions of published parts of this vocabulary are identified by the symbol (I) after the definition; definitions taken from draft international standards, committee drafts, and working papers being developed by ISO/IEC JTC1/SC1 are identified by the symbol (T) after the definition, indicating that final agreement has not yet been reached among the participating National Bodies of SC1. ═══ 23.1. Glossary Listing ═══ Select a starting letter of glossary terms: A N B O C P D Q E R F S G T H U I V J W K X L Y M Z ═══ Glossary - A ═══ accelerator -In SAA Common User Access architecture, a key or combination of keys that invokes an application-defined function. accelerator table -A table used to define which key strokes are treated as accelerators and the commands they are translated into. access mode -The manner in which an application gains access to a file it has opened. Examples of access modes are read-only, write-only, and read/write. access permission -All access rights that a user has regarding an object. (I) action -One of a set of defined tasks that a computer performs. Users request the application to perform an action in several ways, such as typing a command, pressing a function key, or selecting the action name from an action bar or menu. action bar -In SAA Common User Access architecture, the area at the top of a window that contains choices that give a user access to actions available in that window. action point -The current position on the screen at which the pointer is pointing. Contrast with hot spot and input focus. active program -A program currently running on the computer. An active program can be interactive (running and receiving input from the user) or noninteractive (running but not receiving input from the user). See also interactive program and noninteractive program. active window -The window with which the user is currently interacting. address space -(1) The range of addresses available to a program. (A) (2) The area of virtual storage available for a particular job. alphanumeric video output -Output to the logical video buffer when the video adapter is in text mode and the logical video buffer is addressed by an application as a rectangular array of character cells. American National Standard Code for Information Interchange -The standard code, using a coded character set consisting of 7-bit coded characters (8 bits including parity check), that is used for information interchange among data processing systems, data communication systems, and associated equipment. The ASCII set consists of control characters and graphic characters. (A) Note: IBM has defined an extension to ASCII code (characters 128-255). anchor -A window procedure that handles Presentation Manager message conversions between an icon procedure and an application. anchor block -An area of Presentation-Manager-internal resources to allocated process or thread that calls WinInitialize. anchor point -A point in a window used by a program designer or by a window manager to position a subsequently appearing window. ANSI -American National Standards Institute. APA -All points addressable. API -Application programming interface. application -A collection of software components used to perform specific types of work on a computer; for example, a payroll application, an airline reservation application, a network application. application object -In SAA Advanced Common User Access architecture, a form that an application provides for a user; for example, a spreadsheet form. Contrast with user object. application programming interface (API) -A functional interface supplied by the operating system or by a separately orderable licensed program that allows an application program written in a high-level language to use specific data or functions of the operating system or the licensed program. application-modal -Pertaining to a message box or dialog box for which processing must be completed before further interaction with any other window owned by the same application may take place. area -In computer graphics, a filled shape such as a solid rectangle. ASCII -American National Standard Code for Information Interchange. ASCIIZ -A string of ASCII characters that is terminated with a byte containing the value 0. aspect ratio -In computer graphics, the width-to-height ratio of an area, symbol, or shape. asynchronous (ASYNC) -(1) Pertaining to two or more processes that do not depend upon the occurrence of specific events such as common timing signals. (T) (2) Without regular time relationship; unexpected or unpredictable with respect to the execution of program instructions. See also synchronous. atom -A constant that represents a string. As soon as a string has been defined as an atom, the atom can be used in place of the string to save space. Strings are associated with their respective atoms in an atom table. See also integer atom. atom table -A table used to relate atoms with the strings that they represent. Also in the table is the mechanism by which the presence of a string can be checked. atomic operation -An operation that completes its work on an object before another operation can be performed on the same object. attribute -A characteristic or property that can be controlled, usually to obtain a required appearance; for example, the color of a line. See also graphics attributes and segment attributes. automatic link -In Information Presentation Facility (IPF), a link that begins a chain reaction at the primary window. When the user selects the primary window, an automatic link is activated to display secondary windows. AVIO -Advanced Video Input/Output. ═══ Glossary - B ═══ BВzier curve -(1) A mathematical technique of specifying smooth continuous lines and surfaces, which require a starting point and a finishing point with several intermediate points that influence or control the path of the linking curve. Named after Dr. P. BВzier. (2) (D of C) In the AIX Graphics Library, a cubic spline approximation to a set of four control points that passes through the first and fourth control points and that has a continuous slope where two spline segments meet. Named after Dr. P. BВzier. background -(1) In multiprogramming, the conditions under which low-priority programs are executed. Contrast with foreground. (2) An active session that is not currently displayed on the screen. background color -The color in which the background of a graphic primitive is drawn. background mix -An attribute that determines how the background of a graphic primitive is combined with the existing color of the graphics presentation space. Contrast with mix. background program -In multiprogramming, a program that executes with a low priority. Contrast with foreground program. bit map -A representation in memory of the data displayed on an APA device, usually the screen. block -(1) A string of data elements recorded or transmitted as a unit. The elements may be characters, words, or logical records. (T) (2) To record data in a block. (3) A collection of contiguous records recorded as a unit. Blocks are separated by interblock gaps and each block may contain one or more records. (A) block device -A storage device that performs I/O operations on blocks of data called sectors. Data on block devices can be randomly accessed. Block devices are designated by a drive letter (for example, C:). blocking mode -A condition set by an application that determines when its threads might block. For example, an application might set the Pipemode parameter for the DosCreateNPipe function so that its threads perform I/O operations to the named pipe block when no data is available. border -A visual indication (for example, a separator line or a background color) of the boundaries of a window. boundary determination -An operation used to compute the size of the smallest rectangle that encloses a graphics object on the screen. breakpoint -(1) A point in a computer program where execution may be halted. A breakpoint is usually at the beginning of an instruction where halts, caused by external intervention, are convenient for resuming execution. (T) (2) A place in a program, specified by a command or a condition, where the system halts execution and gives control to the workstation user or to a specified program. broken pipe -When all of the handles that access one end of a pipe have been closed. bucket -One or more fields in which the result of an operation is kept. buffer -(1) A portion of storage used to hold input or output data temporarily. (2) To allocate and schedule the use of buffers. (A) button -A mechanism used to request or initiate an action. See also barrel buttons, bezel buttons, mouse button, push button, and radio button. byte pipe -Pipes that handle data as byte streams. All unnamed pipes are byte pipes. Named pipes can be byte pipes or message pipes. See byte stream. byte stream -Data that consists of an unbroken stream of bytes. ═══ Glossary - C ═══ cache -A high-speed buffer storage that contains frequently accessed instructions and data; it is used to reduce access time. cached micro presentation space -A presentation space from a Presentation-Manager-owned store of micro presentation spaces. It can be used for drawing to a window only, and must be returned to the store when the task is complete. CAD -Computer-Aided Design. call -(1) The action of bringing a computer program, a routine, or a subroutine into effect, usually by specifying the entry conditions and jumping to an entry point. (I) (A) (2) To transfer control to a procedure, program, routine, or subroutine. calling sequence -A sequence of instructions together with any associated data necessary to execute a call. (T) Cancel -An action that removes the current window or menu without processing it, and returns the previous window. cascaded menu -In the OS/2 operating system, a menu that appears when the arrow to the right of a cascading choice is selected. It contains a set of choices that are related to the cascading choice. Cascaded menus are used to reduce the length of a menu. See also cascading choice. cascading choice -In SAA Common User Access architecture, a choice in a menu that, when selected, produces a cascaded menu containing other choices. An arrow () appears to the right of the cascading choice. CASE statement -In PM programming, provides the body of a window procedure. There is usually one CASE statement for each message type supported by an application. CGA -Color graphics adapter. chained list -A list in which the data elements may be dispersed but in which each data element contains information for locating the next. (T)Synonymous with linked list. character -A letter, digit, or other symbol. character box -In computer graphics, the boundary that defines, in world coordinates, the horizontal and vertical space occupied by a single character from a character set. See also character mode. Contrast with character cell. character cell -The physical, rectangular space in which any single character is displayed on a screen or printer device. Position is addressed by row and column coordinates. Contrast with character box. character code -The means of addressing a character in a character set, sometimes called code point. character device -A device that performs I/O operations on one character at a time. Because character devices view data as a stream of bytes, character-device data cannot be randomly accessed. Character devices include the keyboard, mouse, and printer, and are referred to by name. character mode -A mode that, in conjunction with the font type, determines the extent to which graphics characters are affected by the character box, shear, and angle attributes. character set -(1) An ordered set of unique representations called characters; for example, the 26 letters of English alphabet, Boolean 0 and 1, the set of symbols in the Morse code, and the 128 ASCII characters. (A) (2) All the valid characters for a programming language or for a computer system. (3) A group of characters used for a specific reason; for example, the set of characters a printer can print. check box -In SAA Advanced Common User Access architecture, a square box with associated text that represents a choice. When a user selects a choice, an X appears in the check box to indicate that the choice is in effect. The user can clear the check box by selecting the choice again. Contrast with radio button. check mark - (1) (D of C) In SAA Advanced Common User Access architecture, a symbol that shows that a choice is currently in effect. (2) The symbol that is used to indicate a selected item on a pull-down menu. child process -In the OS/2 operating system, a process started by another process, which is called the parent process. Contrast with parent process. child window -A window that appears within the border of its parent window (either a primary window or another child window). When the parent window is resized, moved, or destroyed, the child window also is resized, moved, or destroyed; however, the child window can be moved or resized independently from the parent window, within the boundaries of the parent window. Contrast with parent window. choice -(1) An option that can be selected. The choice can be presented as text, as a symbol (number or letter), or as an icon (a pictorial symbol). (2) (D of C) In SAA Common User Access architecture, an item that a user can select. chord -(1) To press more than one button on a pointing device while the pointer is within the limits that the user has specified for the operating environment. (2) (D of C) In graphics, a short line segment whose end points lie on a circle. Chords are a means for producing a circular image from straight lines. The higher the number of chords per circle, the smoother the circular image. class -A way of categorizing objects based on their behavior and shape. A class is, in effect, a definition of a generic object. In SOM, a class is a special kind of object that can manufacture other objects that all have a common shape and exhibit similar behavior (more precisely, all of the objects manufactured by a class have the same memory layout and share a common set of methods). New classes can be defined in terms of existing classes through a technique known as inheritance. class method -A class method of class is a method provided by the metaclass of class . Class methods are executed without requiring any instances of class to exist, and are frequently used to create instances. In System Object Model, an action that can be performed on a class object. class object -In System Object Model, the run-time implementation of a class. class style -The set of properties that apply to every window in a window class. client -(1) A functional unit that receives shared services from a server. (T) (2) A user, as in a client process that uses a named pipe or queue that is created and owned by a server process. client area -The part of the window, inside the border, that is below the menu bar. It is the user's work space, where a user types information and selects choices from selection fields. In primary windows, it is where an application programmer presents the objects that a user works on. client program -An application that creates and manipulates instances of classes. client window -The window in which the application displays output and receives input. This window is located inside the frame window, under the window title bar and any menu bar, and within any scroll bars. clip limits -The area of the paper that can be reached by a printer or plotter. clipboard -In SAA Common User Access architecture, an area of computer memory, or storage, that temporarily holds data. Data in the clipboard is available to other applications. clipping -In computer graphics, removing those parts of a display image that lie outside a given boundary. (I) (A) clipping area -The area in which the window can paint. clipping path -A clipping boundary in world-coordinate space. clock tick -The minimum unit of time that the system tracks. If the system timer currently counts at a rate of X Hz, the system tracks the time every 1/X of a second. Also known as time tick. CLOCK$ -Character-device name reserved for the system clock. code page -An assignment of graphic characters and control-function meanings to all code points. code point -(1) Synonym for character code. (2) (D of C) A 1-byte code representing one of 256 potential characters. code segment -An executable section of programming code within a load module. color dithering -See dithering. color graphics adapter (CGA) -An adapter that simultaneously provides four colors and is supported by all IBM Personal Computer and Personal System/2 models. command -The name and parameters associated with an action that a program can perform. command area -An area composed of a command field prompt and a command entry field. command entry field -An entry field in which users type commands. command line -On a display screen, a display line, sometimes at the bottom of the screen, in which only commands can be entered. command mode -A state of a system or device in which the user can enter commands. command prompt -A field prompt showing the location of the command entry field in a panel. Common Programming Interface (CPI) -Definitions of those application development languages and services that have, or are intended to have, implementations on and a high degree of commonality across the SAA environments. One of the three SAA architectural areas. See also Common User Access architecture. Common User Access (CUA) architecture - Guidelines for the dialog between a human and a workstation or terminal. One of the three SAA architectural areas. See also Common Programming Interface. compile -To translate a program written in a higher-level programming language into a machine language program. composite window -A window composed of other windows (such as a frame window, frame-control windows, and a client window) that are kept together as a unit and that interact with each other. computer-aided design (CAD) -The use of a computer to design or change a product, tool, or machine, such as using a computer for drafting or illustrating. COM1, COM2, COM3 -Character-device names reserved for serial ports 1 through 3. CON -Character-device name reserved for the console keyboard and screen. conditional cascaded menu -A pull-down menu associated with a menu item that has a cascade mini-push button beside it in an object's pop-up menu. The conditional cascaded menu is displayed when the user selects the mini-push button. container -In SAA Common User Access architecture, an object that holds other objects. A folder is an example of a container object. See also folder and object. contextual help -In SAA Common User Access Architecture, help that gives specific information about the item the cursor is on. The help is contextual because it provides information about a specific item as it is currently being used. Contrast with extended help. contiguous -Touching or joining at a common edge or boundary, for example, an unbroken consecutive series of storage locations. control -In SAA Advanced Common User Access architecture, a component of the user interface that allows a user to select choices or type information; for example, a check box, an entry field, a radio button. control area -A storage area used by a computer program to hold control information. (I) (A) Control Panel -In the Presentation Manager, a program used to set up user preferences that act globally across the system. Control Program -(1) The basic functions of the operating system, including DOS emulation and the support for keyboard, mouse, and video input/output. (2) A computer program designed to schedule and to supervise the execution of programs of a computer system. (I) (A) control window -A window that is used as part of a composite window to perform simple input and output tasks. Radio buttons and check boxes are examples. control word -An instruction within a document that identifies its parts or indicates how to format the document. coordinate space -A two-dimensional set of points used to generate output on a video display of printer. Copy -A choice that places onto the clipboard, a copy of what the user has selected. See also Cut and Paste. correlation -The action of determining which element or object within a picture is at a given position on the display. This follows a pick operation. coverpage window -A window in which the application's help information is displayed. CPI -Common Programming Interface. critical extended attribute -An extended attribute that is necessary for the correct operation of the system or a particular application. critical section -(1) In programming languages, a part of an asynchronous procedure that cannot be executed simultaneously with a certain part of another asynchronous procedure. (I) Note: Part of the other asynchronous procedure also is a critical section. (2) A section of code that is not reentrant; that is, code that can be executed by only one thread at a time. CUA architecture -Common User Access architecture. current position -In computer graphics, the position, in user coordinates, that becomes the starting point for the next graphics routine, if that routine does not explicitly specify a starting point. cursor -A symbol displayed on the screen and associated with an input device. The cursor indicates where input from the device will be placed. Types of cursors include text cursors, graphics cursors, and selection cursors. Contrast with pointer and input focus. Cut -In SAA Common User Access architecture, a choice that removes a selected object, or a part of an object, to the clipboard, usually compressing the space it occupied in a window. See also Copy and Paste. ═══ Glossary - D ═══ daisy chain -A method of device interconnection for determining interrupt priority by connecting the interrupt sources serially. data segment -A nonexecutable section of a program module; that is, a section of a program that contains data definitions. data structure -The syntactic structure of symbolic expressions and their storage-allocation characteristics. (T) data transfer -The movement of data from one object to another by way of the clipboard or by direct manipulation. DBCS -Double-byte character set. DDE -Dynamic data exchange. deadlock -(1) Unresolved contention for the use of a resource. (2) An error condition in which processing cannot continue because each of two elements of the process is waiting for an action by, or a response from, the other. (3) An impasse that occurs when multiple processes are waiting for the availability of a resource that will not become available because it is being held by another process that is in a similar wait state. debug -To detect, diagnose, and eliminate errors in programs. (T) decipoint -In printing, one tenth of a point. There are 72 points in an inch. default procedure -A function provided by the Presentation Manager Interface that may be used to process standard messages from dialogs or windows. default value -A value assumed when no value has been specified. Synonymous with assumed value. For example, in the graphics programming interface, the default line-type is 'solid'. definition list -A type of list that pairs a term and its description. delta -An application-defined threshold, or number of container items, from either end of the list. descendant -See child process. descriptive text -Text used in addition to a field prompt to give more information about a field. Deselect all -A choice that cancels the selection of all of the objects that have been selected in that window. Desktop Manager -In the Presentation Manager, a window that displays a list of groups of programs, each of which can be started or stopped. desktop window -The window, corresponding to the physical device, against which all other types of windows are established. detached process -A background process that runs independent of the parent process. detent -A point on a slider that represents an exact value to which a user can move the slider arm. device context -A logical description of a data destination such as memory, metafile, display, printer, or plotter. See also direct device context, information device context, memory device context, metafile device context, queued device context, and screen device context. device driver -A file that contains the code needed to attach and use a device such as a display, printer, or plotter. device space -(1) Coordinate space in which graphics are assembled after all GPI transformations have been applied. Device space is defined in device-specific units. (2) ( D of C) In computer graphics, a space defined by the complete set of addressable points of a display device. (A) dialog -The interchange of information between a computer and its user through a sequence of requests by the user and the presentation of responses by the computer. dialog box -In SAA Advanced Common User Access architecture, a movable window, fixed in size, containing controls that a user uses to provide information required by an application so that it can continue to process a user request. See also message box, primary window, secondary window. Also known as a pop-up window. Dialog Box Editor -A WYSIWYG editor that creates dialog boxes for communicating with the application user. dialog item -A component (for example, a menu or a button) of a dialog box. Dialog items are also used when creating dialog templates. dialog procedure -A dialog window that is controlled by a window procedure. It is responsible for responding to all messages sent to the dialog window. dialog tag language -A markup language used by the DTL compiler to create dialog objects. dialog template -The definition of a dialog box, which contains details of its position, appearance, and window ID, and the window ID of each of its child windows. direct device context -A logical description of a data destination that is a device other than the screen (for example, a printer or plotter), and where the output is not to go through the spooler. Its purpose is to satisfy queries. See also device context. direct manipulation -The user's ability to interact with an object by using the mouse, typically by dragging an object around on the Desktop and dropping it on other objects. direct memory access (DMA) -A technique for moving data directly between main storage and peripheral equipment without requiring processing of the data by the processing unit.(T) directory -A type of file containing the names and controlling information for other files or other directories. display point -Synonym for pel. dithering -(1) The process used in color displays whereby every other pel is set to one color, and the intermediate pels are set to another. Together they produce the effect of a third color at normal viewing distances. This process can only be used on solid areas of color; it does not work, for example, on narrow lines. (2) (D of C ) In computer graphics, a technique of interleaving dark and light pixels so that the resulting image looks smoothly shaded when viewed from a distance. DMA -Direct memory access. DOS Protect Mode Interface (DPMI) -An interface between protect mode and real mode programs. double-byte character set (DBCS) -A set of characters in which each character is represented by two bytes. Languages such as Japanese, Chinese, and Korean, which contain more characters than can be represented by 256 code points, require double-byte character sets. Since each character requires two bytes, the entering, displaying, and printing of DBCS characters requires hardware and software that can support DBCS. doubleword -A contiguous sequence of bits or characters that comprises two computer words and is capable of being addressed as a unit. (A) DPMI -DOS Protect Mode Interface. drag -In SAA Common User Access, to use a pointing device to move an object; for example, clicking on a window border, and dragging it to make the window larger. dragging -(1) In computer graphics, moving an object on the display screen as if it were attached to the pointer. (2) (D of C) In computer graphics, moving one or more segments on a display surface by translating. (I) (A) drawing chain -See segment chain. drop -To fix the position of an object that is being dragged, by releasing the select button of the pointing device. See also drag. DTL -Dialog tag language. dual-boot function -A feature of the OS/2 operating system that allows the user to start DOS from within the operating system, or an OS/2 session from within DOS. duplex -Pertaining to communication in which data can be sent and received at the same time. Synonymous with full duplex. dynamic data exchange (DDE) -A message protocol used to communicate between applications that share data. The protocol uses shared memory as the means of exchanging data between applications. dynamic data formatting -A formatting procedure that enables you to incorporate text, bit maps or metafiles in an IPF window at execution time. dynamic link library -A collection of executable programming code and data that is bound to an application at load time or run time, rather than during linking. The programming code and data in a dynamic link library can be shared by several applications simultaneously. dynamic linking -The process of resolving external references in a program module at load time or run time rather than during linking. dynamic segments -Graphics segments drawn in exclusive-OR mix mode so that they can be moved from one screen position to another without affecting the rest of the displayed picture. dynamic storage -(1) A device that stores data in a manner that permits the data to move or vary with time such that the specified data is not always available for recovery. (A) (2) A storage in which the cells require repetitive application of control signals in order to retain stored data. Such repetitive application of the control signals is called a refresh operation. A dynamic storage may use static addressing or sensing circuits. (A) (3) See also static storage. dynamic time slicing -Varies the size of the time slice depending on system load and paging activity. dynamic-link module -A module that is linked at load time or run time. ═══ Glossary - E ═══ EBCDIC -Extended binary-coded decimal interchange code. A coded character set consisting of 8-bit coded characters (9 bits including parity check), used for information interchange among data processing systems, data communications systems, and associated equipment. edge-triggered -Pertaining to an event semaphore that is posted then reset before a waiting thread gets a chance to run. The semaphore is considered to be posted for the rest of that thread's waiting period; the thread does not have to wait for the semaphore to be posted again. EGA -Extended graphics adapter. element -An entry in a graphics segment that comprises one or more graphics orders and that is addressed by the element pointer. EMS -Expanded Memory Specification. encapsulation -Hiding an object's implementation, that is, its private, internal data and methods. Private variables and methods are accessible only to the object that contains them. entry field -In SAA Common User Access architecture, an area where a user types information. Its boundaries are usually indicated. See also selection field. entry panel -A defined panel type containing one or more entry fields and protected information such as headings, prompts, and explanatory text. entry-field control -The component of a user interface that provides the means by which the application receives data entered by the user in an entry field. When it has the input focus, the entry field displays a flashing pointer at the position where the next typed character will go. environment segment -The list of environment variables and their values for a process. environment strings -ASCII text strings that define the value of environment variables. environment variables -Variables that describe the execution environment of a process. These variables are named by the operating system or by the application. Environment variables named by the operating system are PATH, DPATH, INCLUDE, INIT, LIB, PROMPT, and TEMP. The values of environment variables are defined by the user in the CONFIG.SYS file, or by using the SET command at the OS/2 command prompt. error message -An indication that an error has been detected. (A) event semaphore -A semaphore that enables a thread to signal a waiting thread or threads that an event has occurred or that a task has been completed. The waiting threads can then perform an action that is dependent on the completion of the signaled event. exception -An abnormal condition such as an I/O error encountered in processing a data set or a file. exclusive system semaphore -A system semaphore that can be modified only by threads within the same process. executable file -(1) A file that contains programs or commands that perform operations or actions to be taken. (2) A collection of related data records that execute programs. exit -To execute an instruction within a portion of a computer program in order to terminate the execution of that portion. Such portions of computer programs include loops, subroutines, modules, and so on. (T) Repeated exit requests return the user to the point from which all functions provided to the system are accessible. Contrast with cancel. expanded memory specification (EMS) -Enables DOS applications to access memory above the 1MB real mode addressing limit. extended attribute -An additional piece of information about a file object, such as its data format or category. It consists of a name and a value. A file object may have more than one extended attribute associated with it. extended help -In SAA Common User Access architecture, a help action that provides information about the contents of the application window from which a user requested help. Contrast with contextual help. extended-choice selection -A mode that allows the user to select more than one item from a window. Not all windows allow extended choice selection. Contrast with multiple-choice selection. extent -Continuous space on a disk or diskette that is occupied by or reserved for a particular data set, data space, or file. external link -In Information Presentation Facility, a link that connects external online document files. ═══ Glossary - F ═══ family-mode application -An application program that can run in the OS/2 environment and in the DOS environment; however, it cannot take advantage of many of the OS/2-mode facilities, such as multitasking, interprocess communication, and dynamic linking. FAT -File allocation table. FEA -Full extended attribute. field-level help -Information specific to the field on which the cursor is positioned. This help function is "contextual" because it provides information about a specific item as it is currently used; the information is dependent upon the context within the work session. FIFO -First-in-first-out. (A) file -A named set of records stored or processed as a unit. (T) file allocation table (FAT) -In IBM personal computers, a table used by the operating system to allocate space on a disk for a file, and to locate and chain together parts of the file that may be scattered on different sectors so that the file can be used in a random or sequential manner. file attribute -Any of the attributes that describe the characteristics of a file. File Manager -In the Presentation Manager, a program that displays directories and files, and allows various actions on them. file specification -The full identifier for a file, which includes its drive designation, path, file name, and extension. file system -The combination of software and hardware that supports storing information on a storage device. file system driver (FSD) -A program that manages file I\O and controls the format of information on the storage media. fillet -A curve that is tangential to the end points of two adjoining lines. See also polyfillet. filtering -An application process that changes the order of data in a queue. first-in-first-out (FIFO) -A queuing technique in which the next item to be retrieved is the item that has been in the queue for the longest time. (A) flag -(1) An indicator or parameter that shows the setting of a switch. (2) A character that signals the occurrence of some condition, such as the end of a word. (A) (3) (D of C) A characteristic of a file or directory that enables it to be used in certain ways. See also archive flag, hidden flag, and read-only flag. focus -See input focus. folder -A container used to organize objects. font -A particular size and style of typeface that contains definitions of character sets, marker sets, and pattern sets. Font Editor -A utility program provided with the IBM Developers Toolkit that enables the design and creation of new fonts. foreground program -(1) The program with which the user is currently interacting. Also known as interactive program. Contrast with background program. (2) (D of C) In multiprogramming, a high-priority program. frame -The part of a window that can contain several different visual elements specified by the application, but drawn and controlled by the Presentation Manager. The frame encloses the client area. frame styles -Standard window layouts provided by the Presentation Manager. FSD -File system driver. full-duplex -Synonym for duplex. full-screen application -An application that has complete control of the screen. function -(1) In a programming language, a block, with or without formal parameters, whose execution is invoked by means of a call. (2) A set of related control statements that cause one or more programs to be performed. function key -A key that causes a specified sequence of operations to be performed when it is pressed, for example, F1 and Alt-K. function key area -The area at the bottom of a window that contains function key assignments such as F1=Help. ═══ Glossary - G ═══ GDT -Global Descriptor Table. general protection fault -An exception condition that occurs when a process attempts to use storage or a module that has some level of protection assigned to it, such as I/O privilege level. See also IOPL code segment. Global Descriptor Table (GDT) -A table that defines code and data segments available to all tasks in an application. global dynamic-link module -A dynamic-link module that can be shared by all processes in the system that refer to the module name. global file-name character -Either a question mark (?) or an asterisk (*) used as a variable in a file name or file name extension when referring to a particular file or group of files. glyph -A graphic symbol whose appearance conveys information. GPI -Graphics programming interface. graphic primitive -In computer graphics, a basic element, such as an arc or a line, that is not made up of smaller parts and that is used to create diagrams and pictures. See also graphics segment. graphics -(1) A picture defined in terms of graphic primitives and graphics attributes. (2) (D of C) The making of charts and pictures. (3) Pertaining to charts, tables, and their creation. (4) See computer graphics, coordinate graphics, fixed-image graphics, interactive graphics, passive graphics, raster graphics. graphics attributes -Attributes that apply to graphic primitives. Examples are color, line type, and shading-pattern definition. See also segment attributes. graphics field -The clipping boundary that defines the visible part of the presentation-page contents. graphics mode -One of several states of a display. The mode determines the resolution and color content of the screen. graphics model space -The conceptual coordinate space in which a picture is constructed after any model transforms have been applied. Also known as model space. Graphics programming interface -The formally defined programming language that is between an IBM graphics program and the user of the program. graphics segment -A sequence of related graphic primitives and graphics attributes. See also graphic primitive. graying -The indication that a choice on a pull-down is unavailable. group -A collection of logically connected controls. For example, the buttons controlling paper size for a printer could be called a group. See also program group. ═══ Glossary - H ═══ handle -(1) An identifier that represents an object, such as a device or window, to the Presentation Interface. (2) (D of C) In the Advanced DOS and OS/2 operating systems, a binary value created by the system that identifies a drive, directory, and file so that the file can be found and opened. hard error -An error condition on a network that requires either that the system be reconfigured or that the source of the error be removed before the system can resume reliable operation. header -(1) System-defined control information that precedes user data. (2) The portion of a message that contains control information for the message, such as one or more destination fields, name of the originating station, input sequence number, character string indicating the type of message, and priority level for the message. heading tags -A document element that enables information to be displayed in windows, and that controls entries in the contents window controls placement of push buttons in a window, and defines the shape and size of windows. heap -An area of free storage available for dynamic allocation by an application. Its size varies according to the storage requirements of the application. help function -(1) A function that provides information about a specific field, an application panel, or information about the help facility. (2) (D of C) One or more display images that describe how to use application software or how to do a system operation. Help index -In SAA Common User Access architecture, a help action that provides an index of the help information available for an application. help panel -A panel with information to assist users that is displayed in response to a help request from the user. help window -A Common-User-Access-defined secondary window that displays information when the user requests help. hidden file -An operating system file that is not displayed by a directory listing. hide button -In the OS/2 operating system, a small, square button located in the right-hand corner of the title bar of a window that, when selected, removes from the screen all the windows associated with that window. Contrast with maximize button. See also restore button. hierarchical inheritance -The relationship between parent and child classes. An object that is lower in the inheritance hierarchy than another object, inherits all the characteristics and behaviors of the objects above it in the hierarchy. hierarchy -A tree of segments beginning with the root segment and proceeding downward to dependent segment types. high-performance file system (HPFS) -In the OS/2 operating system, an installable file system that uses high-speed buffer storage, known as a cache, to provide fast access to large disk volumes. The file system also supports the coexistence of multiple, active file systems on a single personal computer, with the capability of multiple and different storage devices. File names used with the HPFS can have as many as 254 characters. hit testing -The means of identifying which window is associated with which input device event. hook -A point in a system-defined function where an application can supply additional code that the system processes as though it were part of the function. hook chain -A sequence of hook procedures that are "chained" together so that each event is passed, in turn, to each procedure in the chain. hot spot -The part of the pointer that must touch an object before it can be selected. This is usually the tip of the pointer. Contrast with action point. HPFS -high-performance file system. hypergraphic link -A connection between one piece of information and another through the use of graphics. hypertext -A way of presenting information online with connections between one piece of information and another, called hypertext links. See also hypertext link. hypertext link -A connection between one piece of information and another. ═══ Glossary - I ═══ I/O operation -An input operation to, or output operation from a device attached to a computer. I-beam pointer -A pointer that indicates an area, such as an entry field in which text can be edited. icon -In SAA Advanced Common User Access architecture, a graphical representation of an object, consisting of an image, image background, and a label. Icons can represent items (such as a document file) that the user wants to work on, and actions that the user wants to perform. In the Presentation Manager, icons are used for data objects, system actions, and minimized programs. icon area -In the Presentation Manager, the area at the bottom of the screen that is normally used to display the icons for minimized programs. Icon Editor -The Presentation Manager-provided tool for creating icons. IDL -Interface Definition Language. image font -A set of symbols, each of which is described in a rectangular array of pels. Some of the pels in the array are set to produce the image of one of the symbols. Contrast with outline font. implied metaclass -Subclassing the metaclass of a parent class without a separate CSC for the resultant metaclass. indirect manipulation -Interaction with an object through choices and controls. information device context -A logical description of a data destination other than the screen (for example, a printer or plotter), but where no output will occur. Its purpose is to satisfy queries. See also device context. information panel -A defined panel type characterized by a body containing only protected information. Information Presentation Facility (IPF) -A facility provided by the OS/2 operating system, by which application developers can produce online documentation and context-sensitive online help panels for their applications. inheritance -The technique of specifying the shape and behavior of one class (called a subclass) as incremental differences from another class (called the parent class or superclass). The subclass inherits the superclass' state representation and methods, and can provide additional data elements and methods. The subclass also can provide new functions with the same method names used by the superclass. Such a subclass method is said to override the superclass method, and will be selected automatically by method resolution on subclass instances. An overriding method can elect to call upon the superclass' method as part of its own implementation. input focus -(1) The area of a window where user interaction is possible using an input device, such as a mouse or the keyboard. (2) The position in the active window where a user's normal interaction with the keyboard will appear. input router -An internal OS/2 process that removes messages from the system queue. input/output control -A device-specific command that requests a function of a device driver. installable file system (IFS) -A file system in which software is installed when the operating system is started. instance -(Or object instance). A specific object, as distinguished from the abstract definition of an object referred to as its class. instance method -A method valid for a particular object. instruction pointer -In System/38, a pointer that provides addressability for a machine interface instruction in a program. integer atom -An atom that represents a predefined system constant and carries no storage overhead. For example, names of window classes provided by Presentation Manager are expressed as integer atoms. interactive graphics -Graphics that can be moved or manipulated by a user at a terminal. interactive program -(1) A program that is running (active) and is ready to receive (or is receiving) input from a user. (2) A running program that can receive input from the keyboard or another input device. Compare with active program and contrast with noninteractive program. Also known as a foreground program. interchange file -A file containing data that can be sent from one Presentation Manager interface application to another. Interface Definition Language (IDL) -Language-neutral interface specification for a SOM class. interpreter -A program that translates and executes each instruction of a high-level programming language before it translates and executes. interprocess communication (IPC) -In the OS/2 operating system, the exchange of information between processes or threads through semaphores, pipes, queues, and shared memory. interval timer -(1) A timer that provides program interruptions on a program-controlled basis. (2) An electronic counter that counts intervals of time under program control. IOCtl -Input/output control. IOPL -Input/output privilege level. IOPL code segment -An IOPL executable section of programming code that enables an application to directly manipulate hardware interrupts and ports without replacing the device driver. See also privilege level. IPC -Interprocess communication. IPF -Information Presentation Facility. IPF compiler -A text compiler that interpret tags in a source file and converts the information into the specified format. IPF tag language -A markup language that provides the instructions for displaying online information. item -A data object that can be passed in a DDE transaction. ═══ Glossary - J ═══ journal -A special-purpose file that is used to record changes made in the system. ═══ Glossary - K ═══ Kanji -A graphic character set used in Japanese ideographic alphabets. KBD$ -Character-device name reserved for the keyboard. kernel -The part of an operating system that performs basic functions, such as allocating hardware resources. kerning -The design of graphics characters so that their character boxes overlap. Used to space text proportionally. keyboard accelerator -A keystroke that generates a command message for an application. keyboard augmentation -A function that enables a user to press a keyboard key while pressing a mouse button. keyboard focus -A temporary attribute of a window. The window that has a keyboard focus receives all keyboard input until the focus changes to a different window. Keys help -In SAA Common User Access architecture, a help action that provides a listing of the application keys and their assigned functions. ═══ Glossary - L ═══ label -In a graphics segment, an identifier of one or more elements that is used when editing the segment. LAN -Local area network. language support procedure -A function provided by the Presentation Manager Interface for applications that do not, or cannot (as in the case of COBOL and FORTRAN programs), provide their own dialog or window procedures. lazy drag -See pickup and drop. lazy drag set -See pickup set. LDT -In the OS/2 operating system, Local Descriptor Table. LIFO stack -A stack from which data is retrieved in last-in, first-out order. linear address -A unique value that identifies the memory object. linked list -Synonym for chained list. list box -In SAA Advanced Common User Access architecture, a control that contains scrollable choices from which a user can select one choice. Note: In CUA architecture, this is a programmer term. The end user term is selection list. list button -A button labeled with an underlined down-arrow that presents a list of valid objects or choices that can be selected for that field. list panel -A defined panel type that displays a list of items from which users can select one or more choices and then specify one or more actions to work on those choices. load time -The point in time at which a program module is loaded into main storage for execution. load-on-call -A function of a linkage editor that allows selected segments of the module to be disk resident while other segments are executing. Disk resident segments are loaded for execution and given control when any entry point that they contain is called. local area network (LAN) -(1) A computer network located on a user's premises within a limited geographical area. Communication within a local area network is not subject to external regulations; however, communication across the LAN boundary may be subject to some form of regulation. (T) Note: A LAN does not use store and forward techniques. (2) A network in which a set of devices are connected to one another for communication and that can be connected to a larger network. Local Descriptor Table (LDT) -Defines code and data segments specific to a single task. lock -A serialization mechanism by means of which a resource is restricted for use by the holder of the lock. logical storage device -A device that the user can map to a physical (actual) device. LPT1, LPT2, LPT3 -Character-device names reserved for parallel printers 1 through 3. ═══ Glossary - M ═══ main window -The window that is positioned relative to the desktop window. manipulation button -The button on a pointing device a user presses to directly manipulate an object. map -(1) A set of values having a defined correspondence with the quantities or values of another set. (I) (A) (2) To establish a set of values having a defined correspondence with the quantities or values of another set. (I) marker box -In computer graphics, the boundary that defines, in world coordinates, the horizontal and vertical space occupied by a single marker from a marker set. marker symbol -A symbol centered on a point. Graphs and charts can use marker symbols to indicate the plotted points. marquee box -The rectangle that appears during a selection technique in which a user selects objects by drawing a box around them with a pointing device. Master Help Index -In the OS/2 operating system, an alphabetic list of help topics related to using the operating system. maximize -To enlarge a window to its largest possible size. media window -The part of the physical device (display, printer, or plotter) on which a picture is presented. memory block -Part memory within a heap. memory device context -A logical description of a data destination that is a memory bit map. See also device context. memory management -A feature of the operating system for allocating, sharing, and freeing main storage. memory object -Logical unit of memory requested by an application, which forms the granular unit of memory manipulation from the application viewpoint. menu -In SAA Advanced Common User Access architecture, an extension of the menu bar that displays a list of choices available for a selected choice in the menu bar. After a user selects a choice in menu bar, the corresponding menu appears. Additional pop-up windows can appear from menu choices. menu bar -In SAA Advanced Common User Access architecture, the area near the top of a window, below the title bar and above the rest of the window, that contains choices that provide access to other menus. menu button -The button on a pointing device that a user presses to view a pop-up menu associated with an object. message -(1) In the Presentation Manager, a packet of data used for communication between the Presentation Manager interface and Presentation Manager applications (2) In a user interface, information not requested by users but presented to users by the computer in response to a user action or internal process. message box -(1) A dialog window predefined by the system and used as a simple interface for applications, without the necessity of creating dialog-template resources or dialog procedures. (2) (D of C) In SAA Advanced Common User Access architecture, a type of window that shows messages to users. See also dialog box, primary window, secondary window. message filter -The means of selecting which messages from a specific window will be handled by the application. message queue -A sequenced collection of messages to be read by the application. message stream mode -A method of operation in which data is treated as a stream of messages. Contrast with byte stream. metacharacter -See global file-name character. metaclass -A class whose instances are all classes. In SOM, any class descended from SOMClass is a metaclass. The methods of a metaclass are sometimes called "class" methods. metafile -A file containing a series of attributes that set color, shape and size, usually of a picture or a drawing. Using a program that can interpret these attributes, a user can view the assembled image. metafile device context -A logical description of a data destination that is a metafile, which is used for graphics interchange. See also device context. metalanguage -A language used to specify another language. For example, data types can be described using a metalanguage so as to make the descriptions independent of any one computer language. method -One of the units that makes up the behavior of an object. A method is a combination of a function and a name, such that many different functions can have the same name. Which function the name refers to at any point in time depends on the object that is to execute the method and is the subject of method resolution. method override -The replacement, by a child class, of the implementation of a method inherited from a parent and an ancestor class. mickey -A unit of measurement for physical mouse motion whose value depends on the mouse device driver currently loaded. micro presentation space -A graphics presentation space in which a restricted set of the GPI function calls is available. minimize -To remove from the screen all windows associated with an application and replace them with an icon that represents the application. mix -An attribute that determines how the foreground of a graphic primitive is combined with the existing color of graphics output. Also known as foreground mix. Contrast with background mix. mixed character string -A string containing a mixture of one-byte and Kanji or Hangeul (two-byte) characters. mnemonic -(1) A method of selecting an item on a pull-down by means of typing the highlighted letter in the menu item. (2) (D of C) In SAA Advanced Common User Access architecture, usually a single character, within the text of a choice, identified by an underscore beneath the character. If all characters in a choice already serve as mnemonics for other choices, another character, placed in parentheses immediately following the choice, can be used. When a user types the mnemonic for a choice, the choice is either selected or the cursor is moved to that choice. modal dialog box -In SAA Advanced Common User Access architecture, a type of movable window, fixed in size, that requires a user to enter information before continuing to work in the application window from which it was displayed. Contrast with modeless dialog box. Also known as a serial dialog box. Contrast with parallel dialog box. Note: In CUA architecture, this is a programmer term. The end user term is pop-up window. model space -See graphics model space. modeless dialog box -In SAA Advanced Common User Access architecture, a type of movable window, fixed in size, that allows users to continue their dialog with the application without entering information in the dialog box. Also known as a parallel dialog box. Contrast with modal dialog box. Note: In CUA architecture, this is a programmer term. The end user term is pop-up window. module definition file -A file that describes the code segments within a load module. For example, it indicates whether a code segment is loadable before module execution begins (preload), or loadable only when referred to at run time (load-on-call). mouse -In SAA usage, a device that a user moves on a flat surface to position a pointer on the screen. It allows a user to select a choice o function to be performed or to perform operations on the screen, such as dragging or drawing lines from one position to another. MOUSE$ -Character-device name reserved for a mouse. multiple-choice selection -In SAA Basic Common User Access architecture, a type of field from which a user can select one or more choices or select none. See also check box. Contrast with extended-choice selection. multiple-line entry field -In SAA Advanced Common User Access architecture, a control into which a user types more than one line of information. See also single-line entry field. multitasking -The concurrent processing of applications or parts of applications. A running application and its data are protected from other concurrently running applications. mutex semaphore -(Mutual exclusion semaphore). A semaphore that enables threads to serialize their access to resources. Only the thread that currently owns the mutex semaphore can gain access to the resource, thus preventing one thread from interrupting operations being performed by another. muxwait semaphore -(Multiple wait semaphore). A semaphore that enables a thread to wait either for multiple event semaphores to be posted or for multiple mutex semaphores to be released. Alternatively, a muxwait semaphore can be set to enable a thread to wait for any ONE of the event or mutex semaphores in the muxwait semaphore's list to be posted or released. ═══ Glossary - N ═══ named pipe -A named buffer that provides client-to-server, server-to-client, or full duplex communication between unrelated processes. Contrast with unnamed pipe. national language support (NLS) -The modification or conversion of a United States English product to conform to the requirements of another language or country. This can include the enabling or retrofitting of a product and the translation of nomenclature, MRI, or documentation of a product. nested list -A list that is contained within another list. NLS -national language support. non-8.3 file-name format -A file-naming convention in which file names can consist of up to 255 characters. See also 8.3 file-name format. noncritical extended attribute -An extended attribute that is not necessary for the function of an application. nondestructive read -Reading that does not erase the data in the source location. (T) noninteractive program -A running program that cannot receive input from the keyboard or other input device. Compare with active program, and contrast with interactive program. nonretained graphics -Graphic primitives that are not remembered by the Presentation Manager interface when they have been drawn. Contrast with retained graphics. null character (NUL) -(1) Character-device name reserved for a nonexistent (dummy) device. (2) (D of C) A control character that is used to accomplish media-fill or time-fill and that may be inserted into or removed from a sequence of characters without affecting the meaning of the sequence; however, the control of equipment or the format may be affected by this character. (I) (A) null-terminated string -A string of (n+1) characters where the (n+1)th character is the 'null' character ($00) Also known as 'zero-terminated' string and 'ASCIIZ' string. ═══ Glossary - O ═══ object -The elements of data and function that programs create, manipulate, pass as arguments, and so forth. An object is a way of associating specific data values with a specific set of named functions (called methods) for a period of time (referred to as the lifetime of the object). The data values of an object are referred to as its state. In SOM, objects are created by other objects called classes. The specification of what comprises the set of functions and data elements that make up an object is referred to as the definition of a class. SOM objects offer a high degree of encapsulation. This property permits many aspects of the implementation of an object to change without affecting client programs that depend on the object's behavior. object definition -See class. object instance -See instance. Object Interface Definition Language (OIDL) -Specification language used in SOM Version 1 for defining classes. Replaced by Interface Definition Language (IDL). object window -A window that does not have a parent but which might have child windows. An object window cannot be presented on a device. OIDL -Object Interface Definition Language. open -To start working with a file, directory, or other object. ordered list -Vertical arrangements of items, with each item in the list preceded by a number or letter. outline font -A set of symbols, each of which is created as a series of lines and curves. Synonymous with vector font. Contrast with image font. output area -An area of storage reserved for output. (A) owner window -A window into which specific events that occur in another (owned) window are reported. ownership -The determination of how windows communicate using messages. owning process -The process that owns the resources that might be shared with other processes. ═══ Glossary - P ═══ page -(1) A 4KB segment of contiguous physical memory. (2) (D of C) A defined unit of space on a storage medium. page viewport -A boundary in device coordinates that defines the area of the output device in which graphics are to be displayed. The presentation-page contents are transformed automatically to the page viewport in device space. paint -(1) The action of drawing or redrawing the contents of a window. (2) In computer graphics, to shade an area of a display image; for example, with crosshatching or color. panel -In SAA Basic Common User Access architecture, a particular arrangement of information that is presented in a window or pop-up. If some of the information is not visible, a user can scroll through the information. panel area -An area within a panel that contains related information. The three major Common User Access-defined panel areas are the action bar, the function key area, and the panel body. panel area separator -In SAA Basic Common User Access architecture, a solid, dashed, or blank line that provides a visual distinction between two adjacent areas of a panel. panel body -The portion of a panel not occupied by the action bar, function key area, title or scroll bars. The panel body can contain protected information, selection fields, and entry fields. The layout and content of the panel body determine the panel type. panel body area -See client area. panel definition -A description of the contents and characteristics of a panel. A panel definition is the application developer's mechanism for predefining the format to be presented to users in a window. panel ID -In SAA Basic Common User Access architecture, a panel identifier, located in the upper-left corner of a panel. A user can choose whether to display the panel ID. panel title -In SAA Basic Common User Access architecture, a particular arrangement of information that is presented in a window or pop-up. If some of the information is not visible, a user can scroll through the information. paper size -The size of paper, defined in either standard U.S. or European names (for example, A, B, A4), and measured in inches or millimeters respectively. parallel dialog box -See modeless dialog box. parameter list -A list of values that provides a means of associating addressability of data defined in a called program with data in the calling program. It contains parameter names and the order in which they are to be associated in the calling and called program. parent class -See inheritance. parent process -In the OS/2 operating system, a process that creates other processes. Contrast with child process. parent window -In the OS/2 operating system, a window that creates a child window. The child window is drawn within the parent window. If the parent window is moved, resized, or destroyed, the child window also will be moved, resized, or destroyed. However, the child window can be moved and resized independently from the parent window, within the boundaries of the parent window. Contrast with child window. partition -(1) A fixed-size division of storage. (2) On an IBM personal computer fixed disk, one of four possible storage areas of variable size; one may be accessed by DOS, and each of the others may be assigned to another operating system. Paste -A choice in the Edit pull-down that a user selects to move the contents of the clipboard into a preselected location. See also Copy and Cut. path -The route used to locate files; the storage location of a file. A fully qualified path lists the drive identifier, directory name, subdirectory name (if any), and file name with the associated extension. PDD -Physical device driver. peeking -An action taken by any thread in the process that owns the queue to examine queue elements without removing them. pel -(1) The smallest area of a display screen capable of being addressed and switched between visible and invisible states. Synonym for display point, pixel, and picture element. (2) (D of C) Picture element. persistent object -An object whose instance data and state are preserved between system shutdown and system startup. physical device driver (PDD) -A system interface that handles hardware interrupts and supports a set of input and output functions. pick -To select part of a displayed object using the pointer. pickup -To add an object or set of objects to the pickup set. pickup and drop -A drag operation that does not require the direct manipulation button to be pressed for the duration of the drag. pickup set -The set of objects that have been picked up as part of a pickup and drop operation. picture chain -See segment chain. picture element -(1) Synonym for pel. (2) (D of C) In computer graphics, the smallest element of a display surface that can be independently assigned color and intensity. (T) . (3) The area of the finest detail that can be reproduced effectively on the recording medium. PID -Process identification. pipe -(1) A named or unnamed buffer used to pass data between processes. A process reads from or writes to a pipe as if the pipe were a standard-input or standard-output file. See also named pipe and unnamed pipe. (2) (D of C) To direct data so that the output from one process becomes the input to another process. The standard output of one command can be connected to the standard input of another with the pipe operator (Or). pixel -(1) Synonym for pel. (2) (D of C) Picture element. plotter -An output unit that directly produces a hardcopy record of data on a removable medium, in the form of a two-dimensional graphic representation. (T) PM -Presentation Manager. pointer -(1) The symbol displayed on the screen that is moved by a pointing device, such as a mouse. The pointer is used to point at items that users can select. Contrast with cursor. (2) A data element that indicates the location of another data element. (T) POINTER$ -Character-device name reserved for a pointer device (mouse screen support). pointing device -In SAA Advanced Common User Access architecture, an instrument, such as a mouse, trackball, or joystick, used to move a pointer on the screen. pointings -Pairs of x-y coordinates produced by an operator defining positions on a screen with a pointing device, such as a mouse. polyfillet -A curve based on a sequence of lines. The curve is tangential to the end points of the first and last lines, and tangential also to the midpoints of all other lines. See also fillet. polygon -One or more closed figures that can be drawn filled, outlined, or filled and outlined. polyline -A sequence of adjoining lines. polymorphism -The ability to have different implementations of the same method for two or more classes of objects. pop -To retrieve an item from a last-in-first-out stack of items. Contrast with push. pop-up menu -A menu that lists the actions that a user can perform on an object. The contents of the pop-up menu can vary depending on the context, or state, of the object. pop-up window -(1) A window that appears on top of another window in a dialog. Each pop-up window must be completed before returning to the underlying window. (2) (D of C) In SAA Advanced Common User Access architecture, a movable window, fixed in size, in which a user provides information required by an application so that it can continue to process a user request. presentation drivers -Special purpose I/O routines that handle field device-independent I/O requests from the PM and its applications. Presentation Manager (PM) -The interface of the OS/2 operating system that presents, in windows a graphics-based interface to applications and files installed and running under the OS/2 operating system. presentation page -The coordinate space in which a picture is assembled for display. presentation space (PS) -(1) Contains the device-independent definition of a picture. (2) (D of C) The display space on a display device. primary window -In SAA Common User Access architecture, the window in which the main interaction between the user and the application takes place. In a multiprogramming environment, each application starts in its own primary window. The primary window remains for the duration of the application, although the panel displayed will change as the user's dialog moves forward. See also secondary window. primitive -In computer graphics, one of several simple functions for drawing on the screen, including, for example, the rectangle, line, ellipse, polygon, and so on. primitive attribute -A specifiable characteristic of a graphic primitive. See graphics attributes. print job -The result of sending a document or picture to be printed. Print Manager -In the Presentation Manager, the part of the spooler that manages the spooling process. It also allows users to view print queues and to manipulate print jobs. privilege level -A protection level imposed by the hardware architecture of the IBM personal computer. There are four privilege levels (number 0 through 3). Only certain types of programs are allowed to execute at each privilege level. See also IOPL code segment. procedure call -In programming languages, a language construct for invoking execution of a procedure. process -An instance of an executing application and the resources it is using. program -A sequence of instructions that a computer can interpret and execute. program details -Information about a program that is specified in the Program Manager window and is used when the program is started. program group -In the Presentation Manager, several programs that can be acted upon as a single entity. program name -The full file specification of a program. Contrast with program title. program title -The name of a program as it is listed in the Program Manager window. Contrast with program name. prompt -A displayed symbol or message that requests input from the user or gives operational information; for example, on the display screen of an IBM personal computer, the DOS A> prompt. The user must respond to the prompt in order to proceed. protect mode -A method of program operation that limits or prevents access to certain instructions or areas of storage. Contrast with real mode. protocol -A set of semantic and syntactic rules that determines the behavior of functional units in achieving communication. (I) pseudocode -An artificial language used to describe computer program algorithms without using the syntax of any particular programming language. (A) pull-down -(1) An action bar extension that displays a list of choices available for a selected action bar choice. After users select an action bar choice, the pull-down appears with the list of choices. Additional pop-up windows may appear from pull-down choices to further extend the actions available to users. (2) (D of C) In SAA Common User Access architecture, pertaining to a choice in an action bar pull-down. push -To add an item to a last-in-first-out stack of items. Contrast with pop. push button -In SAA Advanced Common User Access architecture, a rectangle with text inside. Push buttons are used in windows for actions that occur immediately when the push button is selected. putback -To remove an object or set of objects from the lazy drag set. This has the effect of undoing the pickup operation for those objects putdown -To drop the objects in the lazy drag set on the target object. ═══ Glossary - Q ═══ queue -(1) A linked list of elements waiting to be processed in FIFO order. For example, a queue may be a list of print jobs waiting to be printed. (2) (D of C) A line or list of items waiting to be processed; for example, work to be performed or messages to be displayed. queued device context -A logical description of a data destination (for example, a printer or plotter) where the output is to go through the spooler. See also device context. ═══ Glossary - R ═══ radio button -(1) A control window, shaped like a round button on the screen, that can be in a checked or unchecked state. It is used to select a single item from a list. Contrast with check box. (2) In SAA Advanced Common User Access architecture, a circle with text beside it. Radio buttons are combined to show a user a fixed set of choices from which only one can be selected. The circle is partially filled when a choice is selected. RAS -Reliability, availability, and serviceability. raster -(1) In computer graphics, a predetermined pattern of lines that provides uniform coverage of a display space. (T) (2) The coordinate grid that divides the display area of a display device. (A) read-only file -A file that can be read from but not written to. real mode -A method of program operation that does not limit or prevent access to any instructions or areas of storage. The operating system loads the entire program into storage and gives the program access to all system resources. Contrast with protect mode. realize -To cause the system to ensure, wherever possible, that the physical color table of a device is set to the closest possible match in the logical color table. recursive routine -A routine that can call itself, or be called by another routine that was called by the recursive routine. reentrant -The attribute of a program or routine that allows the same copy of the program or routine to be used concurrently by two or more tasks. reference phrase -(1) A word or phrase that is emphasized in a device-dependent manner to inform the user that additional information for the word or phrase is available. (2) (D of C) In hypertext, text that is highlighted and preceded by a single-character input field used to signify the existence of a hypertext link. reference phrase help -In SAA Common User Access architecture, highlighted words or phrases within help information that a user selects to get additional information. refresh -To update a window, with changed information, to its current status. region -A clipping boundary in device space. register -A part of internal storage having a specified storage capacity and usually intended for a specific purpose. (T) remote file system -A file-system driver that gains access to a remote system without a block device driver. resource -The means of providing extra information used in the definition of a window. A resource can contain definitions of fonts, templates, accelerators, and mnemonics; the definitions are held in a resource file. resource file -A file containing information used in the definition of a window. Definitions can be of fonts, templates, accelerators, and mnemonics. restore -To return a window to its original size or position following a sizing or moving action. retained graphics -Graphic primitives that are remembered by the Presentation Manager interface after they have been drawn. Contrast with nonretained graphics. return code -(1) A value returned to a program to indicate the results of an operation requested by that program. (2) A code used to influence the execution of succeeding instructions.(A) reverse video -(1) A form of highlighting a character, field, or cursor by reversing the color of the character, field, or cursor with its background; for example, changing a red character on a black background to a black character on a red background. (2) In SAA Basic Common User Access architecture, a screen emphasis feature that interchanges the foreground and background colors of an item. REXX Language -Restructured Extended Executor. A procedural language that provides batch language functions along with structured programming constructs such as loops; conditional testing and subroutines. RGB -(1) Color coding in which the brightness of the additive primary colors of light, red, green, and blue, are specified as three distinct values of white light. (2) Pertaining to a color display that accepts signals representing red, green, and blue. roman -Relating to a type style with upright characters. root segment -In a hierarchical database, the highest segment in the tree structure. round-robin scheduling -A process that allows each thread to run for a specified amount of time. run time -(1) Any instant at which the execution of a particular computer program takes place. (T) (2) The amount of time needed for the execution of a particular computer program. (T) (3) The time during which an instruction in an instruction register is decoded and performed. Synonym for execution time. ═══ Glossary - S ═══ SAA -Systems Application Architecture. SBCS -Single-byte character set. scheduler -A computer program designed to perform functions such as scheduling, initiation, and termination of jobs. screen -In SAA Basic Common User Access architecture, the physical surface of a display device upon which information is shown to a user. screen device context -A logical description of a data destination that is a particular window on the screen. See also device context. SCREEN$ -Character-device name reserved for the display screen. scroll bar -In SAA Advanced Common User Access architecture, a part of a window, associated with a scrollable area, that a user interacts with to see information that is not currently allows visible. scrollable entry field -An entry field larger than the visible field. scrollable selection field -A selection field that contains more choices than are visible. scrolling -Moving a display image vertically or horizontally in a manner such that new data appears at one edge, as existing data disappears at the opposite edge. secondary window -A window that contains information that is dependent on information in a primary window and is used to supplement the interaction in the primary window. sector -On disk or diskette storage, an addressable subdivision of a track used to record one block of a program or data. segment -See graphics segment. segment attributes -Attributes that apply to the segment as an entity, as opposed to the individual primitives within the segment. For example, the visibility or detectability of a segment. segment chain -All segments in a graphics presentation space that are defined with the 'chained' attribute. Synonym for picture chain. segment priority -The order in which segments are drawn. segment store -An area in a normal graphics presentation space where retained graphics segments are stored. select -To mark or choose an item. Note that select means to mark or type in a choice on the screen; enter means to send all selected choices to the computer for processing. select button -The button on a pointing device, such as a mouse, that is pressed to select a menu choice. Also known as button 1. selection cursor -In SAA Advanced Common User Access architecture, a visual indication that a user has selected a choice. It is represented by outlining the choice with a dotted box. See also text cursor. selection field -(1) In SAA Advanced Common User Access architecture, a set of related choices. See also entry field. (2) In SAA Basic Common User Access architecture, an area of a panel that cannot be scrolled and contains a fixed number of choices. semantics -The relationships between symbols and their meanings. semaphore -An object used by applications for signalling purposes and for controlling access to serially reusable resources. separator -In SAA Advanced Common User Access architecture, a line or color boundary that provides a visual distinction between two adjacent areas. serial dialog box -See modal dialog box. serialization -The consecutive ordering of items. serialize -To ensure that one or more events occur in a specified sequence. serially reusable resource (SRR) -A logical resource or object that can be accessed by only one task at a time. session -(1) A routing mechanism for user interaction via the console; a complete environment that determines how an application runs and how users interact with the application. OS/2 can manage more than one session at a time, and more than one process can run in a session. Each session has its own set of environment variables that determine where OS/2 looks for dynamic-link libraries and other important files. (2) (D of C) In the OS/2 operating system, one instance of a started program or command prompt. Each session is separate from all other sessions that might be running on the computer. The operating system is responsible for coordinating the resources that each session uses, such as computer memory, allocation of processor time, and windows on the screen. Settings Notebook -A control window that is used to display the settings for an object and to enable the user to change them. shadow -An object that refers to another object. A shadow is not a copy of another object, but is another representation of the object. shadow box -The area on the screen that follows mouse movements and shows what shape the window will take if the mouse button is released. shared data -Data that is used by two or more programs. shared memory -In the OS/2 operating system, a segment that can be used by more than one program. shear -In computer graphics, the forward or backward slant of a graphics symbol or string of such symbols relative to a line perpendicular to the baseline of the symbol. shell -(1) A software interface between a user and the operating system of a computer. Shell programs interpret commands and user interactions on devices such as keyboards, pointing devices, and touch-sensitive screens, and communicate them to the operating system. (2) Software that allows a kernel program to run under different operating-system environments. shutdown -The process of ending operation of a system or a subsystem, following a defined procedure. sibling processes -Child processes that have the same parent process. sibling windows -Child windows that have the same parent window. simple list -A list of like values; for example, a list of user names. Contrast with mixed list. single-byte character set (SBCS) -A character set in which each character is represented by a one-byte code. Contrast with double-byte character set. slider box -In SAA Advanced Common User Access architecture: a part of the scroll bar that shows the position and size of the visible information in a window relative to the total amount of information available. Also known as thumb mark. SOM -System Object Model. source file -A file that contains source statements for items such as high-level language programs and data description specifications. source statement -A statement written in a programming language. specific dynamic-link module -A dynamic-link module created for the exclusive use of an application. spin button -In SAA Advanced Common User Access architecture, a type of entry field that shows a scrollable ring of choices from which a user can select a choice. After the last choice is displayed, the first choice is displayed again. A user can also type a choice from the scrollable ring into the entry field without interacting with the spin button. spline -A sequence of one or more BВzier curves. spooler -A program that intercepts the data going to printer devices and writes it to disk. The data is printed or plotted when it is complete and the required device is available. The spooler prevents output from different sources from being intermixed. stack -A list constructed and maintained so that the next data element to be retrieved is the most recently stored. This method is characterized as last-in-first-out (LIFO). standard window -A collection of window elements that form a panel. The standard window can include one or more of the following window elements: sizing borders, system menu icon, title bar, maximize/minimize/restore icons, action bar and pull-downs, scroll bars, and client area. static control -The means by which the application presents descriptive information (for example, headings and descriptors) to the user. The user cannot change this information. static storage -(1) A read/write storage unit in which data is retained in the absence of control signals. (A) Static storage may use dynamic addressing or sensing circuits. (2) Storage other than dynamic storage. (A) style -See window style. subclass -A class that inherits from another class. See also Inheritance. subdirectory -In an IBM personal computer, a file referred to in a root directory that contains the names of other files stored on the diskette or fixed disk. superclass -A class from which another class inherits. See also inheritance. swapping -(1) A process that interchanges the contents of an area of real storage with the contents of an area in auxiliary storage. (I) (A) (2) In a system with virtual storage, a paging technique that writes the active pages of a job to auxiliary storage and reads pages of another job from auxiliary storage into real storage. (3) The process of temporarily removing an active job from main storage, saving it on disk, and processing another job in the area of main storage formerly occupied by the first job. switch -(1) In SAA usage, to move the cursor from one point of interest to another; for example, to move from one screen or window to another or from a place within a displayed image to another place on the same displayed image. (2) In a computer program, a conditional instruction and an indicator to be interrogated by that instruction. (3) A device or programming technique for making a selection, for example, a toggle, a conditional jump. switch list -See Task List. symbolic identifier -A text string that equates to an integer value in an include file, which is used to identify a programming object. symbols -In Information Presentation Facility, a document element used to produce characters that cannot be entered from the keyboard. synchronous -Pertaining to two or more processes that depend upon the occurrence of specific events such as common timing signals. (T) See also asynchronous. System Menu -In the Presentation Manager, the pull-down in the top left corner of a window that allows it to be moved and sized with the keyboard. System Object Model (SOM) -A mechanism for language-neutral, object-oriented programming in the OS/2 environment. system queue -The master queue for all pointer device or keyboard events. system-defined messages -Messages that control the operations of applications and provides input an other information for applications to process. Systems Application Architecture (SAA) -A set of IBM software interfaces, conventions, and protocols that provide a framework for designing and developing applications that are consistent across systems. ═══ Glossary - T ═══ table tags -In Information Presentation Facility, a document element that formats text in an arrangement of rows and columns. tag -(1) One or more characters attached to a set of data that contain information about the set, including its identification. (I) (A) (2) In Generalized Markup Language markup, a name for a type of document or document element that is entered in the source document to identify it. target object -An object to which the user is transferring information. Task List -In the Presentation Manager, the list of programs that are active. The list can be used to switch to a program and to stop programs. terminate-and-stay-resident (TSR) -Pertaining to an application that modifies an operating system interrupt vector to point to its own location (known as hooking an interrupt). text -Characters or symbols. text cursor -A symbol displayed in an entry field that indicates where typed input will appear. text window -Also known as the VIO window. text-windowed application -The environment in which the operating system performs advanced-video input and output operations. thread -A unit of execution within a process. It uses the resources of the process. thumb mark -The portion of the scroll bar that describes the range and properties of the data that is currently visible in a window. Also known as a slider box. thunk -Term used to describe the process of address conversion, stack and structure realignment, etc., necessary when passing control between 16-bit and 32-bit modules. tilde -A mark used to denote the character that is to be used as a mnemonic when selecting text items within a menu. time slice -(1) An interval of time on the processing unit allocated for use in performing a task. After the interval has expired, processing-unit time is allocated to another task, so a task cannot monopolize processing-unit time beyond a fixed limit. (2) In systems with time sharing, a segment of time allocated to a terminal job. time-critical process -A process that must be performed within a specified time after an event has occurred. timer -A facility provided under the Presentation Manager, whereby Presentation Manager will dispatch a message of class WM_TIMER to a particular window at specified intervals. This capability may be used by an application to perform a specific processing task at predetermined intervals, without the necessity for the application to explicitly keep track of the passage of time. timer tick -See clock tick. title bar -In SAA Advanced Common User Access architecture, the area at the top of each window that contains the window title and system menu icon. When appropriate, it also contains the minimize, maximize, and restore icons. Contrast with panel title. TLB -Translation lookaside buffer. transaction -An exchange between a workstation and another device that accomplishes a particular action or result. transform -(1) The action of modifying a picture by scaling, shearing, reflecting, rotating, or translating. (2) The object that performs or defines such a modification; also referred to as a transformation. Translation lookaside buffer (TLB) -A hardware-based address caching mechanism for paging information. Tree -In the Presentation Manager, the window in the File Manager that shows the organization of drives and directories. truncate -(1) To terminate a computational process in accordance with some rule (A) (2) To remove the beginning or ending elements of a string. (3) To drop data that cannot be printed or displayed in the line width specified or available. (4) To shorten a field or statement to a specified length. TSR -Terminate-and-stay-resident. ═══ Glossary - U ═══ unnamed pipe -A circular buffer, created in memory, used by related processes to communicate with one another. Contrast with named pipe. unordered list -In Information Presentation Facility, a vertical arrangement of items in a list, with each item in the list preceded by a special character or bullet. update region -A system-provided area of dynamic storage containing one or more (not necessarily contiguous) rectangular areas of a window that are visually invalid or incorrect, and therefore are in need of repainting. user interface -Hardware, software, or both that allows a user to interact with and perform operations on a system, program, or device. User Shell -A component of OS/2 that uses a graphics-based, windowed interface to allow the user to manage applications and files installed and running under OS/2. utility program -(1) A computer program in general support of computer processes; for example, a diagnostic program, a trace program, a sort program. (T) (2) A program designed to perform an everyday task such as copying data from one storage device to another. (A) ═══ Glossary - V ═══ value set control -A visual component that enables a user to select one choice from a group of mutually exclusive choices. vector font -A set of symbols, each of which is created as a series of lines and curves. Synonymous with outline font. Contrast with image font. VGA -Video graphics array. view -A way of looking at an object's information. viewing pipeline -The series of transformations applied to a graphic object to map the object to the device on which it is to be presented. viewing window -A clipping boundary that defines the visible part of model space. VIO -Video Input/Output. virtual memory (VM) -Synonymous with virtual storage. virtual storage -(1) The storage space that may be regarded as addressable main storage by the user of a computer system in which virtual addresses are mapped into real addresses. The size of virtual storage is limited by the addressing scheme of the computer system and by the amount of auxiliary storage available, not by the actual number of main storage locations. (I) (A) (2) Addressable space that is apparent to the user as the processor storage space, from which the instructions and the data are mapped into the processor storage locations. (3) Synonymous with virtual memory. visible region -A window's presentation space, clipped to the boundary of the window and the boundaries of any overlying window. volume -(1) A file-system driver that uses a block device driver for input and output operations to a local or remote device. (I) (2) A portion of data, together with its data carrier, that can be handled conveniently as a unit. ═══ Glossary - W ═══ wildcard character -Synonymous with global file-name character. window -(1) A portion of a display surface in which display images pertaining to a particular application can be presented. Different applications can be displayed simultaneously in different windows. (A) (2) An area of the screen with visible boundaries within which information is displayed. A window can be smaller than or the same size as the screen. Windows can appear to overlap on the screen. window class -The grouping of windows whose processing needs conform to the services provided by one window procedure. window coordinates -A set of coordinates by which a window position or size is defined; measured in device units, or pels. window handle -Unique identifier of a window, generated by Presentation Manager when the window is created, and used by applications to direct messages to the window. window procedure -Code that is activated in response to a message. The procedure controls the appearance and behavior of its associated windows. window rectangle -The means by which the size and position of a window is described in relation to the desktop window. window resource -A read-only data segment stored in the .EXE file of an application o the .DLL file of a dynamic link library. window style -The set of properties that influence how events related to a particular window will be processed. window title -In SAA Advanced Common User Access architecture, the area in the title bar that contains the name of the application and the OS/2 operating system file name, if applicable. Workplace Shell -The OS/2 object-oriented, graphical user interface. workstation -(1) A display screen together with attachments such as a keyboard, a local copy device, or a tablet. (2) (D of C) One or more programmable or nonprogrammable devices that allow a user to do work. world coordinates -A device-independent Cartesian coordinate system used by the application program for specifying graphical input and output. (I) (A) world-coordinate space -Coordinate space in which graphics are defined before transformations are applied. WYSIWYG -What-You-See-Is-What-You-Get. A capability of a text editor to continually display pages exactly as they will be printed. ═══ Glossary - X ═══ There are no glossary terms for this starting letter. ═══ Glossary - Y ═══ There are no glossary terms for this starting letter. ═══ Glossary - Z ═══ z-order -The order in which sibling windows are presented. The topmost sibling window obscures any portion of the siblings that it overlaps; the same effect occurs down through the order of lower sibling windows. zooming -The progressive scaling of an entire display image in order to give the visual impression of movement of all or part of a display group toward or away from an observer. (I) (A) 8.3 file-name format -A file-naming convention in which file names are limited to eight characters before and three characters after a single dot. Usually pronounced "eight-dot-three." See also non-8.3 file-name format.