Jump to content

PMGuide - Window Classes

From EDM2
Revision as of 15:22, 4 November 2023 by Martini (talk | contribs) (Created page with "{{IBM-Reprint}} {{PMGuide}} 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 applicat...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Reprint Courtesy of International Business Machines Corporation, © International Business Machines Corporation

Presentation Manager Programming Guide and Reference
  1. How to Use this Book
  2. Device Functions
  3. Direct Manipulation Functions
  4. Dynamic Data Formatting Functions
  5. Hooks and Procedures
  6. Profile Functions
  7. Spooler Functions
  8. Window Functions
  9. Message Processing
  10. Data Types
  11. Errors
  12. Atom Tables
  13. Button Controls
  14. Clipboards
  15. Combination Box
  16. Container Controls
  17. Control Windows
  18. Cursors
  19. Dialog Windows
  20. Direct Manipulation
  21. Drawing in Windows
  22. Dynamic Data Exchange
  23. Entry-Field Controls
  24. File Dialog Controls
  25. Font Dialog Controls
  26. Frame Windows
  27. Hooks
  28. Initialization Files
  29. Keyboard Accelerators
  30. List-Box Controls
  31. Menus
  32. Messages and Message Queues
  33. Multiple-Line Entry Field Controls
  34. Mouse and Keyboard Input
  35. Mouse Pointers and Icons
  36. Notebook Controls
  37. Painting and Drawing
  38. Presentation Parameters
  39. Resource Files
  40. Scroll-Bar Controls
  41. Slider Controls
  42. Spin Button Controls
  43. Static Controls
  44. Title-Bar Controls
  45. Value Set Controls
  46. Windows
  47. Window Classes
  48. Window Procedures
  49. Window Timers
  50. Appendices
  51. Notices
  52. Glossary

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.

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.

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

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.

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. │
└───────────────┴─────────────────────────────────────────────┘

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.

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.

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.

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.

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.

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.

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.

Using Window Classes

This section explains how to perform the following tasks:

  • Register a private window class
  • Register an imported window procedure

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":

    MRESULT EXPENTRY ClientWndProc(HWND hwnd,ULONG msg,MPARAM mp1, MPARAM mp2);

    HAB hab;

    WinRegisterClass(hab,      /* Anchor block handle            */
        "MyPrivateClass",      /* Name of class being registered */
        ClientWndProc,         /* Window procedure for class     */
        CS_SIZEREDRAW |        /* Class style                    */
        CS_HITTEST,            /* Class style                    */
        0);                    /* Extra bytes to reserve         */