[ Next ] [ Previous ] | Chapter 14 |
|
Most users are familiar with the traditional pull-down
menus. (See
Figure 14.1) This interface is common throughout many GUI environments.
A pull-down menu should contain related choices. These choices extend
from
the menu bar when a particular menu bar choice is selected
A cascaded menu is one one that extends from a selected choice in a pull-down menu of a tag-along pull-down menu.. Cascaded menus can help to shorten long menus. Presentation Manager indicates the presence of a cascaded menu by right arrow along the right edge of the pull-down menu. |
A pop-up menu (see Figure 14.2) is a menu that pops up a list of choices for an object when some action is performed to trigger the menu.. Pop-up menus are very common in 32-bit OS/2 and are an integral part of the object-oriented workplace shell. Pop-up menus normally are placed to the right of the object they pertain to, unless space does not permit; in such case, the menu is placed wherever space permits. |
|
The keys specified in Table 14.1 are important keystrokes to access
menus.
Key | Action |
ALT | Toggles the focus on the menu action bar. |
Shift + ESC, Alt + spacebar | Causes the system menu to become visible. |
F10 | Jumps to the next higher menu level. |
(up arrow) | If the pull-down menu is not visible, causes it to become visible; if the pull - down menu is visible, will move to the previous menu item. |
(down arrow) | If the pull-down menu is not visible, causes it to become visible if the pull - down down menu is visible, will move to the next menu item. |
(left arrow) | Will move to the next item on the action bar; the system menu is is included in the items items this key will cycle through. |
(right arrow) | Will move to the previous item on the action bar; the system menu is included in the items this key will cycle through. |
Enter | Selects the current item; if the item is on the action bar, the pull - down menu will become visible. |
Character keys | Moves to the menu item that has corresponding mnemonic key. |
Styles | Description |
MS_ACTIONBAR | Creates a menu bar. |
MS_CONDITIONALCASCADE | Creates a cascaded menu that will become visible only when the arrow to the right of the menu item is selected. |
MS_TITLEBUTTON | Creates a push button along the menu bar. |
MS_VERTICALFLIP | Causes a pull-down menu to be placed above the action bar, space permitting; if space is not available, the menu is placed below the action bar. |
The choices available in a menu are known as menu items. These menu items are not really a window, but they do have a special set of styles associated with them. Table 14.2 lists these styles.
Item Styles | Description |
MIS_SUBMENU | Creates submenu. |
MIS_SEPARATOR | Inserts a horizontal bar in the menu; a separator is a dummy item and cannot be selected, enabled, or disabled. |
MIS_BITMAP | A bitmap instead of text |
MIS_TEXT | A text string. |
MIS_BUTTONSEPARATOR | Creates a menu item that is separate from the other menus. Is placed on the far right on a menu bar and as the last item in a pull-down menu. A vertical separator is drawn between this item and the previous items. |
MIS_BREAK | Creates a new row (on a menu bar) or a new column (on a pull-down menu). |
MIS_BREAKSEPARATOR | Just like MIS_BREAK, except that a line is drawn between the new row or column. |
MIS_SYSCOMMAND | Notifies the owner through a WM_SYSCOMMAND message rather than a WM_COMMAND message. |
MIS_OWNERDRAW | Creates an owner-drawn menu item; WM_DRAWITEM messages are sent whenever the menu item is to be drawn. |
MIS_HELP | Sends a WM_HELP message to its owner, rather than a WM_COMMAND message. |
MIS_STATIC | Creates an unselectable menu item that should be used for information purposes only. |
The following example program shows how to create a pull-down menu. When the menu item is selected a message box is displayed containing information about the selected item.
MENU.C
MENU.RC
MENU.H
MENU.MAK
MENU.DEF
MENU RES_CLIENTThe MENU keyword in a resource file indicates that a menu is being defined. The next word is the resource ID, RES_CLIENT. All resources including icons, accelerator cables, and menus, that are attached to the frame window share the same resource ID. This resource ID will automatically attach all resources indicated by the FCF_* flags used in WinCreateStdWindow. This can cause the function to fail if a resource is defined with the FCF_ flag and not in the .RC file.
MENU RES_FRAMEThe \t character on the MENUITEM indicate that a tab is placed between the next and the text that follows. The text following the tab is the information on the accelerator key. Just because we have defined the menu text to indicate an accelerator key does not guarantee its existence.
{
SUBMENU "~Menu", IDM_SUB1
{
MENUITEM "~Checked\tAlt+C", IDM_ITEM1, MIS_TEXT, MIA_CHECKED
MENUITEM "~Framed\tAlt+F", IDM_ITEM2, MIS_TEXT, MIA_FRAMED
MENUITEM "~Text\tAlt+T", IDM_ITEM3, MIS_TEXT
MENUITEM SEPARATOR
MENUITEM "", IDM_BITMAP
}
SUBMENU "~Edit", IDM_EDIT
{
MENUITEM "~Cut", IDM_CUT
MENUITEM "C~opy", IDM_COPY
MENUITEM "~Paste", IDM_PASTE, MIS_TEXT, MIA_DISABLED
}
MENUITEM "F1=Help", IDM_HELP, MIS_HELP | MIS_BUTTONSEPARATOR
}
The options after the resource IDs arc the menu item styles. A comma is used to separate the styles from the menu item attributes. Attributes are used to describe the state of a menu item and are designed to be turned on and off on the fly. The previous example program contains examples of five different kinds of menu items: Checked, Text, Framed, Bitmap, and Disabled. A menu item that is checked or unchecked is an example of a menu item attribute. The attributes specified in Table 14.4 are available.
Item Attribute | Description |
MIA_HILITED | The menu item is selected |
MIA_CHECKED | A check will appear next to this menu item if TRUE |
MIA_DISABLED | The menu item will appear in grayed, disabled state. |
MIA_FRAMED | The menu item is enclosed within a frame |
MIA_NODISMISS | The pull-down menu containing this menu item will not be dismissed until told to do so. |
hbmBitmap = GpiLoadBitmap(hpsWnd,
NULLHANDLE,
IDB_BITMAP,
32,
32);
For more information on GpiLoadBitmap see Chapter
12.
The bitmap handle, hbmBitmap, is returned from GpiLoadBitmap.
typedef struct _MENUITEM /* mi */
{ SHORT iPosition;
USHORT afStyle;
USHORT afAttribute;
USHORT id;
HWND hwndSubMenu;
ULONG hItem;
} MENUITEM;
typedef MENUITEM *PMENUITEM;
A MENUITEM structure is used to tell the menu how this menu item is to appear. As always when passing structures, all fields must be initialized. For the menu item style, we use MIS_BITMAP. The ID is IDM_BITMAP. hItem is the handle to the item-in this case, hbmBitmap.
miItem.iPosition = 0;
miItem.afStyle = MIS_BITMAP;
miItem.afAttribute = 0;
miItem.id = IDM_BITMAP;
miItem.hwndSubMenu = NULLHANDLE;
miItem.hItem = hbmBitmap;
In the MENU.RC file, a spot was created for the IBM_BITMAP menu item. The MM_SETITEM message is sent to finish the job.
WinSendMsg(hwndMenu,
MM_SETITEM,
MPFROM2SHORT(0, TRUE),
MPFROMP(&miItem));
mpParam1 is composed of two USHORTS. The first is always O
and the second
is a flag indicating that submenus are to be included in the search. We
do want to include submenus. The second message parameter is a pointer
to the MENUITEM structure.
case WM_COMMAND :
switch (SHORT1FROMMP(mpParm1))
{
case
IDM_ITEM1 :
case
IDM_ITEM2 :
case
IDM_ITEM3 :
case
IDM_BITMAP:
case
IDM_CUT :
case
IDM_COPY :
{
HWND
hwndFrame;
HWND
hwndMenu;
USHORT
usAttr;
MRESULT mrReply;
CHAR
achText[64];
hwndFrame = WinQueryWindow(hwndClient,
QW_PARENT);
hwndMenu = WinWindowFromID(hwndFrame,
FID_MENU);
The menu hem ID is contained in mpParam1 of the WM_COMMAND message. After the ID is obtained, we obtain the menu window handle. The menu handle is used later. WinWindowFromID will return the menu window handle when the special ID, FID_MENU, is used. The first parameter is the parent of the menu, the frame window.
if (SHORT1FROMMP(mpParm1) == IDM_ITEM1)
{
mrReply = WinSendMsg(hwndMenu,
MM_QUERYITEMATTR,
MPFROM2SHORT(IDM_ITEM1,
TRUE),
MPFROMSHORT(MIA_CHECKED
));
usAttr = SHORT1FROMMR(mrReply);
If the menu item ID is IDM_ITEM1, we query whether the MIA_CHECKED bit is set, using the message MM_QUERYITEMATTR. mpParm1 consists of two USHORTS. The lower bytes are the menu item ID to query, IDM_ITEM1. The upper bytes indicate whether to include submenus. This is applicable when you want to query all menu items on a pull-down, or sublevel, menu. mpParam2 is the attribute mask for the query. We want to know only whether the MIA_CHECKED bit is set, so this will be the mask we use. A mask can be a collection of attributes OR'ed together or only one. The value of the bit is returned in the variable usAttr.
usAttr ^= MIA_CHECKED;
Once we know whether the menu item is checked, we want to reverse the
state of the MIA_CHECKED bit in order to toggle the check mark.
if (usAttr != 0)
{
strcpy(achText,
" ~Checked item\tAlt + C");
} else {
strcpy(achText,
" ~Unchecked item\tAlt + C");
}
/*
endif
*/
WinSendMsg(hwndMenu,
MM_SETITEMATTR,
MPFROM2SHORT(IDM_ITEM1,
TRUE),
MPFROM2SHORT(MIA_CHECKED,
usAttr));
WinSendMsg(hwndMenu,
MM_SETITEMTEXT,
MPFROMSHORT(IDM_ITEM1),
MPFROMP(achText));
The next thing to do is to set the menu with the new menu item
state,
and also update the menu item text to reflect the change. The checked
state
is determined by AND'ing usAttr and MIA_CHECKED. The message
MM_SETITEMTEXT
is used to set the menu item text to the new string. mpParm1 is
set to the menu item ID, IDM_ITEM1. mpParm2 is a pointer to the
next string. The message MM_SETITEMATTR is used to set the menu item
attribute
to the new value in usAttr. The message parameters are
equivalent
to the MM_QUERYITEMATTR message parameters, except that MM_SETITEMATTR
has an extra SHORT in mpParam2 that contains attribute
data.
After the user selects a menu item, a message box is popped up do
display
various bits of information about the menu item. The menu item
attributes
are found using MM_QUERYITEMATTR. Instead of using just one menu item
attribute
mask, the values MIA_NODISMISS, MIA_FRAMED, MIA_CHECKED, MIA_DISABLED,
and
MIA_HILITED are OR'ed together.
usAllStyles = MIA_NODISMISS | MIA_FRAMED | MIA_CHECKED |
MIA_DISABLED | MIA_HILITED;
usAttr = SHORT1FROMMR(WinSendMsg(hwndMenu,
MM_QUERYITEMATTR,
MPFROM2SHORT(usMenuItem, TRUE),
MPFROMSHORT(usAllStyles)));
usSzText = SHORT1FROMMR(WinSendMsg(hwndMenu,The return from the message will yield the state of all these attributes OR'ed together. MM_QUERYITEMTEXT is used to query the menu item text. mpParm1 is two USHORTS. The lower bytes contain the menu item ID; the upper bytes contain the length of the text input buffer, achItemText. The second message parameter is a pointer to the text input buffer.
MM_QUERYITEMTEXT,
MPFROM2SHORT(usMenuItem, 30),
MPFROMP(achItemText)));
POPUP.C
POPUP.RC
POPUP.H
POPUP.MAK
POPUP.DEF
pmdMenuData = malloc(sizeof(MENUDATA));The pop-up menu is created almost exactly as a regular menu is. The pop-up template contains the same keywords and definitions as regular pull-down template. When the client window is being created (the WM_CREATE processing), the menu template is loaded.
WinSetWindowPtr(hwndClient,
0,
pmdMenuData);
pmdMenuData->hwndMenu = WinLoadMenu(hwndClient,
NULLHANDLE,
IDM_POPUP);
pmdMenuData->hptrFileIcon = WinLoadFileIcon ("POPUP.EXE", FALSE);One of the functions introduced in OS/2 2.0 is WinLoadFileIcon. This is a nifty function to "fit" an icon from some file to use in a program. This example takes the file icon associated with itself and paints it on the client window.
HPOINTER APIENTRY WinLoadFileIcon(PCSZ pszFileName,WinLoadFileIcon has two parameters. The first is the file name. The second is a flag that indicates whether the icon needs to be "public" or "private". A "public" icon is much easier on system resources, but it is a read-only version of the icon. A pointer handle, hptrFileIcon, to the icon is returned. Onces again, the handle is stored in the client's window word for future use.
BOOL fPrivate);
Flag | Description |
PU_POSITIONONITEM |
Will cause the ID specified in the previous parameter to
appear
directly above where the mouse pointer is. This flag overrides the x, y
coordinates as placement of the menu. it also causes the specified menu
item ID to appear selected when the pop-up menu appears. |
PU_KEYBOARD |
Lets the user use the keyboard keys to traverse the menu
choices and select an item. |
PU_MOUSEBUTTON2 | Enables the user to use mouse button 2 to select a menu item. |
PU_MOUSEBUTTON1 | Enables the user to use mouse button 1 to select a menu item. |
Gotcha! For pop-up menus, the WM_INITMENU documentation does not state that the menu identifier for top-level menu will be FID_MENU |
[ Next ] [ Previous ] | Chapter 14 |