PMGuide - Frame Windows: Difference between revisions
Created page with "{{IBM-Reprint}} {{PMGuide}} == Frame Windows == A '''frame window''' is the basic window used by most Presentation Manager applications to enable the user to perform manipulation functions. This chapter explains how to create and use frame windows in PM applications. == About Frame Windows == An application nearly always starts with a frame window to create a '''composite window''' (for example, a main window) that consists of the frame window, several frame-control wi..." |
|||
(8 intermediate revisions by the same user not shown) | |||
Line 11: | Line 11: | ||
=== Main Window === | === Main Window === | ||
The '''main window''' of an application, typically, is composed of a frame window and a client window. The frame window usually includes control windows such as a title bar, system menu, menu bar ('''action bar''' or '''menu''' in user terminology), and scroll bars. | The '''main window''' of an application, typically, is composed of a frame window and a client window. The frame window usually includes control windows such as a title bar, system menu, menu bar ('''action bar''' or '''menu''' in user terminology), and scroll bars. | ||
A frame window provides the standard services the user expects from a window—for example, moving, sizing, minimizing, and maximizing. The frame window receives input from the control windows (called '''frame controls''') and sends messages to both the frame controls and the client window. | A frame window provides the standard services the user expects from a window—for example, moving, sizing, minimizing, and maximizing. The frame window receives input from the control windows (called '''frame controls''') and sends messages to both the frame controls and the client window. | ||
==== Frame Controls ==== | ==== Frame Controls ==== | ||
When creating a frame window, an application also can create one or more frame controls as child windows of the frame window. Most frame windows contain at least a system menu and title bar. Other optional controls might include a menu bar and scroll bar as shown above. | When creating a frame window, an application also can create one or more frame controls as child windows of the frame window. Most frame windows contain at least a system menu and title bar. Other optional controls might include a menu bar and scroll bar as shown above. | ||
An application can create a frame window with specified frame controls by calling WinCreateStdWindow with the appropriate frame-control flags. | An application can create a frame window with specified frame controls by calling WinCreateStdWindow with the appropriate frame-control flags. | ||
The frame window owns the child frame-control windows, which can send notification messages that tell the frame window what the user is doing with the frame controls. For example, using a mouse, a user can move a window by clicking the title bar and dragging the window to a new position. The title-bar control responds to the click by sending a message to the frame window, notifying it of the user's request to move the window. Then the frame window tracks the mouse motion and moves the frame window and all of its child windows to the new position. | The frame window owns the child frame-control windows, which can send notification messages that tell the frame window what the user is doing with the frame controls. For example, using a mouse, a user can move a window by clicking the title bar and dragging the window to a new position. The title-bar control responds to the click by sending a message to the frame window, notifying it of the user's request to move the window. Then the frame window tracks the mouse motion and moves the frame window and all of its child windows to the new position. | ||
PM, rather than the application, handles the processing of the frame controls, thus providing the user a consistent interface for manipulating and interacting with windowed applications on the screen. Frame controls are described in individual chapters. For more information about control windows, see | |||
PM, rather than the application, handles the processing of the frame controls, thus providing the user a consistent interface for manipulating and interacting with windowed applications on the screen. Frame controls are described in individual chapters. For more information about control windows, see Control Windows. | |||
==== Client Window ==== | ==== Client Window ==== | ||
Line 50: | Line 54: | ||
|} | |} | ||
=== Frame-Window Creation === | |||
An application typically creates a frame window by using '''[[WinCreateStdWindow]]''', which creates a frame window, a client window, and the specified frame controls. The application also can call '''[[WinCreateWindow]]''' with the '''WC_FRAME''' window class, which creates the frame window and controls but not the client window. To create the client, the application can call [[WinCreateWindow]], specifying the original frame window as the parent and owner. | |||
An application also can use a frame window to create a dialog window. For a dialog window, the frame window contains control windows but no client window. The application creates the dialog window by using [[WinLoadDlg]] or [[WinCreateDlg]]. These functions require an appropriate dialog template from the application's resource-definition file. The dialog template specifies the styles and dimensions for the frame window and for the control windows that compose the dialog window. | |||
==== Frame Window Controls and Styles ==== | |||
An application uses frame-control flags in [[WinCreateStdWindow]] to specify which frame controls to give to the frame window. Frame-control flags are constants that have the '''FCF_''' prefix. | |||
The frame-window class ('''WC_FRAME}'''), like other public window classes, provides many class-specific window styles that applications can use to adapt the appearance and behavior of a frame window. To specify the frame-window styles, an application can use either frame-control flags or the frame-window style constants, which have the '''FS_''' prefix. Each style constant has a corresponding frame-control flag. Both produce exactly the same styles in a frame window. Typically, if an application is creating a frame window that uses frame controls, the application uses frame-control flags to specify the frame-window styles-if not, the application uses frame-style constants. An application can combine the frame-style constants with the standard window styles when creating a frame window. | |||
When an application calls [[WinCreateStdWindow]] without setting any frame-control flags, the function creates a standard window that is invisible and behind all its sibling windows, has a width and height of 0, and is positioned at the lower-left corner of its parent window. After the call to [[WinCreateStdWindow]] returns, the application can use [[WinSetWindowPos]] to change the window's size, coordinates, z-order position, and visibility. | |||
If an application calls [[WinCreateStdWindow]] with the '''FCF_SHELLPOSITION''' frame-control flag, the function creates the window so that it is in front of its sibling windows and has a standard size and coordinates determined by the system. | |||
==== Frame-Window Resources ==== | |||
If an application specifies '''FCF_ACCELTABLE''', '''FCF_ICON''', '''FCF_MENU''', '''FCF_STANDARD''', '''FS_ACCELTABLE''', '''FS_ICON''', or '''FS_STANDARD''' when creating a frame window, the application must provide the resources to support the specified style. Failure to do so causes the window creation to fail. Depending on the style, a frame window might attempt to load one or more resources from the application's executable files. | |||
The following table shows the frame-control flags and frame-window styles that require resources: | |||
{| class="wikitable" | |||
|+ Frame Creation Flags and Styles | |||
|- | |||
! Flag | |||
! Style | |||
! Description | |||
|- | |||
| FCF_ACCELTABLE | |||
| FS_ACCELTABLE | |||
| Requires an accelerator-table resource. The frame window uses the accelerator table to translate WM_CHAR messages to WM_COMMAND, WM_HELP, or WM_SYSCOMMAND messages. | |||
|- | |||
| FCF_ICON | |||
| FS_ICON | |||
| Requires an icon resource. The frame window draws the icon when the user minimizes the window. | |||
|- | |||
| FCF_MENU | |||
| FS_MENU | |||
| Requires a menu-template resource. A frame window uses the menu template to create a menu containing the commands and menus specified by the resource. | |||
|- | |||
| FCF_STANDARD | |||
| FS_STANDARD | |||
| Requires a menu-template resource (FCF_STANDARD only), an accelerator-table resource, and an icon resource. | |||
|} | |||
You can use the resource compiler to add icon, menu, and accelerator-table resources to the application's executable file. Each resource must have a resource identifier that matches the resource identifier specified in the FRAMECDATA structure passed to WinCreateWindow or in the idResources parameter of WinCreateStdWindow. | |||
;Note: For detailed information about icon, menu, and accelerator-table resources, see Mouse Pointers and Icons, Menus, and Keyboard Accelerators, respectively. | |||
The following sample code illustrates how to use WinCreateStdWindow to load and set up certain resources for a frame window. Normally the first step is to set up a header file defining the the IDs of the applicable resources: | |||
<pre> | |||
#define ID_RESOURCE 301 | |||
#define IDM_OPTIONS 350 | |||
#define IDM_SHIFT 351 | |||
#define IDM_EXIT 352 | |||
</pre> | |||
Then, make a resource (.RC) file, defining each resource: | |||
<pre> | |||
#include <os2.h> | |||
/* Icon */ | |||
POINTER ID_RESOURCE sampres.ico | |||
/* Accelerator table */ | |||
ACCELTABLE ID_RESOURCE | |||
BEGIN | |||
VK_F10, IDM_SHIFT, VIRTUALKEY | |||
VK_F3 , IDM_EXIT, VIRTUALKEY | |||
END | |||
/* Menu */ | |||
MENU ID_RESOURCE | |||
BEGIN | |||
SUBMENU "~Options", IDM_OPTIONS | |||
BEGIN | |||
MENUITEM "~Shift Colors\tF10", IDM_SHIFT | |||
MENUITEM "~Exit\tF3", IDM_EXIT | |||
END | |||
END | |||
</pre> | |||
When using WinCreateStdWindow with more than one resource, each resource can have the same ID, as in the above example (ID_RESOURCE or 1), but only if each resource is of a different type. Resources of the same type must have unique IDs. Use FCF flags to indicate what resources to load: | |||
<pre> | |||
ULONG flFrameFlags= | |||
FCF_TITLEBAR | /* Title bar */ | |||
FCF_SIZEBORDER | /* Size border */ | |||
FCF_MINMAX | /* Min & Max buttons */ | |||
FCF_SYSMENU | /* System menu */ | |||
FCF_SHELLPOSITION | /* System size & position */ | |||
FCF_TASKLIST | /* Add name to task list */ | |||
FCF_ICON | /* Add icon */ | |||
FCF_ACCELTABLE | /* Add accelerator table */ | |||
FCF_MENU; /* Add menu */ | |||
</pre> | |||
Use 0 (or NULL) in the seventh parameter of WinCreateStdWindow to indicate that the resource is stored in the application file, as follows: | |||
<pre> | |||
hwndFrame = WinCreateStdWindow( | |||
HWND_DESKTOP, /* Parent is desktop window */ | |||
WS_VISIBLE, /* Make frame window visible */ | |||
&flFrameFlags, /* Frame controls */ | |||
"ResSamClient", /* Window class for client */ | |||
NULL, /* No window title */ | |||
WS_VISIBLE, /* Make client window visible */ | |||
(HMODULE) 0, /* Resources in application module */ | |||
ID_RESOURCE, /* Resource identifier */ | |||
NULL); /* Pointer to client window handle */ | |||
</pre> | |||
Following is the full listing of the sample program: | |||
<pre> | |||
#define INCL_PM | |||
#include <os2.h> | |||
MRESULT EXPENTRY ClientWndProc(HWND hwnd,ULONG msg,MPARAM mp1,MPARAM mp2); | |||
int main(int argc, char *argv, char *envp) | |||
{ | |||
HWND hwndFrame; | |||
HWND hwndClient; | |||
HMQ hmq; | |||
QMSG qmsg; | |||
HAB hab; | |||
ULONG flFrameFlags= | |||
FCF_TITLEBAR | /* Title bar */ | |||
FCF_SIZEBORDER | /* Size Border */ | |||
FCF_MINMAX | /* Min & Max Buttons */ | |||
FCF_SYSMENU | /* System Menu */ | |||
FCF_SHELLPOSITION | /* System size & position */ | |||
FCF_TASKLIST | /* Add name to task list */ | |||
FCF_ICON | /* Add icon */ | |||
FCF_ACCELTABLE | /* Add accelerator table */ | |||
FCF_MENU; /* Add menu */ | |||
hab = WinInitialize(0); | |||
hmq = WinCreateMsgQueue(hab, 0); | |||
WinRegisterClass( | |||
hab, /* Anchor block handle */ | |||
"ResSamClient", /* Name of class being registered */ | |||
(PFNWP)ClientWndProc, /* Window procedure for class */ | |||
CS_SIZEREDRAW | /* Class style */ | |||
CS_HITTEST, /* Class style */ | |||
0); /* Extra bytes to reserve */ | |||
hwndFrame = WinCreateStdWindow( | |||
HWND_DESKTOP, /* Parent is desktop window */ | |||
WS_VISIBLE, /* Make frame window visible */ | |||
&flFrameFlags, /* Frame controls */ | |||
"ResSamClient", /* Window class for client */ | |||
NULL, /* No window title */ | |||
WS_VISIBLE, /* Make client window visible */ | |||
(HMODULE) 0, /* Resources in application module */ | |||
ID_RESOURCE, /* Resource identifier */ | |||
NULL); /* Pointer to client window handle */ | |||
while (WinGetMsg(hab, &qmsg, 0, 0, 0)) | |||
WinDispatchMsg(hab, &qmsg); | |||
WinDestroyWindow(hwndFrame); | |||
WinDestroyMsgQueue(hmq); | |||
WinTerminate(hab); | |||
return 0; | |||
} | |||
MRESULT EXPENTRY ClientWndProc(HWND hwnd,ULONG msg,MPARAM mp1,MPARAM mp2); | |||
{ | |||
RECTL rcl; | |||
HPS hps; | |||
static LONG lColor=CLR_RED; | |||
switch (msg) | |||
{ | |||
case WM_PAINT: | |||
hps=WinBeginPaint(hwnd,(HPS) NULL, &rcl); /* Get hps */ | |||
WinFillRect(hps,&rcl,lColor); /* Fill the window */ | |||
WinEndPaint(hps); /* Free hps */ | |||
return 0; | |||
case WM_COMMAND: | |||
switch (SHORT1FROMMP(mp1)) | |||
{ | |||
case IDM_SHIFT: /* Shift selected */ | |||
if (lColor==CLR_RED) /* Change the color */ | |||
lColor=CLR_BLUE; | |||
else lColor=CLR_RED; | |||
WinInvalidateRect(hwnd,(PRECTL)NULL,0UL); /* Paint Window */ | |||
return 0; | |||
case IDM_EXIT: /* Exit selected */ | |||
WinPostMsg(hwnd,WM_CLOSE,MPVOID,MPVOID); /* Exit program */ | |||
return 0; | |||
} | |||
} | |||
return WinDefWindowProc (hwnd, msg, mp1, mp2); | |||
} | |||
</pre> | |||
===Frame-Window Class Data=== | |||
An application can specify class-specific data for a frame window by passing to WinCreateWindow a pointer to the FRAMECDATA structure. The class-specific data contains the frame-control flags (FCF_ flags), resource-module handle, and resource identifier to be used when creating the frame window. The resource-module handle and the resource identifier specify where to find resources for the frame window. | |||
Supplying class-specific data with WinCreateWindow is similar to using WinCreateStdWindow without creating a client window. | |||
===Frame-Window Data=== | |||
Frame-window data specifies the state of the frame window at a given time. An application can retrieve the frame-window data by calling WinQueryWindowUShort. A frame window has the following state flags: | |||
{| class="wikitable" | |||
|+ Frame Window Flags and Descriptions | |||
|- | |||
! Flag | |||
! Description | |||
|- | |||
| FF_ACTIVE | |||
| Indicates that the frame window is active. | |||
|- | |||
| FF_DLGDISMISSED | |||
| Indicates that a dialog window has been dismissed by a call to WinDismissDlg. If the dialog window needs to be processed through WinProcessDlg, after being dismissed, the FF_DLGDISMISSED flag must be reset. | |||
|- | |||
| FF_FLASHHILITE | |||
| Indicates that the frame window is flashing and its flash state is TRUE. | |||
|- | |||
| FF_FLASHWINDOW | |||
| Indicates that the frame window flashes as the result of either a call to WinFlashWindow or a WM_FLASHWINDOW message. | |||
|- | |||
| FF_NOACTIVATESWP | |||
| Indicates that the system should do no z-ordering on this frame window. | |||
|- | |||
| FF_OWNERDISABLE | |||
| Indicates whether the owner window was enabled or disabled when the dialog window was loaded, for a frame window that is part of a dialog window. | |||
|- | |||
| FF_OWNERHIDDEN | |||
| Indicates that the frame window's owner window is hidden or minimized, in which case the frame window also is hidden. | |||
|- | |||
| FF_SELECTED | |||
| Indicates that the frame window has been selected. | |||
|- | |||
| FI_ACTIVATEOK | |||
| Indicates that the window can be activated. | |||
|- | |||
| FI_FRAME | |||
| Indicates that the window is a frame window. | |||
|- | |||
| FI_NOMOVEWITHOWNER | |||
| Indicates that the window should move when its owner window moves. | |||
|- | |||
| FI_OWNERHIDE | |||
| Indicates that the frame window should be hidden or shown as a result of its owner window being hidden, shown, minimized, or maximized. | |||
|} | |||
===Frame-Window Operation=== | |||
The frame window maintains the size, position, and visibility of itself, its frame controls, and its client window. The frame window responds to user requests to move, size, minimize, maximize, and redraw itself. It also responds to requests to close (destroy) itself and to change the focus and activation state. | |||
The frame window, when being moved or sized, maintains the position of each owned window relative to its owner window's lower-left corner. | |||
Whenever the frame window redraws itself (for example, after being moved or sized), it draws the frame controls and then lets the application draw the client window. This order ensures that the rapidly drawn frame controls are drawn before the client window. | |||
The order in which the frame controls are drawn depends on the z-order position of the controls. The following list specifies the z-order position of the frame controls (from top to bottom): | |||
FID_SYSMENU | |||
FID_TITLEBAR | |||
FID_MENU | |||
FID_VERTSCROLL | |||
FID_HORZSCROLL | |||
FID_CLIENT | |||
Although an application can change the z-order position of any window, changing the relative positions of frame controls is not recommended. | |||
When the user maximizes the frame window, the size of the frame window increases to the size of its parent window, plus an additional amount on each of its four sides equal to the width of its sizing border. A window always is clipped to its parent window; a maximized standard frame window does not show its sizing border in its normal maximized position. | |||
Frame controls owned by a frame window or windows owned by child windows of a frame window are destroyed automatically when the frame window processes the WM_DESTROY message. | |||
===Nonstandard Frame Windows=== | |||
Although most applications use frame windows to create their main windows and dialog windows, they are not limited to frame windows. Applications can create nonstandard frame windows and still use the standard frame controls, such as the title bar and system menu, within the nonstandard windows. | |||
An application can create a nonstandard frame window either by subclassing a frame window or by creating a private frame-window class. An application that subclasses a frame window can intercept the messages sent to the window and process them in new ways. An application that creates private frame-window classes essentially rewrites the frame-window procedure. In either case, by creating nonstandard frame windows, the application gains much more control over the arrangement of frame controls in the frame window. | |||
The messages WM_FORMATFRAME, WM_UPDATEFRAME, and WM_CALCVALIDRECTS control the arrangement of frame controls for applications that subclass the frame-window procedure. By intercepting these messages, an application can rearrange the frame controls in a frame window. | |||
To maintain the size and position of frame controls, an application that creates private frame-window classes can use WinCreateFrameControls and WinCalcFrameRect. These functions provide capabilities that are similar to those provided by frame windows. | |||
===Default Frame-Window Behavior === | |||
The following table lists all the messages specifically handled by the window procedure of the predefined frame-window class (WC_FRAME) and describes how the window procedure responds to each message. | |||
<pre> | |||
┌────────────────────┬────────────────────────────────────────┐ | |||
│Message │Description │ | |||
├────────────────────┼────────────────────────────────────────┤ | |||
│WM_ACTIVATE │Sets the highlighted state of the title │ | |||
│ │bar or border so that it matches the │ | |||
│ │frame window's activation state. │ | |||
├────────────────────┼────────────────────────────────────────┤ | |||
│WM_BUTTON1DOWN │If the frame window is minimized, │ | |||
│ │captures the mouse; otherwise, activates│ | |||
│ │the frame window. │ | |||
├────────────────────┼────────────────────────────────────────┤ | |||
│WM_BUTTON2DOWN │Activates the frame window. │ | |||
├────────────────────┼────────────────────────────────────────┤ | |||
│WM_BUTTON3DOWN │Activates the frame window. │ | |||
├────────────────────┼────────────────────────────────────────┤ | |||
│WM_BUTTON1UP │Processes messages from minimized window│ | |||
│ │frames. │ | |||
├────────────────────┼────────────────────────────────────────┤ | |||
│WM_BUTTON1DBLCLK │If the frame window is minimized, posts │ | |||
│ │a WM_SYSCOMMAND message to itself; │ | |||
│ │otherwise, activates the frame window. │ | |||
├────────────────────┼────────────────────────────────────────┤ | |||
│WM_CALCVALIDRECTS │If the frame window has no client window│ | |||
│ │or if the client window has the │ | |||
│ │CS_SIZEREDRAW style, returns the │ | |||
│ │CVR_REDRAW flag to invalidate the entire│ | |||
│ │window. │ | |||
├────────────────────┼────────────────────────────────────────┤ | |||
│WM_CLOSE │If the frame window has a client window,│ | |||
│ │passes this message to the client; │ | |||
│ │otherwise, returns the result of │ | |||
│ │WinDefWindowProc. │ | |||
├────────────────────┼────────────────────────────────────────┤ | |||
│WM_CREATE │Creates the specified frame controls by │ | |||
│ │calling WinCreateFrameControls. Also │ | |||
│ │creates any accelerator tables, loads │ | |||
│ │icons, and adds itself to the Window │ | |||
│ │List. These actions depend on the │ | |||
│ │frame-window styles and frame-control │ | |||
│ │flags specified for the window. │ | |||
├────────────────────┼────────────────────────────────────────┤ | |||
│WM_DESTROY │If the focus is held by a child window │ | |||
│ │of the frame window, sets the focus to │ | |||
│ │the frame window's parent window, │ | |||
│ │destroys any owned windows or child │ | |||
│ │windows, destroys any icons created by │ | |||
│ │using the FS_ICON style, and destroys │ | |||
│ │any accelerator tables created by using │ | |||
│ │the FS_ACCELTABLE style. │ | |||
├────────────────────┼────────────────────────────────────────┤ | |||
│WM_ENABLE │Returns the result of WinDefWindowProc. │ | |||
├────────────────────┼────────────────────────────────────────┤ | |||
│WM_ERASEBACKGROUND │Returns TRUE, signaling that the window │ | |||
│ │should erase the client-window area. The│ | |||
│ │frame window sends this message to │ | |||
│ │itself during WM_PAINT processing. │ | |||
├────────────────────┼────────────────────────────────────────┤ | |||
│WM_FORMATFRAME │Calculates the sizes and positions of │ | |||
│ │the frame controls and the client │ | |||
│ │window. │ | |||
├────────────────────┼────────────────────────────────────────┤ | |||
│WM_HITTEST │If the frame window is minimized and │ | |||
│ │disabled, returns HT_ERROR; otherwise, │ | |||
│ │returns TF_MOVE. │ | |||
├────────────────────┼────────────────────────────────────────┤ | |||
│WM_MINMAXFRAME │If the frame window has a client window,│ | |||
│ │passes this message to the client │ | |||
│ │window; otherwise, passes this message │ | |||
│ │to WinDefWindowProc. │ | |||
├────────────────────┼────────────────────────────────────────┤ | |||
│WM_MOUSEMOVE │Determines the correct mouse pointer to │ | |||
│ │use and returns the result of │ | |||
│ │WinDefWindowProc. │ | |||
├────────────────────┼────────────────────────────────────────┤ | |||
│WM_PAINT │If the frame window is minimized, sends │ | |||
│ │WM_QUERYICON and WM_ERASEBACKGROUND to │ | |||
│ │itself and draws the icon; otherwise, │ | |||
│ │paints the control windows, sends a │ | |||
│ │WM_ERASEBACKGROUND message to the client│ | |||
│ │window, and paints the client window. │ | |||
├────────────────────┼────────────────────────────────────────┤ | |||
│WM_QUERYTRACKINFO │Starts track-move processing of the │ | |||
│ │title-bar control window. │ | |||
├────────────────────┼────────────────────────────────────────┤ | |||
│WM_SHOW │Returns the result of WinDefWindowProc. │ | |||
├────────────────────┼────────────────────────────────────────┤ | |||
│WM_SIZE │Sends a WM_FORMATFRAME message to │ | |||
│ │itself. │ | |||
├────────────────────┼────────────────────────────────────────┤ | |||
│WM_SYSCOMMAND │If the frame window has captured the │ | |||
│ │mouse, ignores the system command; │ | |||
│ │otherwise, uses one of the following │ | |||
│ │commands: SC_APPMENU, SC_CLOSE, SC_MOVE,│ | |||
│ │SC_NEXT, SC_NEXTFRAME, SC_RESTORE, │ | |||
│ │SC_SIZE, SC_SYSMENU, SC_TASKMANAGER. │ | |||
├────────────────────┼────────────────────────────────────────┤ | |||
│WM_UPDATEFRAME │Reformats and updates the appearance of │ | |||
│ │the frame window. Sent after a frame │ | |||
│ │control has been added to or removed │ | |||
│ │from the frame window. │ | |||
└────────────────────┴────────────────────────────────────────┘ | |||
</pre> | |||
==Using Frame Windows== | |||
This section explains how to: | |||
* Create a main window | |||
* Retrieve a frame-control handle | |||
===Creating a Main Window=== | |||
An application can create a main window by using WinCreateStdWindow. The following code fragment creates a typical main window-a frame window that has a system menu, title bar, menu, vertical and horizontal scroll bars, minimize and maximize (window-sizing) buttons, and a sizing border: | |||
<pre> | |||
#define IDM_MENU 1 | |||
HWND hwndFrame; | |||
ULONG flFrameControlFlags = | |||
FCF_SYSMENU | | |||
FCF_TITLEBAR | | |||
FCF_SIZEBORDER | | |||
FCF_MENU | | |||
FCF_MINMAX | | |||
FCF_HORZSCROLL | | |||
FCF_VERTSCROLL | | |||
FCF_SHELLPOSITION; | |||
hwndFrame = WinCreateStdWindow( | |||
HWND_DESKTOP, /* Frame-window parent */ | |||
WS_VISIBLE, /* Make window visible */ | |||
&flFrameControlFlags, /* Frame-control flags */ | |||
"MyClass", /* Client-window class */ | |||
"Main Window", /* Window title */ | |||
0, /* No client-window styles */ | |||
(HMODULE)NULL, /* App. module has resources */ | |||
IDM_MENU, /* Resource ID */ | |||
0); /* Client-window handle */ | |||
</pre> | |||
An application also can create a standard main window by creating a frame window with the FCF_STANDARD flag. The application must include icon, menu, and accelerator-table resources if it uses the FCF_STANDARD flag. | |||
The application creates the standard window by using WinCreateStdWindow, as shown in the following code fragment: | |||
<pre> | |||
#define IDM_RESOURCES 1 | |||
HWND hwndFrame; | |||
/* Set the frame-control flags. */ | |||
ULONG flFrameControlFlags = FCF_STANDARD; | |||
/* Create the standard main window. */ | |||
hwndFrame = WinCreateStdWindow(HWND_DESKTOP, | |||
WS_VISIBLE, | |||
&flFrameControlFlags, | |||
"MyClass", | |||
"Main Window", 0, | |||
(HMODULE) NULL, | |||
IDM_RESOURCES, 0); | |||
</pre> | |||
Another way to create a main window and its frame controls is to use WinCreateWindow to create the frame window and the frame controls, then call WinCreateWindow again to create the client window. One advantage of this approach is that, when creating the frame window, the application can specify the window's initial size and position. The following figure illustrates this approach: | |||
<pre> | |||
#define ID_RESOURCES 1 | |||
#define ID_FRAME 1 | |||
ULONG flFrameControlFlags = | |||
FCF_ACCELTABLE | | |||
FCF_ICON | | |||
FCF_MENU | | |||
FCF_MINMAX | | |||
FCF_SIZEBORDER | | |||
FCF_SYSMENU | | |||
FCF_TASKLIST | | |||
FCF_TITLEBAR; | |||
FRAMECDATA fcdata; | |||
HWND hwndFrame; | |||
HWND hwndClient; | |||
SWP swp; | |||
fcdata.cb = sizeof(FRAMECDATA); | |||
fcdata.flCreateFlags = flFrameControlFlags; | |||
fcdata.hmodResources = (HMODULE) NULL; | |||
fcdata.idResources = ID_RESOURCES; | |||
/* Create the frame and client windows. */ | |||
hwndFrame = WinCreateWindow( | |||
HWND_DESKTOP, /* Frame-window parent */ | |||
WC_FRAME, /* Frame-window class */ | |||
"Main Window", /* Window title */ | |||
0, /* Initially invisible */ | |||
0,0,0,0, /* Size and position = 0 */ | |||
NULL, /* No owner */ | |||
HWND_TOP, /* Top z-order position */ | |||
ID_FRAME, /* Frame-window ID */ | |||
&fcdata, /* Pointer to class data */ | |||
NULL); /* No presentation parameters */ | |||
hwndClient = WinCreateWindow( | |||
hwndFrame, /* Client-window parent */ | |||
"MyClass", /* Client-window class */ | |||
NULL, /* No title for client window */ | |||
0, /* Initially invisible */ | |||
0,0,0,0, /* Size and position = 0 */ | |||
hwndFrame, /* Owner is frame window */ | |||
HWND_BOTTOM, /* Bottom z-order position */ | |||
FID_CLIENT, /* Standard client-window ID */ | |||
NULL, /* No class data */ | |||
NULL); /* No presentation parameters */ | |||
. | |||
. /* Continue with initialization. */ | |||
. | |||
/* Set the size and position of the frame window. */ | |||
WinQueryWindowPos(HWND_DESKTOP, &swp); | |||
WinSetWindowPos(hwndFrame, | |||
HWND_TOP, | |||
swp.x, | |||
swp.cy / 2, | |||
swp.cx, | |||
swp.cy / 2, | |||
SWP_MOVE | | |||
SWP_SIZE); | |||
/* Set the size and position of the client window. */ | |||
WinQueryWindowPos(hwndFrame, &swp); | |||
WinSetWindowPos(hwndClient, | |||
HWND_TOP, | |||
SV_CXSIZEBORDER, | |||
SV_CYSIZEBORDER - 1, | |||
swp.cx - SV_CXSIZEBORDER * 2, | |||
(swp.cy - SV_CYSIZEBORDER * 2) + 1, | |||
SWP_MOVE | | |||
SWP_SIZE); | |||
/* Make the frame and client windows visible. */ | |||
WinShowWindow(hwndFrame, TRUE); | |||
WinShowWindow(hwndClient, TRUE); | |||
</pre> | |||
===Retrieving a Frame Handle === | |||
An application can retrieve a frame-control handle by using WinWindowFromID. The following code fragment retrieves the handle of a title-bar control: | |||
HWND hwndTitleBar,hwndFrame; | |||
hwndTitleBar = WinWindowFromID(hwndFrame, FID_TITLEBAR); | |||
Given a frame-control handle, an application can retrieve its parent frame-window handle by using WinQueryWindow: | |||
HWND hwndFrame,hwndTitleBar; | |||
hwndFrame = WinQueryWindow(hwndTitleBar, QW_PARENT); | |||
By using identifiers to identify frame controls, rather than using window classes, an application can create its own controls to replace the predefined controls. |
Latest revision as of 04:53, 28 April 2025
Reprint Courtesy of International Business Machines Corporation, © International Business Machines Corporation
Frame Windows
A frame window is the basic window used by most Presentation Manager applications to enable the user to perform manipulation functions. This chapter explains how to create and use frame windows in PM applications.
About Frame Windows
An application nearly always starts with a frame window to create a composite window (for example, a main window) that consists of the frame window, several frame-control windows, and a client window. The frame controls conform to the Common User Access (CUA) user interface guidelines. The frame window coordinates the actions of the frame controls and client window, enabling the composite window to act as a single unit. Frame windows have the preregistered public window class WC_FRAME. The frame-window class, like the preregistered control classes, defines the appearance and behavior of the frame window.
Main Window
The main window of an application, typically, is composed of a frame window and a client window. The frame window usually includes control windows such as a title bar, system menu, menu bar (action bar or menu in user terminology), and scroll bars.
A frame window provides the standard services the user expects from a window—for example, moving, sizing, minimizing, and maximizing. The frame window receives input from the control windows (called frame controls) and sends messages to both the frame controls and the client window.
Frame Controls
When creating a frame window, an application also can create one or more frame controls as child windows of the frame window. Most frame windows contain at least a system menu and title bar. Other optional controls might include a menu bar and scroll bar as shown above.
An application can create a frame window with specified frame controls by calling WinCreateStdWindow with the appropriate frame-control flags.
The frame window owns the child frame-control windows, which can send notification messages that tell the frame window what the user is doing with the frame controls. For example, using a mouse, a user can move a window by clicking the title bar and dragging the window to a new position. The title-bar control responds to the click by sending a message to the frame window, notifying it of the user's request to move the window. Then the frame window tracks the mouse motion and moves the frame window and all of its child windows to the new position.
PM, rather than the application, handles the processing of the frame controls, thus providing the user a consistent interface for manipulating and interacting with windowed applications on the screen. Frame controls are described in individual chapters. For more information about control windows, see Control Windows.
Client Window
Every main window has a client window, which is the window in which the application displays output and receives mouse and keyboard input from the user. What an application displays in the client window, how it displays it, and how it interprets input to the window are controlled by the client's application-defined window procedure. An application creates the client window when it creates the frame window. The client window, which is specific to the application, is nearly always created using a private window class (a class registered by the application). Like a frame control, the client window is a child window and is owned by the frame window. This means, for example, that the client window is moved when the frame window moves, is clipped to the frame-window size, and is destroyed when the frame window is destroyed. The relationship between the frame window and the client window allows the frame window to pass messages between other frame controls and the client window. For example, a client window can send a message to the frame window requesting that the frame window change the window title. The frame window, in turn, sends a message to the title-bar control, telling it to change the title of the window.
Additional Frame-Window Items
In addition to its frame controls, a frame window also can contain a sizing border and the minimize and maximize buttons (also known as minimize and maximize icons). These items are not frame controls, because the frame window draws and maintains them. (Frame controls are windows that draw and maintain themselves.) The sizing border encloses the frame window and lets the user change the size of the window using a mouse. The minimize button, at the right end of the title bar, lets the user reduce the frame window to an icon. The maximize button, to the right of the minimize button, lets the user enlarge the window so that it fills the screen. An application can add these items to a frame window by using the FCF_SIZEBORDER, FCF_MAXBUTTON, and FCF_MINBUTTON (or FCF_MINMAX) styles. (The FCF_MINMAX style adds both a maximize button and a minimize button.)
Frame-Control Identifiers
A frame window uses a set of standard constants to identify the frame controls and the client window. The frame-control identifiers all begin with the prefix FID_ and can be used in functions such as WinWindowFromID to uniquely identify a given control or the client window. The frame controls also use these identifiers in notification messages sent to the frame window. The following table describes the frame-control identifiers:
Identifier | Description |
---|---|
FID_CLIENT | Identifies a client window. |
FID_HORZSCROLL | Identifies a horizontal scroll bar. |
FID_MENU | Identifies a menu. |
FID_MINMAX | Identifies the minimize and maximize (window-sizing) buttons. |
FID_SYSMENU | Identifies a system menu. |
FID_TITLEBAR | Identifies a title bar. |
FID_VERTSCROLL | Identifies a vertical scroll bar. |
Frame-Window Creation
An application typically creates a frame window by using WinCreateStdWindow, which creates a frame window, a client window, and the specified frame controls. The application also can call WinCreateWindow with the WC_FRAME window class, which creates the frame window and controls but not the client window. To create the client, the application can call WinCreateWindow, specifying the original frame window as the parent and owner.
An application also can use a frame window to create a dialog window. For a dialog window, the frame window contains control windows but no client window. The application creates the dialog window by using WinLoadDlg or WinCreateDlg. These functions require an appropriate dialog template from the application's resource-definition file. The dialog template specifies the styles and dimensions for the frame window and for the control windows that compose the dialog window.
Frame Window Controls and Styles
An application uses frame-control flags in WinCreateStdWindow to specify which frame controls to give to the frame window. Frame-control flags are constants that have the FCF_ prefix.
The frame-window class (WC_FRAME}), like other public window classes, provides many class-specific window styles that applications can use to adapt the appearance and behavior of a frame window. To specify the frame-window styles, an application can use either frame-control flags or the frame-window style constants, which have the FS_ prefix. Each style constant has a corresponding frame-control flag. Both produce exactly the same styles in a frame window. Typically, if an application is creating a frame window that uses frame controls, the application uses frame-control flags to specify the frame-window styles-if not, the application uses frame-style constants. An application can combine the frame-style constants with the standard window styles when creating a frame window.
When an application calls WinCreateStdWindow without setting any frame-control flags, the function creates a standard window that is invisible and behind all its sibling windows, has a width and height of 0, and is positioned at the lower-left corner of its parent window. After the call to WinCreateStdWindow returns, the application can use WinSetWindowPos to change the window's size, coordinates, z-order position, and visibility.
If an application calls WinCreateStdWindow with the FCF_SHELLPOSITION frame-control flag, the function creates the window so that it is in front of its sibling windows and has a standard size and coordinates determined by the system.
Frame-Window Resources
If an application specifies FCF_ACCELTABLE, FCF_ICON, FCF_MENU, FCF_STANDARD, FS_ACCELTABLE, FS_ICON, or FS_STANDARD when creating a frame window, the application must provide the resources to support the specified style. Failure to do so causes the window creation to fail. Depending on the style, a frame window might attempt to load one or more resources from the application's executable files.
The following table shows the frame-control flags and frame-window styles that require resources:
Flag | Style | Description |
---|---|---|
FCF_ACCELTABLE | FS_ACCELTABLE | Requires an accelerator-table resource. The frame window uses the accelerator table to translate WM_CHAR messages to WM_COMMAND, WM_HELP, or WM_SYSCOMMAND messages. |
FCF_ICON | FS_ICON | Requires an icon resource. The frame window draws the icon when the user minimizes the window. |
FCF_MENU | FS_MENU | Requires a menu-template resource. A frame window uses the menu template to create a menu containing the commands and menus specified by the resource. |
FCF_STANDARD | FS_STANDARD | Requires a menu-template resource (FCF_STANDARD only), an accelerator-table resource, and an icon resource. |
You can use the resource compiler to add icon, menu, and accelerator-table resources to the application's executable file. Each resource must have a resource identifier that matches the resource identifier specified in the FRAMECDATA structure passed to WinCreateWindow or in the idResources parameter of WinCreateStdWindow.
- Note
- For detailed information about icon, menu, and accelerator-table resources, see Mouse Pointers and Icons, Menus, and Keyboard Accelerators, respectively.
The following sample code illustrates how to use WinCreateStdWindow to load and set up certain resources for a frame window. Normally the first step is to set up a header file defining the the IDs of the applicable resources:
#define ID_RESOURCE 301 #define IDM_OPTIONS 350 #define IDM_SHIFT 351 #define IDM_EXIT 352
Then, make a resource (.RC) file, defining each resource:
#include <os2.h> /* Icon */ POINTER ID_RESOURCE sampres.ico /* Accelerator table */ ACCELTABLE ID_RESOURCE BEGIN VK_F10, IDM_SHIFT, VIRTUALKEY VK_F3 , IDM_EXIT, VIRTUALKEY END /* Menu */ MENU ID_RESOURCE BEGIN SUBMENU "~Options", IDM_OPTIONS BEGIN MENUITEM "~Shift Colors\tF10", IDM_SHIFT MENUITEM "~Exit\tF3", IDM_EXIT END END
When using WinCreateStdWindow with more than one resource, each resource can have the same ID, as in the above example (ID_RESOURCE or 1), but only if each resource is of a different type. Resources of the same type must have unique IDs. Use FCF flags to indicate what resources to load:
ULONG flFrameFlags= FCF_TITLEBAR | /* Title bar */ FCF_SIZEBORDER | /* Size border */ FCF_MINMAX | /* Min & Max buttons */ FCF_SYSMENU | /* System menu */ FCF_SHELLPOSITION | /* System size & position */ FCF_TASKLIST | /* Add name to task list */ FCF_ICON | /* Add icon */ FCF_ACCELTABLE | /* Add accelerator table */ FCF_MENU; /* Add menu */
Use 0 (or NULL) in the seventh parameter of WinCreateStdWindow to indicate that the resource is stored in the application file, as follows:
hwndFrame = WinCreateStdWindow( HWND_DESKTOP, /* Parent is desktop window */ WS_VISIBLE, /* Make frame window visible */ &flFrameFlags, /* Frame controls */ "ResSamClient", /* Window class for client */ NULL, /* No window title */ WS_VISIBLE, /* Make client window visible */ (HMODULE) 0, /* Resources in application module */ ID_RESOURCE, /* Resource identifier */ NULL); /* Pointer to client window handle */
Following is the full listing of the sample program:
#define INCL_PM #include <os2.h> MRESULT EXPENTRY ClientWndProc(HWND hwnd,ULONG msg,MPARAM mp1,MPARAM mp2); int main(int argc, char *argv, char *envp) { HWND hwndFrame; HWND hwndClient; HMQ hmq; QMSG qmsg; HAB hab; ULONG flFrameFlags= FCF_TITLEBAR | /* Title bar */ FCF_SIZEBORDER | /* Size Border */ FCF_MINMAX | /* Min & Max Buttons */ FCF_SYSMENU | /* System Menu */ FCF_SHELLPOSITION | /* System size & position */ FCF_TASKLIST | /* Add name to task list */ FCF_ICON | /* Add icon */ FCF_ACCELTABLE | /* Add accelerator table */ FCF_MENU; /* Add menu */ hab = WinInitialize(0); hmq = WinCreateMsgQueue(hab, 0); WinRegisterClass( hab, /* Anchor block handle */ "ResSamClient", /* Name of class being registered */ (PFNWP)ClientWndProc, /* Window procedure for class */ CS_SIZEREDRAW | /* Class style */ CS_HITTEST, /* Class style */ 0); /* Extra bytes to reserve */ hwndFrame = WinCreateStdWindow( HWND_DESKTOP, /* Parent is desktop window */ WS_VISIBLE, /* Make frame window visible */ &flFrameFlags, /* Frame controls */ "ResSamClient", /* Window class for client */ NULL, /* No window title */ WS_VISIBLE, /* Make client window visible */ (HMODULE) 0, /* Resources in application module */ ID_RESOURCE, /* Resource identifier */ NULL); /* Pointer to client window handle */ while (WinGetMsg(hab, &qmsg, 0, 0, 0)) WinDispatchMsg(hab, &qmsg); WinDestroyWindow(hwndFrame); WinDestroyMsgQueue(hmq); WinTerminate(hab); return 0; } MRESULT EXPENTRY ClientWndProc(HWND hwnd,ULONG msg,MPARAM mp1,MPARAM mp2); { RECTL rcl; HPS hps; static LONG lColor=CLR_RED; switch (msg) { case WM_PAINT: hps=WinBeginPaint(hwnd,(HPS) NULL, &rcl); /* Get hps */ WinFillRect(hps,&rcl,lColor); /* Fill the window */ WinEndPaint(hps); /* Free hps */ return 0; case WM_COMMAND: switch (SHORT1FROMMP(mp1)) { case IDM_SHIFT: /* Shift selected */ if (lColor==CLR_RED) /* Change the color */ lColor=CLR_BLUE; else lColor=CLR_RED; WinInvalidateRect(hwnd,(PRECTL)NULL,0UL); /* Paint Window */ return 0; case IDM_EXIT: /* Exit selected */ WinPostMsg(hwnd,WM_CLOSE,MPVOID,MPVOID); /* Exit program */ return 0; } } return WinDefWindowProc (hwnd, msg, mp1, mp2); }
Frame-Window Class Data
An application can specify class-specific data for a frame window by passing to WinCreateWindow a pointer to the FRAMECDATA structure. The class-specific data contains the frame-control flags (FCF_ flags), resource-module handle, and resource identifier to be used when creating the frame window. The resource-module handle and the resource identifier specify where to find resources for the frame window.
Supplying class-specific data with WinCreateWindow is similar to using WinCreateStdWindow without creating a client window.
Frame-Window Data
Frame-window data specifies the state of the frame window at a given time. An application can retrieve the frame-window data by calling WinQueryWindowUShort. A frame window has the following state flags:
Flag | Description |
---|---|
FF_ACTIVE | Indicates that the frame window is active. |
FF_DLGDISMISSED | Indicates that a dialog window has been dismissed by a call to WinDismissDlg. If the dialog window needs to be processed through WinProcessDlg, after being dismissed, the FF_DLGDISMISSED flag must be reset. |
FF_FLASHHILITE | Indicates that the frame window is flashing and its flash state is TRUE. |
FF_FLASHWINDOW | Indicates that the frame window flashes as the result of either a call to WinFlashWindow or a WM_FLASHWINDOW message. |
FF_NOACTIVATESWP | Indicates that the system should do no z-ordering on this frame window. |
FF_OWNERDISABLE | Indicates whether the owner window was enabled or disabled when the dialog window was loaded, for a frame window that is part of a dialog window. |
FF_OWNERHIDDEN | Indicates that the frame window's owner window is hidden or minimized, in which case the frame window also is hidden. |
FF_SELECTED | Indicates that the frame window has been selected. |
FI_ACTIVATEOK | Indicates that the window can be activated. |
FI_FRAME | Indicates that the window is a frame window. |
FI_NOMOVEWITHOWNER | Indicates that the window should move when its owner window moves. |
FI_OWNERHIDE | Indicates that the frame window should be hidden or shown as a result of its owner window being hidden, shown, minimized, or maximized. |
Frame-Window Operation
The frame window maintains the size, position, and visibility of itself, its frame controls, and its client window. The frame window responds to user requests to move, size, minimize, maximize, and redraw itself. It also responds to requests to close (destroy) itself and to change the focus and activation state.
The frame window, when being moved or sized, maintains the position of each owned window relative to its owner window's lower-left corner.
Whenever the frame window redraws itself (for example, after being moved or sized), it draws the frame controls and then lets the application draw the client window. This order ensures that the rapidly drawn frame controls are drawn before the client window.
The order in which the frame controls are drawn depends on the z-order position of the controls. The following list specifies the z-order position of the frame controls (from top to bottom):
FID_SYSMENU FID_TITLEBAR FID_MENU FID_VERTSCROLL FID_HORZSCROLL FID_CLIENT
Although an application can change the z-order position of any window, changing the relative positions of frame controls is not recommended.
When the user maximizes the frame window, the size of the frame window increases to the size of its parent window, plus an additional amount on each of its four sides equal to the width of its sizing border. A window always is clipped to its parent window; a maximized standard frame window does not show its sizing border in its normal maximized position.
Frame controls owned by a frame window or windows owned by child windows of a frame window are destroyed automatically when the frame window processes the WM_DESTROY message.
Nonstandard Frame Windows
Although most applications use frame windows to create their main windows and dialog windows, they are not limited to frame windows. Applications can create nonstandard frame windows and still use the standard frame controls, such as the title bar and system menu, within the nonstandard windows.
An application can create a nonstandard frame window either by subclassing a frame window or by creating a private frame-window class. An application that subclasses a frame window can intercept the messages sent to the window and process them in new ways. An application that creates private frame-window classes essentially rewrites the frame-window procedure. In either case, by creating nonstandard frame windows, the application gains much more control over the arrangement of frame controls in the frame window.
The messages WM_FORMATFRAME, WM_UPDATEFRAME, and WM_CALCVALIDRECTS control the arrangement of frame controls for applications that subclass the frame-window procedure. By intercepting these messages, an application can rearrange the frame controls in a frame window.
To maintain the size and position of frame controls, an application that creates private frame-window classes can use WinCreateFrameControls and WinCalcFrameRect. These functions provide capabilities that are similar to those provided by frame windows.
Default Frame-Window Behavior
The following table lists all the messages specifically handled by the window procedure of the predefined frame-window class (WC_FRAME) and describes how the window procedure responds to each message.
┌────────────────────┬────────────────────────────────────────┐ │Message │Description │ ├────────────────────┼────────────────────────────────────────┤ │WM_ACTIVATE │Sets the highlighted state of the title │ │ │bar or border so that it matches the │ │ │frame window's activation state. │ ├────────────────────┼────────────────────────────────────────┤ │WM_BUTTON1DOWN │If the frame window is minimized, │ │ │captures the mouse; otherwise, activates│ │ │the frame window. │ ├────────────────────┼────────────────────────────────────────┤ │WM_BUTTON2DOWN │Activates the frame window. │ ├────────────────────┼────────────────────────────────────────┤ │WM_BUTTON3DOWN │Activates the frame window. │ ├────────────────────┼────────────────────────────────────────┤ │WM_BUTTON1UP │Processes messages from minimized window│ │ │frames. │ ├────────────────────┼────────────────────────────────────────┤ │WM_BUTTON1DBLCLK │If the frame window is minimized, posts │ │ │a WM_SYSCOMMAND message to itself; │ │ │otherwise, activates the frame window. │ ├────────────────────┼────────────────────────────────────────┤ │WM_CALCVALIDRECTS │If the frame window has no client window│ │ │or if the client window has the │ │ │CS_SIZEREDRAW style, returns the │ │ │CVR_REDRAW flag to invalidate the entire│ │ │window. │ ├────────────────────┼────────────────────────────────────────┤ │WM_CLOSE │If the frame window has a client window,│ │ │passes this message to the client; │ │ │otherwise, returns the result of │ │ │WinDefWindowProc. │ ├────────────────────┼────────────────────────────────────────┤ │WM_CREATE │Creates the specified frame controls by │ │ │calling WinCreateFrameControls. Also │ │ │creates any accelerator tables, loads │ │ │icons, and adds itself to the Window │ │ │List. These actions depend on the │ │ │frame-window styles and frame-control │ │ │flags specified for the window. │ ├────────────────────┼────────────────────────────────────────┤ │WM_DESTROY │If the focus is held by a child window │ │ │of the frame window, sets the focus to │ │ │the frame window's parent window, │ │ │destroys any owned windows or child │ │ │windows, destroys any icons created by │ │ │using the FS_ICON style, and destroys │ │ │any accelerator tables created by using │ │ │the FS_ACCELTABLE style. │ ├────────────────────┼────────────────────────────────────────┤ │WM_ENABLE │Returns the result of WinDefWindowProc. │ ├────────────────────┼────────────────────────────────────────┤ │WM_ERASEBACKGROUND │Returns TRUE, signaling that the window │ │ │should erase the client-window area. The│ │ │frame window sends this message to │ │ │itself during WM_PAINT processing. │ ├────────────────────┼────────────────────────────────────────┤ │WM_FORMATFRAME │Calculates the sizes and positions of │ │ │the frame controls and the client │ │ │window. │ ├────────────────────┼────────────────────────────────────────┤ │WM_HITTEST │If the frame window is minimized and │ │ │disabled, returns HT_ERROR; otherwise, │ │ │returns TF_MOVE. │ ├────────────────────┼────────────────────────────────────────┤ │WM_MINMAXFRAME │If the frame window has a client window,│ │ │passes this message to the client │ │ │window; otherwise, passes this message │ │ │to WinDefWindowProc. │ ├────────────────────┼────────────────────────────────────────┤ │WM_MOUSEMOVE │Determines the correct mouse pointer to │ │ │use and returns the result of │ │ │WinDefWindowProc. │ ├────────────────────┼────────────────────────────────────────┤ │WM_PAINT │If the frame window is minimized, sends │ │ │WM_QUERYICON and WM_ERASEBACKGROUND to │ │ │itself and draws the icon; otherwise, │ │ │paints the control windows, sends a │ │ │WM_ERASEBACKGROUND message to the client│ │ │window, and paints the client window. │ ├────────────────────┼────────────────────────────────────────┤ │WM_QUERYTRACKINFO │Starts track-move processing of the │ │ │title-bar control window. │ ├────────────────────┼────────────────────────────────────────┤ │WM_SHOW │Returns the result of WinDefWindowProc. │ ├────────────────────┼────────────────────────────────────────┤ │WM_SIZE │Sends a WM_FORMATFRAME message to │ │ │itself. │ ├────────────────────┼────────────────────────────────────────┤ │WM_SYSCOMMAND │If the frame window has captured the │ │ │mouse, ignores the system command; │ │ │otherwise, uses one of the following │ │ │commands: SC_APPMENU, SC_CLOSE, SC_MOVE,│ │ │SC_NEXT, SC_NEXTFRAME, SC_RESTORE, │ │ │SC_SIZE, SC_SYSMENU, SC_TASKMANAGER. │ ├────────────────────┼────────────────────────────────────────┤ │WM_UPDATEFRAME │Reformats and updates the appearance of │ │ │the frame window. Sent after a frame │ │ │control has been added to or removed │ │ │from the frame window. │ └────────────────────┴────────────────────────────────────────┘
Using Frame Windows
This section explains how to:
- Create a main window
- Retrieve a frame-control handle
Creating a Main Window
An application can create a main window by using WinCreateStdWindow. The following code fragment creates a typical main window-a frame window that has a system menu, title bar, menu, vertical and horizontal scroll bars, minimize and maximize (window-sizing) buttons, and a sizing border:
#define IDM_MENU 1 HWND hwndFrame; ULONG flFrameControlFlags = FCF_SYSMENU | FCF_TITLEBAR | FCF_SIZEBORDER | FCF_MENU | FCF_MINMAX | FCF_HORZSCROLL | FCF_VERTSCROLL | FCF_SHELLPOSITION; hwndFrame = WinCreateStdWindow( HWND_DESKTOP, /* Frame-window parent */ WS_VISIBLE, /* Make window visible */ &flFrameControlFlags, /* Frame-control flags */ "MyClass", /* Client-window class */ "Main Window", /* Window title */ 0, /* No client-window styles */ (HMODULE)NULL, /* App. module has resources */ IDM_MENU, /* Resource ID */ 0); /* Client-window handle */
An application also can create a standard main window by creating a frame window with the FCF_STANDARD flag. The application must include icon, menu, and accelerator-table resources if it uses the FCF_STANDARD flag.
The application creates the standard window by using WinCreateStdWindow, as shown in the following code fragment:
#define IDM_RESOURCES 1 HWND hwndFrame; /* Set the frame-control flags. */ ULONG flFrameControlFlags = FCF_STANDARD; /* Create the standard main window. */ hwndFrame = WinCreateStdWindow(HWND_DESKTOP, WS_VISIBLE, &flFrameControlFlags, "MyClass", "Main Window", 0, (HMODULE) NULL, IDM_RESOURCES, 0);
Another way to create a main window and its frame controls is to use WinCreateWindow to create the frame window and the frame controls, then call WinCreateWindow again to create the client window. One advantage of this approach is that, when creating the frame window, the application can specify the window's initial size and position. The following figure illustrates this approach:
#define ID_RESOURCES 1 #define ID_FRAME 1 ULONG flFrameControlFlags = FCF_ACCELTABLE | FCF_ICON | FCF_MENU | FCF_MINMAX | FCF_SIZEBORDER | FCF_SYSMENU | FCF_TASKLIST | FCF_TITLEBAR; FRAMECDATA fcdata; HWND hwndFrame; HWND hwndClient; SWP swp; fcdata.cb = sizeof(FRAMECDATA); fcdata.flCreateFlags = flFrameControlFlags; fcdata.hmodResources = (HMODULE) NULL; fcdata.idResources = ID_RESOURCES; /* Create the frame and client windows. */ hwndFrame = WinCreateWindow( HWND_DESKTOP, /* Frame-window parent */ WC_FRAME, /* Frame-window class */ "Main Window", /* Window title */ 0, /* Initially invisible */ 0,0,0,0, /* Size and position = 0 */ NULL, /* No owner */ HWND_TOP, /* Top z-order position */ ID_FRAME, /* Frame-window ID */ &fcdata, /* Pointer to class data */ NULL); /* No presentation parameters */ hwndClient = WinCreateWindow( hwndFrame, /* Client-window parent */ "MyClass", /* Client-window class */ NULL, /* No title for client window */ 0, /* Initially invisible */ 0,0,0,0, /* Size and position = 0 */ hwndFrame, /* Owner is frame window */ HWND_BOTTOM, /* Bottom z-order position */ FID_CLIENT, /* Standard client-window ID */ NULL, /* No class data */ NULL); /* No presentation parameters */ . . /* Continue with initialization. */ . /* Set the size and position of the frame window. */ WinQueryWindowPos(HWND_DESKTOP, &swp); WinSetWindowPos(hwndFrame, HWND_TOP, swp.x, swp.cy / 2, swp.cx, swp.cy / 2, SWP_MOVE | SWP_SIZE); /* Set the size and position of the client window. */ WinQueryWindowPos(hwndFrame, &swp); WinSetWindowPos(hwndClient, HWND_TOP, SV_CXSIZEBORDER, SV_CYSIZEBORDER - 1, swp.cx - SV_CXSIZEBORDER * 2, (swp.cy - SV_CYSIZEBORDER * 2) + 1, SWP_MOVE | SWP_SIZE); /* Make the frame and client windows visible. */ WinShowWindow(hwndFrame, TRUE); WinShowWindow(hwndClient, TRUE);
Retrieving a Frame Handle
An application can retrieve a frame-control handle by using WinWindowFromID. The following code fragment retrieves the handle of a title-bar control:
HWND hwndTitleBar,hwndFrame; hwndTitleBar = WinWindowFromID(hwndFrame, FID_TITLEBAR);
Given a frame-control handle, an application can retrieve its parent frame-window handle by using WinQueryWindow:
HWND hwndFrame,hwndTitleBar; hwndFrame = WinQueryWindow(hwndTitleBar, QW_PARENT);
By using identifiers to identify frame controls, rather than using window classes, an application can create its own controls to replace the predefined controls.