PMGuide - Window Classes: Difference between revisions
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..." |
|||
(2 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
{{IBM-Reprint}} | {{IBM-Reprint}} | ||
{{PMGuide}} | {{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 application creates and uses 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. | ||
==About Window Classes== | ==About Window Classes== | ||
Line 8: | Line 8: | ||
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. | 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. | An application can register private classes or use preregistered public window classes. | ||
===Private 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. | 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. | ||
Line 31: | Line 30: | ||
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: | 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: | ||
{|class="wikitable" | |||
!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==== | ====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. | 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==== | ====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. | 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. | 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==== | ====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. | 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. | 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=== | ||
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. | 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. | An application cannot use a public window class name when it registers a private window class. | ||
====System-Defined Public Window Classes==== | ====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: | 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="wikitable" | |||
|+ Window Classes and Descriptions | |||
|- | |||
! 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. | |||
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==== | ====Custom Public Window Classes==== | ||
Line 206: | Line 127: | ||
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. | 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. | 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=== | ===Class Data=== | ||
Line 230: | Line 151: | ||
0); /* Extra bytes to reserve */ | 0); /* Extra bytes to reserve */ | ||
</PRE> | </PRE> | ||
==Register an Imported Window Procedure== | |||
'''NOT DOCUMENTED ON ORIGINAL SOURCE.''' | |||
[[Category:PM Guide]] | [[Category:PM Guide]] |
Latest revision as of 17:58, 15 April 2025
Reprint Courtesy of International Business Machines Corporation, © International Business Machines Corporation
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 */
Register an Imported Window Procedure
NOT DOCUMENTED ON ORIGINAL SOURCE.