|
|
1.1 root 1: /*==============================================================*\
2: * img_main.c - Image Porting PM application main source file
3: * Created 1989, 1990 IBM, Microsoft Corp.
4: *--------------------------------------------------------------
5: *
6: * This application serves as an example of porting a 16-bit
7: * application to 32-bit. It takes a 16-bit application which
8: * can be built using the headers/libraries/tools from an OS/2 1.2
9: * toolkit and ends up with a pure 32-bit application.
10: *
11: *--------------------------------------------------------------
12: *
13: * This source file contains the following functions:
14: *
15: * main()
16: * MainWndProc(hwnd, msg, mp1, mp2)
17: * FrameWndProc(hwnd, msg, mp1, mp2)
18: * MessageBox(hwnd idMsg, fsStyle, fBeep)
19: * MainCommand(mp1, mp2)
20: * ExitProc(usTermCode)
21: *
22: \*==============================================================*/
23: /*--------------------------------------------------------------*\
24: * Include files, macros, defined constants, and externs *
25: \*--------------------------------------------------------------*/
26: #define INCL_DOSPROCESS
27: #define INCL_WINWINDOWMGR
28: #define INCL_WINFRAMEMGR
29: #define INCL_WINSYS
30: #define INCL_WINTRACKRECT
31: #define INCL_WINHELP
32: #define INCL_GPIPRIMITIVES
33:
34: /*--------------------------------------------------------------*\
35: * Include files, macros, defined constants, and externs *
36: \*--------------------------------------------------------------*/
37: #include <os2.h>
38: #include <string.h>
39: #include "img_main.h"
40: #include "img_xtrn.h"
41: #include "img_help.h"
42:
43: /*--------------------------------------------------------------*\
44: * error defines *
45: \*--------------------------------------------------------------*/
46: #define RETURN_SUCCESS 0 /* successful return in DosExit */
47: #define RETURN_ERROR 1 /* error return in DosExit */
48: #define BEEP_WARN_FREQ 60 /* frequency of warning beep */
49: #define BEEP_WARN_DUR 100 /* duration of warning beep */
50:
51: /*--------------------------------------------------------------*\
52: * Entry point declarations *
53: \*--------------------------------------------------------------*/
54: VOID MainCommand(MPARAM mp1, MPARAM mp2);
55:
56: /*--------------------------------------------------------------*\
57: * Static variables *
58: \*--------------------------------------------------------------*/
59: HMQ hmq; /* application queue handle */
60:
61: /****************************************************************\
62: * Main routine *
63: *--------------------------------------------------------------*
64: * *
65: * Name: main() *
66: * *
67: * Purpose: Initializes the PM environment, calls the *
68: * initialization routine, creates the main *
69: * window, and polls the message queue *
70: * *
71: * Usage: *
72: * *
73: * Method: *
74: * - obtains anchor block handle and creates message *
75: * queue *
76: * - calls the initialization routine *
77: * - creates the main frame window which creates the *
78: * main client window *
79: * - polls the message queue via Get/Dispatch Msg loop *
80: * - upon exiting the loop, exits *
81: * *
82: * Returns: *
83: * 1 - if sucessful execution completed *
84: * 0 - if error *
85: \****************************************************************/
86:
87: BOOL cdecl main(VOID)
88: {
89: QMSG qmsg; /* message structure */
90: USHORT rc;
91:
92: vhab = WinInitialize(0);
93: if(!vhab) {
94: DosBeep(BEEP_WARN_FREQ, BEEP_WARN_DUR);
95: return RETURN_ERROR;
96: }
97:
98: /* find a define for this v */
99: hmq = WinCreateMsgQueue(vhab, 0);
100: if(!hmq) {
101: DosBeep(BEEP_WARN_FREQ, BEEP_WARN_DUR);
102: WinTerminate(vhab);
103: return RETURN_ERROR;
104: }
105:
106: if(rc = Init()) {
107: MessageBox(HWND_DESKTOP, rc, 0, MB_OK | MB_ERROR, TRUE);
108: } else {
109:
110: /* get/dispatch message loop */
111:
112: while (WinGetMsg(vhab, &qmsg, (HWND)NULL, 0, 0))
113: WinDispatchMsg(vhab, &qmsg);
114:
115: }
116:
117: /*
118: * release any allocated resource - no need to check return codes
119: */
120: #ifdef HELP_MANAGER_ENABLED
121: /* destroy the help instance */
122: HelpDestroyInstance();
123: #endif
124: return RETURN_SUCCESS;
125:
126: } /* main() */
127:
128: /****************************************************************\
129: * Main client window procedure *
130: *--------------------------------------------------------------*
131: * *
132: * Name: MainWndProc(hwnd, msg, mp1, mp2) *
133: * *
134: * Purpose: Processes the messages sent to the main client *
135: * window. This routine processes the basic *
136: * messages all client windows should process *
137: * and passes all others onto UserWndProc where *
138: * the developer can process any others. *
139: * *
140: * Usage: Called for each message placed in the main *
141: * window's message queue *
142: * *
143: * Method: a switch statement branches to the routines to be *
144: * performed for each message processed. Any messages *
145: * not specifically process are passed to the user's *
146: * message processing procedure UserWndProc(). *
147: * *
148: * Returns: Return values are determined by each message *
149: * *
150: \****************************************************************/
151:
152: MRESULT EXPENTRY MainWndProc(hwnd, msg, mp1, mp2)
153: HWND hwnd; /* handle of window */
154: USHORT msg; /* id of message */
155: MPARAM mp1; /* first message parameter */
156: MPARAM mp2; /* second message parameter */
157: {
158: PSWP pswp;
159: BOOL fHScroll;
160: RECTL rcl;
161: POINTL ptl;
162:
163: switch (msg) {
164:
165: case WM_CREATE:
166: /*
167: * set application title to 'Untitled'
168: */
169: UtilUpdateTitleText(vhab,
170: ((PCREATESTRUCT)PVOIDFROMMP(mp2))->hwndParent,
171: "");
172:
173: /* return FALSE to continue window creation, TRUE to abort it */
174: return (MRESULT)FALSE;
175: break;
176:
177: case WM_INITMENU:
178:
179: /*
180: * disable/enable menu items as appropriate
181: */
182: MenuInit(mp1, mp2);
183: break;
184:
185: case WM_ERASEBACKGROUND:
186:
187: /*
188: * The client window is cleared to SYSCLR_WINDOW
189: */
190: return (MRESULT)TRUE;
191: break;
192:
193: case WM_MINMAXFRAME:
194:
195: /*
196: * the window can be maximized by double clicking on the
197: * title bar, clicking on the maximize icon, or by
198: * selecting the maximize option in the System Menu.
199: * The SizeCalculateMaxWindow() function is invoked to set the
200: * window to a size that is no larger than the loaded image.
201: */
202: pswp = (PSWP)mp1;
203: #if (defined(PORT_S132) || defined(PORT_32))
204: if (pswp->fl & SWP_MAXIMIZE) {
205: #else
206: if (pswp->fs & SWP_MAXIMIZE) {
207: #endif
208:
209: /*
210: * disable options which aren't valid when
211: * the window is maximized
212: */
213: vfMaximized = TRUE;
214:
215: if (vfDetail) {
216: SizeCalculateMaxWindow(&rcl);
217: pswp->cy = (SHORT)(rcl.yTop - rcl.yBottom);
218: pswp->cx = (SHORT)(rcl.xRight - rcl.xLeft);
219: pswp->y = (SHORT)rcl.yBottom;
220: pswp->x = (SHORT)rcl.xLeft;
221: }
222: } else
223:
224: /*
225: * re-enable options which were invalid when
226: * the window was maximized
227: */
228: vfMaximized = FALSE;
229: break;
230:
231: case WM_PAINT:
232:
233: WinBeginPaint(hwnd, vhps, (PRECTL)&rcl);
234: if (vfImgLoaded && vfDetail)
235:
236: /*
237: * If an image has been loaded and the user has selected
238: * the 'Detail' view, the PaintUnSizedImage() function is
239: * invoked to draw the image data in the client window.
240: * The image is drawn unscaled, and clipped if necessary.
241: */
242: PaintUnSizedImage();
243:
244: else if (vfImgLoaded && !vfDetail)
245:
246: /*
247: * If an image has been loaded and the user has selected
248: * the 'Non-detailed' view, the PaintSizedImage() function is
249: * invoked to size the image and draw it. * The image is drawn scaled to fit the window.
250: */
251: PaintSizedImage();
252:
253: else
254: /*
255: * If no image data has been loaded, clear the window to
256: * the default system color. */
257: WinFillRect(vhps, &rcl, SYSCLR_WINDOW);
258:
259: WinEndPaint(vhps);
260: break;
261:
262: case WM_SIZE:
263:
264: /*
265: * If the window size is altered and the image is being
266: * viewed in detail, the WndSize function is invoked to restrict
267: * the new window size and scroll-bar range to image limits.
268: * If the 'Non-detailed' view has been selected and the window
269: * size is altered, the image has to be redrawn to fit the window.
270: */
271: if (vfImgLoaded && vfDetail)
272: SizePositionImage(mp2);
273:
274: WinInvalidateRect(hwnd, (PRECTL)NULL, FALSE);
275: break;
276:
277: case WM_HSCROLL:
278: case WM_VSCROLL:
279:
280: /*
281: * scrolling is implemented only if an image has been
282: * loaded, the 'Detail' view has been selected, and there is
283: * image data still lying outside window limits.
284: */
285: fHScroll = (BOOL)(msg == WM_HSCROLL);
286: if (vfImgLoaded && vfDetail &&
287: (fHScroll ? vulScrollXMax > 0 : vulScrollYMax > 0)) {
288:
289: GpiQueryCurrentPosition(vhps, &ptl);
290: WinQueryWindowRect(hwnd, &rcl);
291:
292: /* call the appropriate scroll routine */
293: (fHScroll ? SizeHScroll(mp2, rcl, ptl) :
294: SizeVScroll(mp2, rcl, ptl));
295: }
296: break;
297:
298: case WM_DESTROY:
299:
300: /*
301: * delete the image graphics presentation space
302: */
303: GpiAssociate(vhps, (HDC)NULL);
304: GpiDestroyPS(vhps);
305:
306: if (vfImgLoaded) {
307:
308: /*
309: * Free any allocated memory
310: */
311: #if (defined(PORT_16) || defined(PORT_S132))
312: UtilMemoryFree(SELECTOROF(vpbImgBuf));
313: #else
314: UtilMemoryFree(vpbImgBuf);
315: #endif
316:
317: /*
318: * Release all bit-map resources and close the memory
319: * device context
320: */
321: GpiSetBitmap(vhpsMem, (HBITMAP)NULL);
322: GpiDeleteBitmap(vhbm);
323: GpiAssociate(vhpsMem, (HDC)NULL);
324: GpiDestroyPS(vhpsMem);
325: DevCloseDC(vhdcMem);
326: }
327:
328: /*
329: * ensure that the scroll bars are child windows of the
330: * frame, so that they will be destroyed automatically.
331: */
332: if (!WinIsChild(vhwndHScroll, vhwndFrame)) {
333: WinSetParent(vhwndVScroll, vhwndFrame, FALSE);
334: WinSetParent(vhwndHScroll, vhwndFrame, FALSE);
335: }
336: break;
337:
338: case WM_CLOSE:
339: WinPostMsg(hwnd, WM_QUIT, 0L, 0L);
340: break;
341:
342: case WM_COMMAND:
343:
344: /*
345: * processing of menu options is required
346: */
347: MainCommand(mp1, mp2);
348: break;
349:
350: #ifdef HELP_MANAGER_ENABLED
351: case HM_QUERY_KEYS_HELP:
352:
353: /*
354: * pass the id of the Keys help panel to the system
355: */
356: return (MRESULT)PANEL_HELPKEYS; /* id of key help panel */
357: break;
358:
359: case HM_ERROR:
360: /*
361: * an error has occurred whilst using IPF help - report
362: * the error, and destroy the help instance
363: */
364: MessageBox(vhwndFrame, IDMSG_HELPMANAGERERROR, 0,
365: MB_OK | MB_ERROR, TRUE);
366: vfHelpEnabled = FALSE;
367: break;
368: #endif
369: default:
370:
371: /*
372: * default must call WinDefWindowProc()
373: */
374: return WinDefWindowProc(hwnd, msg, mp1, mp2);
375: break;
376: }
377: return 0L; /* all window procedures should return 0 as a default */
378: } /* MainWndProc() */
379:
380: /****************************************************************\
381: * Frame subclassed window procedure *
382: *--------------------------------------------------------------*
383: * *
384: * Name: FrameWndProc(hwnd, msg, mp1, mp2) *
385: * *
386: * Purpose: The purpose of the frame-window subclass procedure *
387: * is to restrict frame-window sizing so that it is *
388: * in step with the size of the client-window *
389: * presentation space. That is, the size of the image *
390: * dictates the size of the maximized window. *
391: * Messages intended for the frame-window procedure *
392: * are sent here first. *
393: * *
394: * Usage: Called for each message placed in the main *
395: * window's message queue *
396: * *
397: * Method: a switch statement branches to the routines to be *
398: * performed for each message processed. Any messages *
399: * not specifically process are passed to the user's *
400: * message processing procedure MainWndProc(). The *
401: * message trapped by this wndproc() are *
402: * WM_QUERYTRACKINFO & WM_ADJUSTWINDOWPOS which are *
403: * both posted to the frame procedure initially to *
404: * setup the default values. *
405: * *
406: * Returns: Return values are determined by each message *
407: * *
408: \****************************************************************/
409:
410: MRESULT EXPENTRY FrameWndProc(hwnd, msg, mp1, mp2)
411: HWND hwnd; /* handle of window */
412: USHORT msg; /* id of message */
413: MPARAM mp1; /* first message parameter */
414: MPARAM mp2; /* second message parameter */
415: {
416: SWP swp;
417: PSWP pswp;
418: RECTL rcl;
419: ULONG rc;
420: POINTL ptl;
421: PTRACKINFO ptrack;
422:
423: switch(msg) {
424: case WM_ADJUSTWINDOWPOS:
425:
426: /*
427: * restrict the size of the window so that it never exceeds
428: * the maximum size of the image - only handle explicitly
429: * for the 'Detail' mode
430: */
431: if (vfImgLoaded && vfDetail) {
432: rc = (ULONG)(*vpfnwpFrame)(hwnd, msg, mp1, mp2);
433: pswp = (PSWP)mp1;
434: swp = *pswp;
435:
436: /*
437: * find the maximum allowed size, and ensure that
438: * the window size never exceeds this
439: */
440: SizeCalculateMaxWindow(&rcl);
441: if (swp.cx > (SHORT)rcl.xRight)
442: swp.cx = (SHORT)rcl.xRight;
443: if (swp.cy > (SHORT)rcl.yTop)
444: swp.cy = (SHORT)rcl.yTop;
445: *pswp = swp;
446: return (MRESULT)rc;
447: } else
448:
449: /* let the system handle the message */
450: return (*vpfnwpFrame)(hwnd, msg, mp1, mp2);
451:
452: break;
453:
454: case WM_QUERYTRACKINFO:
455:
456: /*
457: * Invoke the normal frame-window procedure first in order
458: * to update the tracking rectangle to the new position.
459: */
460: (*vpfnwpFrame)(hwnd, msg, mp1, mp2);
461: ptrack = (PTRACKINFO)mp2;
462:
463: if (vfImgLoaded && vfDetail) {
464:
465: /*
466: * Limit the size of the bounding rectangle only if the
467: * window is being sized.
468: * fs and rclBoundary are tracking information structure
469: * elements.
470: */
471: if (((ptrack->fs & TF_MOVE) != TF_MOVE) &&
472: ((ptrack->fs & TF_MOVE) ||
473: (ptrack->fs & TF_SETPOINTERPOS)
474: )) {
475: WinQueryWindowRect(vhwndClient, &rcl);
476: GpiQueryCurrentPosition(vhps, &ptl);
477:
478: ptrack->rclBoundary.yTop = rcl.yBottom + ptl.y;
479: ptrack->rclBoundary.yBottom = rcl.yBottom + ptl.y -
480: vsizlImg.cy;
481: ptrack->rclBoundary.xLeft = rcl.xLeft + ptl.x;
482: ptrack->rclBoundary.xRight = rcl.xLeft + ptl.x +
483: vsizlImg.cx;
484:
485: /*
486: * convert client boundary coordinates to screen
487: * coordinates
488: */
489: WinMapWindowPoints(vhwndClient,
490: HWND_DESKTOP,
491: (PPOINTL)&ptrack->rclBoundary,
492: sizeof(RECTL)/sizeof(POINTL));
493:
494: /*
495: * calculate equivalent frame boundary from client
496: * boundary data
497: */
498: WinCalcFrameRect(vhwndFrame,
499: (PRECTL)&ptrack->rclBoundary,
500: FALSE);
501:
502: ptrack->fs |= TF_ALLINBOUNDARY;
503: }
504: }
505: return (MRESULT)TRUE;
506: break;
507:
508: default:
509:
510: /*
511: * return using the normal frame window procedure
512: */
513: return (*vpfnwpFrame)(hwnd, msg, mp1, mp2);
514: break;
515:
516: }
517: return 0L; /* all window procedures should return 0 as a default */
518: } /* FrameWndProc() */
519: /****************************************************************\
520: * Message Box procedure
521: *--------------------------------------------------------------
522: *
523: * Name: MessageBox(hwndOwner, idMsg, idCaption, fsStyle, fBeep)
524: *
525: * Purpose: Displays the message box with the message
526: * given in idMsg retrived from the message table
527: * and using the style flags in fsStyle
528: *
529: * Usage: Called whenever a MessageBox is to be displayed
530: *
531: * Method: - Message string is loaded from the process'
532: * message table
533: * - Alarm beep is sounded if desired
534: * - Message box with the message is displayed
535: * - WinMessageBox return value is returned
536: *
537: * Returns: return value from WinMessageBox()
538: *
539: \****************************************************************/
540: SHORT MessageBox(hwndOwner, idMsg, idCaption, fsStyle, fBeep)
541: HWND hwndOwner; /* handle of the message box's owner */
542: SHORT idMsg; /* id if the message in the message table */
543: SHORT idCaption; /* id if the caption in the message table */
544: SHORT fsStyle; /* style of the message box */
545: BOOL fBeep; /* if TRUE, beep before message box is displayed */
546: {
547: CHAR szText[MESSAGELEN];
548: CHAR szCaption[MESSAGELEN];
549:
550: if (!WinLoadMessage(vhab,
551: (HMODULE)NULL,
552: idMsg,
553: MESSAGELEN,
554: (PSZ)szText)) {
555:
556: WinAlarm(HWND_DESKTOP, WA_ERROR);
557: return MBID_ERROR;
558: }
559:
560: /*
561: * if idCaption specified load string else use default
562: * caption 'Error!'
563: */
564: if (idCaption) {
565: if (!WinLoadMessage(vhab,
566: (HMODULE)NULL,
567: idCaption,
568: MESSAGELEN,
569: (PSZ)szCaption)) {
570:
571: WinAlarm(HWND_DESKTOP, WA_ERROR);
572: return MBID_ERROR;
573: }
574: }
575:
576: if (fBeep)
577: WinAlarm(HWND_DESKTOP, WA_ERROR);
578:
579: return WinMessageBox(HWND_DESKTOP,
580: hwndOwner,
581: szText,
582: (idCaption ? szCaption : (PSZ)NULL),
583: MSGBOXID,
584: fsStyle);
585:
586: } /* MessageBox() */
587:
588: /****************************************************************\
589: * Main window WM_COMMAND processing procedure
590: *--------------------------------------------------------------
591: *
592: * Name: MainCommand(mp1, mp2)
593: *
594: * Purpose: Calls the appropriate procedures that deal with
595: * the selected menu item.
596: *
597: * Usage: Routine is called whenever a WM_COMMAND message
598: * is posted to the main window.
599: *
600: * Method: a switch statement branches on the id of the
601: * menu item that posted the message and the
602: * appropriate action for that item is taken. Any
603: * menu ids that are not part of the standard menu
604: * set are passed onto the user defined WM_COMMAND
605: * processing procedure.
606: *
607: * Returns:
608: *
609: \****************************************************************/
610: VOID MainCommand(mp1, mp2)
611: MPARAM mp1; /* first parameter of WM_COMMAND message */
612: MPARAM mp2; /* second parameter of WM_COMMAND message */
613: {
614: switch (SHORT1FROMMP(mp1)) {
615: case IDM_FILEOPEN:
616:
617: /*
618: * Open file and load/draw the selected image
619: */
620: FileOpen(mp2);
621: break;
622:
623: case IDM_FILEEXIT:
624:
625: /*
626: * time to leave
627: */
628: FileExit(mp2);
629: break;
630:
631: case IDM_VIEWDETAIL:
632:
633: /*
634: * toggle between Detail and Non-Detail mode
635: */
636: ViewSwitchMode();
637: break;
638:
639: case IDM_VIEWSAVEPOSITION:
640:
641: /*
642: * save the current image position
643: */
644: ViewSavePosition();
645: break;
646:
647: case IDM_VIEWRESTOREPOSITION:
648:
649: /*
650: * save the current image position
651: */
652: ViewRestorePosition();
653: break;
654:
655: case IDM_VIEWFORECOLORBLACK:
656: case IDM_VIEWFORECOLORWHITE:
657: case IDM_VIEWFORECOLORBLUE:
658: case IDM_VIEWFORECOLORGREEN:
659: case IDM_VIEWFORECOLORYELLOW:
660: case IDM_VIEWFORECOLORRED:
661: case IDM_VIEWBACKCOLORBLACK:
662: case IDM_VIEWBACKCOLORWHITE:
663: case IDM_VIEWBACKCOLORBLUE:
664: case IDM_VIEWBACKCOLORGREEN:
665: case IDM_VIEWBACKCOLORYELLOW:
666: case IDM_VIEWBACKCOLORRED:
667: ViewChangeColor(SHORT1FROMMP(mp1));
668: break;
669:
670: #ifdef HELP_MANAGER_ENABLED
671: case IDM_HELPHELPFORHELP:
672: HelpHelpForHelp(mp2);
673: break;
674:
675: case IDM_HELPEXTENDED:
676: HelpExtended(mp2);
677: break;
678:
679: case IDM_HELPINDEX:
680: HelpIndex(mp2);
681: break;
682: #endif
683: case IDM_HELPABOUT:
684: HelpAbout();
685: break;
686: }
687: } /* MainCommand() */
688:
689: /****************************************************************\
690: * Exit list processing procedure
691: *--------------------------------------------------------------
692: *
693: * Name: ExitProc(usTermCode)
694: *
695: * Purpose: Cleans up certain resources when the application
696: * terminates
697: *
698: * Usage: Routine is called by DosExitList when the
699: * application exits
700: *
701: * Method: global resources, such as the main window and
702: * message queue, are destroyed and any system
703: * resources used are freed
704: *
705: * Returns: Returns EXLST_EXIT to the DosExitList handler
706: *
707: \****************************************************************/
708: VOID PASCAL ExitProc(usTermCode)
709: USHORT usTermCode; /* code for the reason for termination */
710: {
711:
712: /* destroy the main window if it exists */
713: if (WinIsWindow(vhab, vhwndFrame))
714: WinDestroyWindow(vhwndFrame);
715:
716: WinDestroyMsgQueue(hmq);
717: WinTerminate(vhab);
718:
719: DosExitList(EXLST_EXIT, 0L); /* termination complete */
720:
721: /* This routine currently doesn't use the usTermCode parameter so *\
722: * it is referenced here to prevent an 'Unreferenced Parameter'
723: \* warning at compile time */
724:
725: usTermCode;
726:
727: } /* ExitProc() */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.