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