|
|
Microsoft Windows NT Build 297 06-28-1992
/* This is a document showing Menus.c commented with PM information. */
/* Menus.c is a combination of many of the menu functionality */
/* available under PM. It shows cascaded menus, how to disable a */
/* menu item through its attributes, how to check menu items through */
/* their attributes, how to display bitmaps in menus, how to create */
/* popup menus, how to change menus on the fly, and how to create new */
/* menu items on the fly. */
#define INCL_WINMESSAGEMGR
#define INCL_WIN
#define INCL_GPI
#define INCL_WINDIALOGS
#include <os2.h>
#include "menus.h"
#include "string.h"
#include "stdio.h"
#include "stdlib.h"
MRESULT EXPENTRY ClientWndProc (HWND, USHORT, MPARAM, MPARAM);
int main (void)
{
static CHAR szClientClass [] = "menus";
static ULONG flFrameFlags = FCF_TITLEBAR | FCF_SYSMENU |
FCF_SIZEBORDER | FCF_MINMAX |
FCF_SHELLPOSITION | FCF_TASKLIST |
FCF_MENU | FCF_ACCELTABLE ;
HAB hab;
HMQ hmq;
HWND hwndFrame, hwndClient;
QMSG qmsg;
hab = WinInitialize (0);
hmq = WinCreateMsgQueue (hab, 0);
WinRegisterClass (
hab, // Anchor Block handle
szClientClass, // Name of class being registered
ClientWndProc, // Window procedure for class
CS_SIZEREDRAW, // Class style
0); // Extra bytes to reserve
hwndFrame = WinCreateStdWindow (
HWND_DESKTOP, // Parent of Window handle
WS_VISIBLE, // Style of frame window
&flFrameFlags, // Pointer to control data
szClientClass, // Client window class name
NULL, // Title bar text
0L, // Style of Client Window
0, // Module of handle for resources
ID_RESOURCE, // ID of resources
&hwndClient); // Pointer to client window handle
WinSendMsg (hwndFrame, WM_SETICON,
WinQuerySysPointer (HWND_DESKTOP, SPTR_APPICON, FALSE),
NULL);
WinSetWindowText (hwndFrame, "Menus Code for PM Apps");
while (WinGetMsg (hab, &qmsg, NULL, 0, 0))
WinDispatchMsg (hab, &qmsg);
WinDestroyWindow (hwndFrame);
WinDestroyMsgQueue (hmq);
WinTerminate (hab);
return 0;
}
/********************** ClientWndProc **************************/
MRESULT EXPENTRY ClientWndProc (HWND hwnd, USHORT msg,
MPARAM mp1, MPARAM mp2)
{
/* Used in switching menus. */
static HWND hwndFrame; // Handle to the window frame.
static HWND hwndMenu; // Handle to the original menu.
static HWND hwndMenuAlt; // Handle to the switched to menu.
/* Used in the popup menu. */
static HWND hwndMenuPopup; // Handle to the popup menu.
HPS hps; // These 3 variables are used in
RECTL rcl; // in locating the popup menu.
POINTL ptlMouse ;
/* Used in enable/disable and checking menu items. */
SHORT sState; // Used to toggle 'checked' and
// 'enabled' menu item state.
/* Used in adding menu items on the fly. */
HWND hSubMenu; // Handle to added menu item.
MENUITEM mi; // Structure to define new menu item.
static USHORT ActionBarID = 1000; // Used to identify new menu item.
static USHORT SubMenuID = 6000; // Used to identify new sub menu item.
CHAR buffer[10]; // Holds text string for menu item.
MENUCREATETEMPLATE mt; // See type definition in menus.h
switch (msg)
{
case WM_CREATE:
/* During the create, the 3 menus are loaded: the original */
/* "Cascade Sample Microsoft *Button2 Up Shows Popup Menus"; */
/* the popup menu; and the second menu used to switch to */
/* "MenuItems". */
/* Loading the popup menu. */
hwndMenuPopup = WinLoadMenu (hwnd, 0, ID_POPUP) ;
WinSetWindowPos (hwndMenuPopup, NULL,
0, 0, 0, 0, SWP_SIZE) ;
WinSetParent (hwndMenuPopup, HWND_DESKTOP, FALSE) ;
/* Setting the original menu's owner to HWND_OBJECT to make it */
/* make it disappear. Then loading the second menu, and then */
/* setting it's parent to be HWND_OBJECT to make it disappear. */
/* And finally setting the original menu's parent to be the */
/* window frame again to make it visible. */
hwndFrame = WinQueryWindow(hwnd, QW_PARENT,FALSE);
hwndMenu = WinWindowFromID (hwndFrame, FID_MENU);
WinSetParent(hwndMenu, HWND_OBJECT, TRUE);
hwndMenuAlt = WinLoadMenu( hwndFrame, 0, ID_ALTERNATE);
WinSetParent(hwndMenuAlt, HWND_OBJECT, TRUE);
WinSetParent(hwndMenu, hwndFrame, TRUE);
return 0;
case WM_COMMAND:
switch (COMMANDMSG(&msg)->cmd)
{
case IDM_ALT_ADD:
/* From the second menu, when the user chooses to add a new */
/* menu item, this is done on the fly. In general you create*/
/* a menu, and then insert it. The menu is created with */
/* WinCreateMenu using control data in the form of the */
/* Resource Type Menu (RT_MENU), or menu creation template. */
/* The menu is inserted with a MM_INSERTITEM and a MENUITEM */
/* sturcture. */
/* Filling out the menu template, using many defaults. */
mt.size = 0;
mt.version = 0;
mt.codepage = 0;
mt.mnemonic = 0;
mt.itemcount = 1;
mt.item[0].afStyle = MIS_TEXT;
mt.item[0].afAttribute = 0;
mt.item[0].id = SubMenuID;
strcpy(mt.item[0].text,
itoa(SubMenuID++,buffer,10));
/* Create a popup menu using template information. */
hSubMenu = WinCreateMenu( hwndMenuAlt, &mt);
/* Filling out the MENUITEM structure. */
mi.iPosition = MIT_END;
mi.afStyle = MIS_TEXT | MIS_SUBMENU;
mi.afAttribute = 0;
mi.id = ActionBarID;
mi.hwndSubMenu = hSubMenu;
mi.hItem = 0;
/* Inserting the new item. */
WinSendMsg(hwndMenuAlt,MM_INSERTITEM,(MPARAM)&mi,
(MPARAM)(PCH)itoa(ActionBarID++,buffer,10));
break;
case IDM_SWITCH:
/* From the original menu, when the user chooses to switch */
/* to the second menu: Set the first menu's parent to be */
/* HWND_OBJECT to make it disappear, set the second menu's */
/* parent to be the window frame, and then post an update */
/* message telling the frame to redraw. */
WinSetParent(hwndMenu, HWND_OBJECT, TRUE);
WinSetParent(hwndMenuAlt, hwndFrame, TRUE);
WinPostMsg (hwndFrame, WM_UPDATEFRAME,
MPFROMSHORT(FCF_MENU), 0L);
break;
case IDM_ALT_SWITCH:
/* From the second menu, when the user chooses to switch */
/* back; follow the same procedure as demonstrated for */
/* case IDM_SWITCH: */
WinSetParent(hwndMenuAlt, HWND_OBJECT, TRUE);
WinSetParent(hwndMenu, hwndFrame, TRUE);
WinPostMsg (hwndFrame, WM_UPDATEFRAME,
MPFROMSHORT(FCF_MENU), 0L);
break;
case IDM_DISABLE:
/* From the original menu, when the user chooses to disable */
/* the cascading menu items, the "Disable Cascade" sub-menu */
/* item is checked, and the "Cascade" sub-menu item and its */
/* cascaded items are grayed out and disabled. The user can */
/* reactivate it by selecting "Disable Cascade" again. To */
/* toggle a menu items MIA_* attribute state, query its state*/
/* using MM_QUERYITEMATTR. Toggle the value using the found */
/* state and XORing it with the chosen MIA_* value, and then */
/* reset the attribute value with MM_SETITEMATTR. */
/* Toggling the check on "Disable Cascade". */
(MRESULT)sState = WinSendMsg( hwndMenu,
MM_QUERYITEMATTR,
MPFROM2SHORT(IDM_DISABLE, TRUE),
MPFROMSHORT(MIA_CHECKED));
sState ^= MIA_CHECKED;
WinSendMsg(hwndMenu,
MM_SETITEMATTR,
MPFROM2SHORT(IDM_DISABLE, TRUE),
MPFROM2SHORT(MIA_CHECKED, sState));
/* Toggling the enable for "Cascade". */
(MRESULT)sState = WinSendMsg( hwndMenu,
MM_QUERYITEMATTR,
MPFROM2SHORT(IDM_SUB3, TRUE),
MPFROMSHORT(MIA_DISABLED));
sState ^= MIA_DISABLED;
WinSendMsg(hwndMenu,
MM_SETITEMATTR,
MPFROM2SHORT(IDM_SUB3, TRUE),
MPFROM2SHORT(MIA_DISABLED, sState));
break;
default:
/* A catch all default which explains that the action menu */
/* items have no functionality. */
WinAlarm(HWND_DESKTOP, WA_NOTE);
WinMessageBox (HWND_DESKTOP, hwnd,
"This item has no functionality.",
"PM Menus Code",
0, MB_OK | MB_ICONASTERISK );
break;
}
case WM_PAINT:
/* A simple client space paint. */
hps = WinBeginPaint (hwnd, NULL, NULL);
GpiErase (hps);
WinQueryWindowRect (hwnd, &rcl);
WinEndPaint (hps);
return 0;
case WM_BUTTON2UP:
/* When the user activates the popup menu with the Button2Up, */
/* First query the position of the mouse, display the popup menu */
/* using the WinSetWindowPos, and then capture the mouse to this */
/* window. */
WinQueryPointerPos (HWND_DESKTOP, &ptlMouse) ;
ptlMouse.y += WinQuerySysValue (HWND_DESKTOP, SV_CYMENU) ;
WinSetWindowPos (hwndMenuPopup, HWND_TOP,
(SHORT) ptlMouse.x, (SHORT) ptlMouse.y,
0, 0, SWP_MOVE | SWP_SHOW) ;
WinSendMsg (hwndMenuPopup, MM_SELECTITEM,
MPFROM2SHORT (IDM_POPUP, FALSE),
MPFROMSHORT (FALSE)) ;
WinSetCapture (HWND_DESKTOP, hwndMenuPopup) ;
return 0 ;
case WM_HELP:
WinMessageBox (HWND_DESKTOP, hwnd, "Help Message Box",
"PM Menus Code", 0,
MB_OK | MB_ICONASTERISK);
break;
case WM_DESTROY:
return 0;
}
return WinDefWindowProc (hwnd, msg, mp1, mp2);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.