|
|
1.1 root 1: /******************************Module*Header*******************************\
2: * Module Name: mdi.c
3: *
4: * MDI demonstration
5: * + Associating data with a MDI window (using Set/GetWindowLong )
6: *
7: * Created: 24-Oct-1991 18:34:08
8: * Author: Petrus Wong []
9: *
10: * Copyright (c) 1990 Microsoft Corporation
11: *
12: * Dependencies:
13: *
14: * (#defines)
15: * (#includes)
16: * MDI.H
17: *
18: \**************************************************************************/
19: #define STRICT
20: #include <stdlib.h>
21: #include "mdi.h"
22: #include <stdarg.h>
23:
24: HANDLE ghModule;
25: HWND ghwndMain = NULL;
26: HWND ghwndClient = NULL;
27:
28: HMENU hMenu, hMenuWindow;
29: HMENU hChildMenu, hChildMenuWindow;
30:
31: CHAR gszFile[20];
32: CHAR gszMapName[20];
33:
34: //
35: // Instance data for each MDI child window
36: //
37: typedef struct _PerWndInfo {
38: HWND hParent;
39: HWND hTextWnd;
40: RECT rcClient;
41: char CaptionBarText[SIZEOFCAPTIONTEXT];
42: } INFO, *PINFO;
43:
44: //
45: // Forward declarations.
46: //
47: BOOL InitializeApp (void);
48: LONG MainWndProc (HWND, UINT, DWORD, LONG);
49: LONG MDIWndProc (HWND, UINT, DWORD, LONG);
50: LONG About (HWND, UINT, DWORD, LONG);
51: LONG TextWndProc (HWND, UINT, DWORD, LONG);
52: VOID vTest (PINFO);
53:
54: /***************************************************************************\
55: * WinMain
56: *
57: *
58: * History:
59: * 11-Feb-1992 Petrus Wong []
60: * Added conditional compile statement for internal build environment.
61: * 04-17-91 ???? Created.
62: \***************************************************************************/
63: int WinMain(
64: HANDLE hInstance,
65: HANDLE hPrevInstance,
66: LPSTR lpCmdLine,
67: int nShowCmd)
68: {
69: MSG msg;
70: HANDLE hAccel;
71:
72: ghModule = GetModuleHandle(NULL);
73: if (!InitializeApp()) {
74: MessageBox(ghwndMain, "MDI: InitializeApp failure!", "Error", MB_OK);
75: return 0;
76: }
77:
78: if (!(hAccel = LoadAccelerators (ghModule, MAKEINTRESOURCE(ACCEL_ID))))
79: MessageBox(ghwndMain, "MDI: Load Accel failure!", "Error", MB_OK);
80:
81:
82: while (GetMessage(&msg, NULL, 0, 0)) {
83: if (!TranslateAccelerator( ghwndMain, hAccel, &msg) &&
84: !TranslateMDISysAccel( ghwndClient, &msg) ) {
85: TranslateMessage(&msg);
86: DispatchMessage(&msg);
87: }
88: }
89:
90: return 1;
91:
92: UNREFERENCED_PARAMETER(lpCmdLine);
93: UNREFERENCED_PARAMETER(nShowCmd);
94: UNREFERENCED_PARAMETER(hInstance);
95: UNREFERENCED_PARAMETER(hPrevInstance);
96: }
97:
98:
99: /***************************************************************************\
100: * InitializeApp
101: *
102: * History:
103: * 11-Feb-1992 Petrus Wong []
104: * Name changes.
105: * 09-09-91 Created.
106: \***************************************************************************/
107:
108: BOOL InitializeApp(void)
109: {
110: WNDCLASS wc;
111:
112: wc.style = CS_OWNDC;
113: wc.lpfnWndProc = (WNDPROC) MainWndProc;
114: wc.cbClsExtra = 0;
115: wc.cbWndExtra = sizeof(LONG);
116: wc.hInstance = ghModule;
117: wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
118: wc.hCursor = LoadCursor(NULL, IDC_ARROW);
119: wc.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE);
120: wc.lpszMenuName = "MainMenu";
121: wc.lpszClassName = "MDIDemoClass";
122:
123: if (!RegisterClass(&wc))
124: return FALSE;
125:
126: wc.lpfnWndProc = (WNDPROC) MDIWndProc;
127: wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
128: wc.lpszMenuName = NULL;
129: wc.lpszClassName = "MDIClass";
130:
131: if (!RegisterClass(&wc))
132: return FALSE;
133:
134: wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
135: wc.lpfnWndProc = (WNDPROC) TextWndProc;
136: wc.hIcon = NULL;
137: wc.hCursor = LoadCursor(NULL, IDC_ARROW);
138: wc.hbrBackground = (HBRUSH)(COLOR_BTNSHADOW);
139: wc.lpszMenuName = NULL;
140: wc.lpszClassName = "Text";
141:
142: if (!RegisterClass(&wc))
143: return FALSE;
144:
145:
146:
147: hMenu = LoadMenu(ghModule, "MainMenu");
148: hChildMenu = LoadMenu(ghModule, "ChildMenu");
149: hMenuWindow = GetSubMenu(hMenu, 1);
150: hChildMenuWindow = GetSubMenu(hChildMenu, 2);
151:
152: ghwndMain = CreateWindowEx(0L, "MDIDemoClass", "MDI Demonstration",
153: WS_OVERLAPPED | WS_CAPTION | WS_BORDER |
154: WS_THICKFRAME | WS_MAXIMIZEBOX | WS_MINIMIZEBOX |
155: WS_CLIPCHILDREN | WS_VISIBLE | WS_SYSMENU,
156: 80, 70, 400, 300,
157: NULL, hMenu, ghModule, NULL);
158:
159: if (ghwndMain == NULL)
160: return FALSE;
161:
162: SetWindowLong(ghwndMain, GWL_USERDATA, 0L);
163:
164: SetFocus(ghwndMain); /* set initial focus */
165:
166: return TRUE;
167: }
168:
169:
170: /***************************************************************************\
171: * MainWndProc
172: *
173: * History:
174: * 11-Feb-1992 Petrus Wong []
175: * Name changes. Added comments.
176: * 09-09-91 Created.
177: \***************************************************************************/
178:
179: long MainWndProc(
180: HWND hwnd,
181: UINT message,
182: DWORD wParam,
183: LONG lParam)
184: {
185: static int iMDICount=1;
186: CLIENTCREATESTRUCT clientcreate;
187: HWND hwndChildWindow;
188:
189:
190: switch (message) {
191:
192: case WM_CREATE:
193: SetWindowLong(hwnd, 0, (LONG)NULL);
194:
195: clientcreate.hWindowMenu = hMenuWindow;
196: clientcreate.idFirstChild = 1;
197:
198: ghwndClient = CreateWindow("MDICLIENT", NULL,
199: WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE,
200: 0,0,0,0,
201: hwnd, NULL, ghModule, (LPVOID)&clientcreate);
202: return 0L;
203:
204: case WM_DESTROY: {
205: PostQuitMessage(0);
206: return 0L;
207: }
208:
209: case WM_COMMAND:
210:
211: switch (LOWORD(wParam)) {
212: //
213: // Getting default MDI functionalities...
214: //
215: case IDM_TILE:
216: SendMessage(ghwndClient, WM_MDITILE, 0L, 0L);
217: return 0L;
218: case IDM_CASCADE:
219: SendMessage(ghwndClient, WM_MDICASCADE, 0L, 0L);
220: return 0L;
221: case IDM_ARRANGE:
222: SendMessage(ghwndClient, WM_MDIICONARRANGE, 0L, 0L);
223: return 0L;
224:
225: //
226: // Creates MDI child
227: //
228: case MM_MDI: {
229: HANDLE hInfo;
230: PINFO pInfo;
231: MDICREATESTRUCT mdicreate;
232:
233: //
234: // Allocating memory for INFO to be associated with the
235: // new child
236: //
237: hInfo = LocalAlloc(LHND, (WORD) sizeof(INFO));
238: if (hInfo) {
239: if ((pInfo = (PINFO)LocalLock(hInfo)) == NULL)
240: MessageBox(ghwndMain, "Failed in LocalLock", "Error", MB_OK);
241:
242: wsprintf((LPSTR) &(pInfo->CaptionBarText),
243: "MDI %d", iMDICount);
244: pInfo->hParent = ghwndClient;
245:
246: mdicreate.szClass = "MDIClass";
247: mdicreate.szTitle = (LPTSTR)&(pInfo->CaptionBarText);
248: mdicreate.hOwner = ghModule;
249: mdicreate.x =
250: mdicreate.y =
251: mdicreate.cx =
252: mdicreate.cy = CW_USEDEFAULT;
253: mdicreate.style = 0L;
254: //
255: // passing the handle of the per MDI child INFO to the
256: // child MDI window for storage
257: //
258: mdicreate.lParam = (LONG) hInfo;
259:
260: /*Create Child Window*/
261: hwndChildWindow =
262: (HANDLE) SendMessage(ghwndClient, WM_MDICREATE,
263: 0L,
264: (LONG)(LPMDICREATESTRUCT)&mdicreate);
265:
266: if (hwndChildWindow == NULL) {
267: MessageBox(ghwndMain, "Failed in Creating Child Window", "Error", MB_OK);
268: return 0L;
269: }
270:
271: iMDICount++;
272:
273: LocalUnlock(hInfo);
274: } else {
275: MessageBox(ghwndMain, "Failed to Allocate INFO data!", "Error", MB_OK);
276: }
277: return 0L;
278: }
279:
280:
281: case MM_ABOUT:
282: if (DialogBox(ghModule, "AboutBox", ghwndMain, (DLGPROC)About) == -1)
283: MessageBox(ghwndMain, "DEMO: About Dialog Creation Error!", "Error", MB_OK);
284: return 0L;
285:
286: //
287: // Passes these WM_COMMAND messages to the appropriate active child
288: // window proc for processing
289: //
290: case MM_OPT_1:
291: case MM_OPT_2:
292: case MM_OPT_3:
293: case MM_OPT_4:
294: case MM_OPT_5:
295: case MM_OPT_6:
296: case MM_OPT_7:
297: case MM_OPT_8: {
298: HWND hActiveChild;
299:
300: hActiveChild = (HANDLE) SendMessage(ghwndClient, WM_MDIGETACTIVE, 0L, 0L);
301: if (hActiveChild)
302: SendMessage(hActiveChild, WM_COMMAND, wParam, lParam);
303: return 0L;
304: }
305:
306: default:
307: return DefFrameProc(hwnd, ghwndClient, message, wParam, lParam);
308: }
309:
310: default:
311:
312: return DefFrameProc(hwnd, ghwndClient, message, wParam, lParam);
313: }
314: }
315:
316: /***************************************************************************\
317: * MDIWndProc
318: *
319: * History:
320: * 11-Feb-1992 Petrus Wong []
321: * Name changes. Added comments.
322: * 09-09-91 Petrus Wong Rewrote.
323: * 04-17-91 ???? Created.
324: \***************************************************************************/
325:
326: long MDIWndProc(
327: HWND hwnd,
328: UINT message,
329: DWORD wParam,
330: LONG lParam)
331: {
332:
333: switch (message) {
334: case WM_COMMAND: {
335: HANDLE hInfo;
336: PINFO pInfo;
337: HWND hTextWnd;
338:
339: //
340: // Retrieving this child window's INFO data for displaying
341: // messages in the text window
342: //
343: hInfo = (HANDLE) GetWindowLong(hwnd, 0);
344: if (hInfo) {
345: if ((pInfo = (PINFO)LocalLock(hInfo)) == NULL)
346: MessageBox(ghwndMain, "Failed in LocalLock", "Error", MB_OK);
347:
348: hTextWnd = pInfo->hTextWnd;
349: vTest(pInfo);
350: LocalUnlock(hInfo);
351: } else {
352: MessageBox(ghwndMain, "Can't get hInfo!", "Error", MB_OK);
353: }
354:
355:
356: switch (LOWORD(wParam)) {
357: case MM_OPT_1: {
358: SetWindowText(hTextWnd, "MM_OPT_1");
359: return 0L;
360: }
361:
362: case MM_OPT_2: {
363: SetWindowText(hTextWnd, "MM_OPT_2");
364: return 0L;
365: }
366:
367: case MM_OPT_3: {
368: SetWindowText(hTextWnd, "MM_OPT_3");
369: return 0L;
370: }
371:
372: case MM_OPT_4: {
373: SetWindowText(hTextWnd, "MM_OPT_4");
374: return 0L;
375: }
376: default:
377: return 0L;
378:
379: }
380:
381: }
382: case WM_SETFOCUS:
383: break;
384:
385: //
386: // Potentially, you can set different menu for different MDI
387: // child which is currently being active.
388: //
389: case WM_MDIACTIVATE:
390: if ((HWND) lParam == hwnd) {
391: SendMessage(GetParent(hwnd), WM_MDISETMENU,
392: (DWORD) hChildMenu,
393: (LONG) hChildMenuWindow) ;
394: DrawMenuBar(GetParent(GetParent(hwnd))) ;
395: }
396: return 0L;
397:
398: //
399: // Whenever the MDI child window is resized, its children has to be
400: // resized accordingly.
401: //
402: case WM_SIZE: {
403: HANDLE hInfo;
404: PINFO pInfo;
405: HWND hTextWnd;
406:
407: //
408: // First, get the text window's handle from the per MDI child
409: // INFO data structure
410: //
411: hInfo = (HANDLE) GetWindowLong(hwnd, 0);
412: if (hInfo) {
413: if ((pInfo = (PINFO)LocalLock(hInfo)) == NULL)
414: MessageBox(ghwndMain, "Failed in LocalLock", "Error", MB_OK);
415:
416: hTextWnd = pInfo->hTextWnd;
417: LocalUnlock(hInfo);
418: } else {
419: MessageBox(ghwndMain, "Can't get hInfo!", "Error", MB_OK);
420: }
421:
422: //
423: // Always, put the text window at the bottom of the MDI window
424: //
425: MoveWindow(hTextWnd,
426: 0,
427: HIWORD(lParam) - GetWindowLong(hTextWnd, GWL_USERDATA),
428: LOWORD(lParam),
429: HIWORD(lParam), TRUE);
430: break;
431: }
432:
433: //
434: // Creates the text window for this MDI child and saves its handle
435: // in the per MDI child INFO data structure.
436: //
437: case WM_CREATE: {
438: PINFO pInfo;
439: HANDLE hInfo;
440: HWND hTextWnd;
441:
442: hTextWnd = CreateWindow("Text", NULL,
443: WS_BORDER | SS_LEFT | WS_CHILD | WS_VISIBLE,
444: 0, 0, 0, 0,
445: hwnd,
446: (HMENU) 2,
447: ghModule,
448: NULL);
449:
450: SetWindowText(hTextWnd, "Select 'Option' menu items");
451: //
452: // INFO was allocated in the MDIWndProc at MM_MDI time and is
453: // passed to us at WM_CREATE time...
454: //
455: hInfo = (HANDLE) ((LPMDICREATESTRUCT) ((LPCREATESTRUCT) lParam)->lpCreateParams)->lParam ;
456: if (hInfo) {
457: if ((pInfo = (PINFO)LocalLock(hInfo)) == NULL)
458: MessageBox(ghwndMain, "Failed in LocalLock", "Error", MB_OK);
459:
460: if (!GetClientRect(hwnd, &pInfo->rcClient))
461: MessageBox(ghwndMain, "Failed in GetClientRect!", "Error", MB_OK);
462:
463: pInfo->hTextWnd = hTextWnd;
464: //
465: // Save the handle to INFO in our window structure
466: //
467: SetWindowLong(hwnd, 0, (LONG) hInfo);
468: LocalUnlock(hInfo);
469: } else {
470: MessageBox(ghwndMain, "Can't allocate hInfo!", "Error", MB_OK);
471: }
472:
473: break;
474: }
475:
476: //
477: // Free the INFO data that associates with this window
478: // also, reset the menu.
479: //
480: case WM_CLOSE: {
481: HANDLE hInfo;
482:
483: SendMessage(GetParent(hwnd), WM_MDISETMENU,
484: (DWORD) hMenu,
485: (LONG) hMenuWindow) ;
486: DrawMenuBar(GetParent(GetParent(hwnd))) ;
487:
488: hInfo = (HANDLE) GetWindowLong(hwnd, 0);
489: LocalFree(hInfo);
490: break;
491: }
492:
493: default:
494: return DefMDIChildProc(hwnd, message, wParam, lParam);
495:
496: } //switch
497: return DefMDIChildProc(hwnd, message, wParam, lParam);
498: }
499:
500: /***************************************************************************\
501: * About
502: *
503: * About dialog proc.
504: *
505: * History:
506: * 09-09-91 Petrus Wong Rewrote.
507: * 04-13-91 ???? Created.
508: \***************************************************************************/
509:
510: long About(
511: HWND hDlg,
512: UINT message,
513: DWORD wParam,
514: LONG lParam)
515: {
516: switch (message) {
517: case WM_INITDIALOG:
518: return TRUE;
519:
520: case WM_COMMAND:
521: if (wParam == IDOK)
522: EndDialog(hDlg, wParam);
523: break;
524: }
525:
526: return FALSE;
527:
528: UNREFERENCED_PARAMETER(lParam);
529: UNREFERENCED_PARAMETER(hDlg);
530: }
531:
532: /***************************************************************************\
533: *
534: * TextWndProc
535: *
536: * Text Window procedure for displaying miscellaneous messages to user.
537: *
538: * History:
539: * 10-07-91
540: * 3D text output
541: *
542: \***************************************************************************/
543:
544: LONG TextWndProc (HWND hwnd, UINT message, DWORD wParam, LONG lParam)
545: {
546: static HFONT hFont = (HFONT) NULL;
547:
548: switch (message)
549: {
550: case WM_CREATE:
551: {
552: LOGFONT lf;
553: HDC hDC;
554: HFONT hOldFont;
555: TEXTMETRIC tm;
556: RECT rect;
557: LONG lHeight;
558:
559: SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lf), (PVOID) &lf, (UINT)FALSE);
560:
561: hDC = GetDC(hwnd);
562: // this is the height for 8 point size font in pixels
563: lf.lfHeight = 8 * GetDeviceCaps(hDC, LOGPIXELSY) / 72;
564:
565: hFont = CreateFontIndirect(&lf);
566: hOldFont = SelectObject(hDC, hFont);
567: GetTextMetrics(hDC, &tm);
568: GetClientRect(GetParent(hwnd), &rect);
569:
570: // base the height of the window on size of text
571: lHeight = tm.tmHeight+6*GetSystemMetrics(SM_CYBORDER)+2;
572: // saved the height for later reference
573: SetWindowLong(hwnd, GWL_USERDATA, lHeight);
574: SetWindowPos(hwnd, NULL,
575: 0,
576: rect.bottom-lHeight,
577: rect.right-rect.left,
578: lHeight,
579: SWP_NOZORDER | SWP_NOMOVE);
580:
581: ReleaseDC(hwnd, hDC);
582: break;
583: }
584:
585: case WM_DESTROY:
586: if (hFont)
587: DeleteObject(hFont);
588: break;
589:
590: case WM_SETTEXT:
591: DefWindowProc(hwnd, message, wParam, lParam);
592: InvalidateRect(hwnd,NULL,FALSE);
593: UpdateWindow(hwnd);
594: return 0L;
595:
596: case WM_PAINT:
597: {
598: PAINTSTRUCT ps;
599: RECT rc;
600: char ach[128];
601: int len, nxBorder, nyBorder;
602: HFONT hOldFont = NULL;
603:
604: BeginPaint(hwnd, &ps);
605:
606: GetClientRect(hwnd,&rc);
607:
608: nxBorder = GetSystemMetrics(SM_CXBORDER);
609: rc.left += 9*nxBorder;
610: rc.right -= 9*nxBorder;
611:
612: nyBorder = GetSystemMetrics(SM_CYBORDER);
613: rc.top += 3*nyBorder;
614: rc.bottom -= 3*nyBorder;
615:
616: // 3D Text
617: len = GetWindowText(hwnd, ach, sizeof(ach));
618: SetBkColor(ps.hdc, GetSysColor(COLOR_BTNFACE));
619:
620: SetBkMode(ps.hdc, TRANSPARENT);
621: SetTextColor(ps.hdc, RGB(64,96,96));
622: if (hFont)
623: hOldFont = SelectObject(ps.hdc, hFont);
624: ExtTextOut(ps.hdc, rc.left+2*nxBorder+2, rc.top+2, ETO_OPAQUE | ETO_CLIPPED,
625: &rc, ach, len, NULL);
626:
627: SetTextColor(ps.hdc, RGB(128,128,128));
628: if (hFont)
629: hOldFont = SelectObject(ps.hdc, hFont);
630: ExtTextOut(ps.hdc, rc.left+2*nxBorder+1, rc.top+1, ETO_CLIPPED,
631: &rc, ach, len, NULL);
632:
633: SetTextColor(ps.hdc, RGB(255,255,255));
634: if (hFont)
635: hOldFont = SelectObject(ps.hdc, hFont);
636: ExtTextOut(ps.hdc, rc.left+2*nxBorder, rc.top, ETO_CLIPPED,
637: &rc, ach, len, NULL);
638:
639: SetBkMode(ps.hdc, OPAQUE);
640:
641: if (hOldFont)
642: SelectObject(ps.hdc, hOldFont);
643:
644: EndPaint(hwnd, &ps);
645: return 0L;
646: }
647: }
648: return DefWindowProc(hwnd, message, wParam, lParam);
649: }
650:
651: VOID vTest(PINFO pInfo)
652: {
653: OutputDebugString("Inside vTest()\n");
654:
655: UNREFERENCED_PARAMETER(pInfo);
656: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.