|
|
1.1 root 1: /* This is a document showing Menus.c commented with PM information. */
2: /* Menus.c is a combination of many of the menu functionality */
3: /* available under PM. It shows cascaded menus, how to disable a */
4: /* menu item through its attributes, how to check menu items through */
5: /* their attributes, how to display bitmaps in menus, how to create */
6: /* popup menus, how to change menus on the fly, and how to create new */
7: /* menu items on the fly. */
8:
9: #define INCL_WINMESSAGEMGR
10: #define INCL_WIN
11: #define INCL_GPI
12: #define INCL_WINDIALOGS
13: #include <os2.h>
14: #include "menus.h"
15:
16: #include "string.h"
17: #include "stdio.h"
18: #include "stdlib.h"
19:
20: MRESULT EXPENTRY ClientWndProc (HWND, USHORT, MPARAM, MPARAM);
21:
22: int main (void)
23: {
24: static CHAR szClientClass [] = "menus";
25: static ULONG flFrameFlags = FCF_TITLEBAR | FCF_SYSMENU |
26: FCF_SIZEBORDER | FCF_MINMAX |
27: FCF_SHELLPOSITION | FCF_TASKLIST |
28: FCF_MENU | FCF_ACCELTABLE ;
29: HAB hab;
30: HMQ hmq;
31: HWND hwndFrame, hwndClient;
32: QMSG qmsg;
33:
34: hab = WinInitialize (0);
35: hmq = WinCreateMsgQueue (hab, 0);
36:
37: WinRegisterClass (
38: hab, // Anchor Block handle
39: szClientClass, // Name of class being registered
40: ClientWndProc, // Window procedure for class
41: CS_SIZEREDRAW, // Class style
42: 0); // Extra bytes to reserve
43:
44: hwndFrame = WinCreateStdWindow (
45: HWND_DESKTOP, // Parent of Window handle
46: WS_VISIBLE, // Style of frame window
47: &flFrameFlags, // Pointer to control data
48: szClientClass, // Client window class name
49: NULL, // Title bar text
50: 0L, // Style of Client Window
51: 0, // Module of handle for resources
52: ID_RESOURCE, // ID of resources
53: &hwndClient); // Pointer to client window handle
54:
55: WinSendMsg (hwndFrame, WM_SETICON,
56: WinQuerySysPointer (HWND_DESKTOP, SPTR_APPICON, FALSE),
57: NULL);
58:
59: WinSetWindowText (hwndFrame, "Menus Code for PM Apps");
60:
61:
62: while (WinGetMsg (hab, &qmsg, NULL, 0, 0))
63: WinDispatchMsg (hab, &qmsg);
64:
65: WinDestroyWindow (hwndFrame);
66: WinDestroyMsgQueue (hmq);
67: WinTerminate (hab);
68: return 0;
69: }
70:
71: /********************** ClientWndProc **************************/
72:
73: MRESULT EXPENTRY ClientWndProc (HWND hwnd, USHORT msg,
74: MPARAM mp1, MPARAM mp2)
75: {
76: /* Used in switching menus. */
77: static HWND hwndFrame; // Handle to the window frame.
78: static HWND hwndMenu; // Handle to the original menu.
79: static HWND hwndMenuAlt; // Handle to the switched to menu.
80:
81: /* Used in the popup menu. */
82: static HWND hwndMenuPopup; // Handle to the popup menu.
83: HPS hps; // These 3 variables are used in
84: RECTL rcl; // in locating the popup menu.
85: POINTL ptlMouse ;
86:
87: /* Used in enable/disable and checking menu items. */
88: SHORT sState; // Used to toggle 'checked' and
89: // 'enabled' menu item state.
90:
91: /* Used in adding menu items on the fly. */
92: HWND hSubMenu; // Handle to added menu item.
93: MENUITEM mi; // Structure to define new menu item.
94: static USHORT ActionBarID = 1000; // Used to identify new menu item.
95: static USHORT SubMenuID = 6000; // Used to identify new sub menu item.
96: CHAR buffer[10]; // Holds text string for menu item.
97: MENUCREATETEMPLATE mt; // See type definition in menus.h
98:
99:
100: switch (msg)
101: {
102: case WM_CREATE:
103: /* During the create, the 3 menus are loaded: the original */
104: /* "Cascade Sample Microsoft *Button2 Up Shows Popup Menus"; */
105: /* the popup menu; and the second menu used to switch to */
106: /* "MenuItems". */
107:
108:
109: /* Loading the popup menu. */
110: hwndMenuPopup = WinLoadMenu (hwnd, 0, ID_POPUP) ;
111: WinSetWindowPos (hwndMenuPopup, NULL,
112: 0, 0, 0, 0, SWP_SIZE) ;
113: WinSetParent (hwndMenuPopup, HWND_DESKTOP, FALSE) ;
114:
115: /* Setting the original menu's owner to HWND_OBJECT to make it */
116: /* make it disappear. Then loading the second menu, and then */
117: /* setting it's parent to be HWND_OBJECT to make it disappear. */
118: /* And finally setting the original menu's parent to be the */
119: /* window frame again to make it visible. */
120:
121: hwndFrame = WinQueryWindow(hwnd, QW_PARENT,FALSE);
122: hwndMenu = WinWindowFromID (hwndFrame, FID_MENU);
123: WinSetParent(hwndMenu, HWND_OBJECT, TRUE);
124: hwndMenuAlt = WinLoadMenu( hwndFrame, 0, ID_ALTERNATE);
125: WinSetParent(hwndMenuAlt, HWND_OBJECT, TRUE);
126: WinSetParent(hwndMenu, hwndFrame, TRUE);
127: return 0;
128:
129: case WM_COMMAND:
130: switch (COMMANDMSG(&msg)->cmd)
131: {
132: case IDM_ALT_ADD:
133: /* From the second menu, when the user chooses to add a new */
134: /* menu item, this is done on the fly. In general you create*/
135: /* a menu, and then insert it. The menu is created with */
136: /* WinCreateMenu using control data in the form of the */
137: /* Resource Type Menu (RT_MENU), or menu creation template. */
138: /* The menu is inserted with a MM_INSERTITEM and a MENUITEM */
139: /* sturcture. */
140:
141: /* Filling out the menu template, using many defaults. */
142: mt.size = 0;
143: mt.version = 0;
144: mt.codepage = 0;
145: mt.mnemonic = 0;
146: mt.itemcount = 1;
147: mt.item[0].afStyle = MIS_TEXT;
148: mt.item[0].afAttribute = 0;
149: mt.item[0].id = SubMenuID;
150: strcpy(mt.item[0].text,
151: itoa(SubMenuID++,buffer,10));
152:
153: /* Create a popup menu using template information. */
154: hSubMenu = WinCreateMenu( hwndMenuAlt, &mt);
155:
156: /* Filling out the MENUITEM structure. */
157: mi.iPosition = MIT_END;
158: mi.afStyle = MIS_TEXT | MIS_SUBMENU;
159: mi.afAttribute = 0;
160: mi.id = ActionBarID;
161: mi.hwndSubMenu = hSubMenu;
162: mi.hItem = 0;
163:
164: /* Inserting the new item. */
165: WinSendMsg(hwndMenuAlt,MM_INSERTITEM,(MPARAM)&mi,
166: (MPARAM)(PCH)itoa(ActionBarID++,buffer,10));
167: break;
168:
169:
170: case IDM_SWITCH:
171: /* From the original menu, when the user chooses to switch */
172: /* to the second menu: Set the first menu's parent to be */
173: /* HWND_OBJECT to make it disappear, set the second menu's */
174: /* parent to be the window frame, and then post an update */
175: /* message telling the frame to redraw. */
176:
177: WinSetParent(hwndMenu, HWND_OBJECT, TRUE);
178: WinSetParent(hwndMenuAlt, hwndFrame, TRUE);
179: WinPostMsg (hwndFrame, WM_UPDATEFRAME,
180: MPFROMSHORT(FCF_MENU), 0L);
181: break;
182:
183: case IDM_ALT_SWITCH:
184: /* From the second menu, when the user chooses to switch */
185: /* back; follow the same procedure as demonstrated for */
186: /* case IDM_SWITCH: */
187:
188: WinSetParent(hwndMenuAlt, HWND_OBJECT, TRUE);
189: WinSetParent(hwndMenu, hwndFrame, TRUE);
190: WinPostMsg (hwndFrame, WM_UPDATEFRAME,
191: MPFROMSHORT(FCF_MENU), 0L);
192: break;
193:
194: case IDM_DISABLE:
195: /* From the original menu, when the user chooses to disable */
196: /* the cascading menu items, the "Disable Cascade" sub-menu */
197: /* item is checked, and the "Cascade" sub-menu item and its */
198: /* cascaded items are grayed out and disabled. The user can */
199: /* reactivate it by selecting "Disable Cascade" again. To */
200: /* toggle a menu items MIA_* attribute state, query its state*/
201: /* using MM_QUERYITEMATTR. Toggle the value using the found */
202: /* state and XORing it with the chosen MIA_* value, and then */
203: /* reset the attribute value with MM_SETITEMATTR. */
204:
205: /* Toggling the check on "Disable Cascade". */
206: (MRESULT)sState = WinSendMsg( hwndMenu,
207: MM_QUERYITEMATTR,
208: MPFROM2SHORT(IDM_DISABLE, TRUE),
209: MPFROMSHORT(MIA_CHECKED));
210:
211: sState ^= MIA_CHECKED;
212:
213: WinSendMsg(hwndMenu,
214: MM_SETITEMATTR,
215: MPFROM2SHORT(IDM_DISABLE, TRUE),
216: MPFROM2SHORT(MIA_CHECKED, sState));
217:
218:
219: /* Toggling the enable for "Cascade". */
220: (MRESULT)sState = WinSendMsg( hwndMenu,
221: MM_QUERYITEMATTR,
222: MPFROM2SHORT(IDM_SUB3, TRUE),
223: MPFROMSHORT(MIA_DISABLED));
224:
225: sState ^= MIA_DISABLED;
226:
227: WinSendMsg(hwndMenu,
228: MM_SETITEMATTR,
229: MPFROM2SHORT(IDM_SUB3, TRUE),
230: MPFROM2SHORT(MIA_DISABLED, sState));
231: break;
232:
233:
234: default:
235: /* A catch all default which explains that the action menu */
236: /* items have no functionality. */
237:
238: WinAlarm(HWND_DESKTOP, WA_NOTE);
239: WinMessageBox (HWND_DESKTOP, hwnd,
240: "This item has no functionality.",
241: "PM Menus Code",
242: 0, MB_OK | MB_ICONASTERISK );
243: break;
244: }
245:
246: case WM_PAINT:
247: /* A simple client space paint. */
248:
249: hps = WinBeginPaint (hwnd, NULL, NULL);
250: GpiErase (hps);
251: WinQueryWindowRect (hwnd, &rcl);
252: WinEndPaint (hps);
253: return 0;
254:
255:
256: case WM_BUTTON2UP:
257: /* When the user activates the popup menu with the Button2Up, */
258: /* First query the position of the mouse, display the popup menu */
259: /* using the WinSetWindowPos, and then capture the mouse to this */
260: /* window. */
261:
262: WinQueryPointerPos (HWND_DESKTOP, &ptlMouse) ;
263:
264: ptlMouse.y += WinQuerySysValue (HWND_DESKTOP, SV_CYMENU) ;
265:
266: WinSetWindowPos (hwndMenuPopup, HWND_TOP,
267: (SHORT) ptlMouse.x, (SHORT) ptlMouse.y,
268: 0, 0, SWP_MOVE | SWP_SHOW) ;
269:
270: WinSendMsg (hwndMenuPopup, MM_SELECTITEM,
271: MPFROM2SHORT (IDM_POPUP, FALSE),
272: MPFROMSHORT (FALSE)) ;
273:
274: WinSetCapture (HWND_DESKTOP, hwndMenuPopup) ;
275: return 0 ;
276:
277:
278:
279:
280: case WM_HELP:
281: WinMessageBox (HWND_DESKTOP, hwnd, "Help Message Box",
282: "PM Menus Code", 0,
283: MB_OK | MB_ICONASTERISK);
284: break;
285:
286: case WM_DESTROY:
287: return 0;
288: }
289: return WinDefWindowProc (hwnd, msg, mp1, mp2);
290: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.