Jump to content

PMGuide - Windows: Difference between revisions

From EDM2
Created page with "= 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 t..."
 
No edit summary
 
Line 1: Line 1:
= Windows =
{{IBM-Reprint}}
 
{{PMGuide}}
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:
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:



Latest revision as of 03:46, 7 May 2025

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

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.

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.

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 |                       |
|  | | | +------------+ |                     |
|  | | | |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.

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  | |Window  |        |        | |Window  | |Window  |
| |1.1     | |1.2     |        |        | |2.1     | |2.2     |
| +--------+ +--------+        |        | +--------+ +--------+
| |Child   |                   |        |
| |Window  |                   |        |
| |1.1.1   |                   |        |
| +--------+                   |        |
+---------------------+        |        +---------------------+

Typical Window Relationships

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
  | |Main 1| |                +----------+
  | | +----+ |                |Child 1A  |
  | | |Child| |               +----------+
  | | |1A   | |               |Child 1A.1|
  | | +----+ |               +----------+
  | +------+ |
  | +------+ |
  | |Main 2| |
  | +------+ |
  | +------+ |
  | |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. A 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.

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.

Note: Never create a window with an owner being a window in a different process. This causes problems when destroying the owned- or owner-window; usually the owned- or owner-window hangs.

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.

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.

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.

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.

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.

The User

Mouse or keyboard input to an application window causes the operating system to direct messages to that window.

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.

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.

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.

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.

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.

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.

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.

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.

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.

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.

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.

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 bitmap. 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.)

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.

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.

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.

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 bitmap. 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.

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.

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.

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.

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, bitmaps, 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 Identifier Description
RT_ACCELTABLE Keyboard accelerator table
RT_BITMAP Bitmap
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.

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.

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               |
|   +-------+           |
|   |   C   |   B       |
|   |       |           |
|   |       +-----------+
|   |       |           |
|   +-------+           |
|                       |
|               D       |
|                       |
+-----------------------+
+-------+
|   A   | - 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.

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.

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.

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.

#define IDR_RESOURCES 1

MRESULT EXPENTRY ClientWndProc(HWND, ULONG, MPARAM, MPARAM);

int main(VOID)
{
    HWND hwndFrame;
    HWND hwndClient;
    HMQ  hmq;
    QMSG qmsg;
    HAB  hab;

    /* Set the frame-window creation flags.                       */
    ULONG flFrameFlags =
        FCF_TITLEBAR      |   /* Title bar                        */
        FCF_SIZEBORDER    |   /* Size border                      */
        FCF_MINMAX        |   /* Minimize and maximize buttons.   */
        FCF_SYSMENU       |   /* System menu                      */
        FCF_SHELLPOSITION |   /* 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.                      */
    hmq = WinCreateMsgQueue(hab, 0);

    /* Register the class for the client window.                  */
    WinRegisterClass(
        hab,                    /* Anchor block handle            */
        "MyPrivateClass",       /* Name of class being registered */
        (PFNWP)ClientWndProc,   /* Window procedure for class     */
        CS_SIZEREDRAW |         /* 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             */
        NULL,              /* No window title                     */
        WS_VISIBLE,        /* Make client window visible .        */
        (HMODULE) 0,       /* Resources in application module     */
        IDR_RESOURCES,     /* Resource identifier                 */
        NULL);             /* 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))
           WinDispatchMsg(hab, &qmsg);

    /* Main loop has terminated. Destroy all windows and the      */
    /* message queue; then terminate the application.             */
    WinDestroyWindow(hwndFrame);
    WinDestroyMsgQueue(hmq);
    WinTerminate(hab);

    return 0;
}

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.

#define ID_OBJWINDOW 2

HWND hwndObject;

hwndObject = WinCreateWindow(
    HWND_OBJECT,        /* Parent is object window.            */
    "MyObjClass",       /* Window class for client             */
    NULL,               /* Window text                         */
    0,                  /* No styles for object window         */
    0, 0,               /* Lower-left corner                   */
    0, 0,               /* Width and height                    */
    NULL,               /* No owner                            */
    HWND_BOTTOM,        /* Inserts window at bottom of z-order */
    ID_OBJWINDOW,       /* Window identifier                   */
    NULL,               /* No class-specific data              */
    NULL);              /* No presentation data                */

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:

HWND hwndObject;
USHORT usObjID;

usObjID = WinQueryWindowUShort(hwndObject, QWS_ID);

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.

switch (msg) {
    case WM_ACTIVATE: {
        HWND hwndFrame, hwndSysMenu, hwnd;

        /* 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))
            WinSetParent(hwndSysMenu, hwndFrame, TRUE);
        else
            WinSetParent(hwndSysMenu, HWND_OBJECT, TRUE);
    }
    return 0;
}

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:

HWND hwndParent;
HWND hwndMyWindow;

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

HWND hwndTopChild;
HWND hwndParent;

hwndTopChild = WinQueryWindow(hwndParent, QW_TOP);

If a given window does not have an owner or child window, WinQueryWindow returns NULL.

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:

#define NEW_OWNER 1

HWND hwndMyWindow;
HWND hwndNewOwner;

if (WinSetOwner(hwndMyWindow, hwndNewOwner))
    /* Send a notification message.                                 */
    WinSendMsg(hwndNewOwner,   /* Sends to owner                    */
        WM_CONTROL,            /* Control message for notification  */
        (MPARAM) NEW_OWNER,    /* Notification code                 */
        NULL);                 /* No extra data                     */

A window can have only one owner, so WinSetOwner removes any previous owner.

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.

HWND hwndOwned;
HWND hwndOwner;

case WM_CONTROL:
    switch (SHORT2FROMMP(mp2)) {
        case BN_CLICKED:
            hwndOwned = WinWindowFromID(hwndOwner, (ULONG)SHORT1FROMMP(mp1));
            WinSendMsg(hwndOwned, WM_ENABLE, (MPARAM)TRUE, (MPARAM)NULL);
            return 0;
        /* Check for other notification codes. */
    }

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.

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

HWND hwndTop;
HENUM henum;

/* Enumerate all top-level windows.           */
henum = WinBeginEnumWindows(HWND_DESKTOP);

/* Loop through all enumerated windows.       */
while (hwndTop = WinGetNextWindow(henum)) {
    /* Perform desired task on each window. */
}

WinEndEnumWindows(henum);

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

HWND hwnd;

WinSetWindowPos(
    hwnd,                 /* Window handle                  */
    NULL,                 /* 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.

HWND hwnd;

WinSetWindowPos(
    hwnd,                 /* Window handle                  */
    NULL,                 /* Not used for moving and sizing */
    10, 10,               /* New position                   */
    200, 200,             /* Width and height               */
    SWP_MOVE | 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.

HWND hwnd;
SWP swp;

WinQueryWindowPos(hwnd, &swp);
WinSetWindowPos(
    hwnd,                /* Window handle                  */
    NULL,                /* 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.

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.

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.

HWND hwndParent;
HWND hwndNext;
HENUM henum;

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.

HWND hwndParent;
HWND hwndNext;
HWND hwndExchange;
HENUM henum;

henum = WinBeginEnumWindows(hwndParent);

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);

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.

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.

SWP swpCurrent;
HWND hwndFrame;

WinQueryWindowPos(hwndFrame, &swpCurrent);
WinSetWindowPos(
    hwndFrame,           /* Window handle               */
    NULL,                /* Not used to maximize        */
    swpCurrent.x,
    swpCurrent.y,        /* Stored for restoring window */
    swpCurrent.cx,
    swpCurrent.cy,       /* Stored for restoring window */
    SWP_MAXIMIZE | SWP_SIZE | SWP_MOVE);    /* Maximize */

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:

HWND hwndCtrl;
HWND hwndParent;

hwndCtrl = WinCreateWindow(hwndParent, WC_BUTTON, ...);

WinDestroyWindow(hwndCtrl);