|
|
1.1 root 1: /****************************** Module Header ******************************\
2: * Module Name: dcalc.c - Dialog form of the Calc application
3: *
4: * OS/2 Presentation Manager version of Calc, ported from Windows version
5: *
6: * Created by Microsoft, IBM Corporation, 1990
7: *
8: * DISCLAIMER OF WARRANTIES. The following [enclosed] code is
9: * sample code created by Microsoft Corporation and/or IBM
10: * Corporation. This sample code is not part of any standard
11: * Microsoft or IBM product and is provided to you solely for
12: * the purpose of assisting you in the development of your
13: * applications. The code is provided "AS IS", without
14: * warranty of any kind. Neither Microsoft nor IBM shall be
15: * liable for any damages arising out of your use of the sample
16: * code, even if they have been advised of the possibility of
17: * such damages.
18: *
19: \***************************************************************************/
20:
21: #define INCL_DEV
22: #define INCL_DOSPROCESS
23: #define INCL_DOSSEMAPHORES
24: #define INCL_DOSNLS
25: #define INCL_ERRORS
26: #define INCL_WINBUTTONS
27: #define INCL_WINCLIPBOARD
28: #define INCL_WINDIALOGS
29: #define INCL_WINFRAMEMGR
30: #define INCL_WININPUT
31: #define INCL_WINMENUS
32: #define INCL_WINMESSAGEMGR
33: #define INCL_WINPOINTERS
34: #define INCL_WINSWITCHLIST
35: #define INCL_WINTRACKRECT
36: #define INCL_WINWINDOWMGR
37: #include <os2.h>
38: #include <string.h>
39: #include <stdlib.h>
40: #include <stdio.h>
41: #include "dcalc.h"
42:
43: /************* GLOBAL VARIABLES */
44:
45: char chLastKey, currkey;
46: char szCalcClass[] = "Calculator";
47: char szTitle[30];
48: char szreg1[20], szreg2[20], szmem[20], szregx[20];
49: /* hope 20 is enough for kanji error string */
50: char szErrorString[20], szPlusMinus[2];
51: short charwidth, charheight;
52: int aspectx, aspecty, nchszstr;
53: extern BOOL fError = FALSE;
54: BOOL fValueInMemory = FALSE;
55: BOOL fMDown = FALSE;
56: UCHAR mScan = 0;
57:
58: #define TOLOWER(x) ( (((x) >= 'A') && ((x) <= 'Z')) ? (x)|0x20 : (x))
59: #define WIDTHCONST 28
60: #define CXCHARS 37
61: #define CYCHARS 13
62:
63: HAB hab;
64: HDC hdcLocal; /* Local used for button bitmap */
65: HPS hpsLocal;
66: HDC hdcSqr; /* Sqr used for square-root bitmap */
67: HPS hpsSqr;
68: HBITMAP hbmLocal, hbmSqr;
69: HMQ hmqCalc = NULL;
70:
71: HWND hwndCalc = NULL,
72: hwndMenu = NULL;
73:
74: HPOINTER hptrFinger = NULL,
75: hptrIcon = NULL;
76:
77: DEVOPENSTRUC dop = /* used by DevOpenDC */
78: {
79: NULL, "DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL
80: };
81:
82: static char bButtonValues[] = /* Button values */
83: {
84: 0xBC, 0xBB, 0xBA, 0xB9, '0', '1', '2', '3', '4',
85: '5', '6', '7', '8', '9', '.', '/', '*', '-',
86: '+', 'q', '%', 'c', '=', 0xB1, NULL
87: };
88:
89: /************* PROCEDURE DECLARATIONS */
90:
91: MPARAM EXPENTRY AboutDlgProc(HWND, USHORT, MPARAM, MPARAM);
92: BOOL CalcInit(VOID);
93: VOID CalcPaint( HWND, HPS);
94: MRESULT EXPENTRY fnDlgCalc(HWND, USHORT, MPARAM, MPARAM);
95: VOID cdecl main(VOID);
96: VOID DataXCopy( VOID);
97: VOID DataXPaste( VOID);
98: VOID DrawNumbers( HPS);
99: VOID Evaluate(BYTE);
100: VOID InitCalc( VOID);
101: BOOL InterpretChar( CHAR);
102: VOID ProcessKey(HWND, WPOINT *);
103: char Translate(WPOINT *);
104: VOID UpdateDisplay( VOID);
105:
106:
107:
108: /********************************************************************
109: Write the appropriate number or error string to the display area
110: and mark memory-in-use if appropriate.
111: */
112:
113: BYTE aszDisplayBuff[20];
114:
115: VOID UpdateDisplay()
116: {
117: strcpy(aszDisplayBuff, fError? "Error" :szreg1);
118: strcat(aszDisplayBuff, fValueInMemory? " M" : " ");
119:
120: WinSetDlgItemText(hwndCalc, TXT_RESULT_DISPLAY, aszDisplayBuff);
121: }
122:
123:
124: /**********************************************************************
125: Display helpful info
126: */
127:
128: MPARAM EXPENTRY AboutDlgProc(hwnd, msg, mp1, mp2)
129: HWND hwnd;
130: USHORT msg;
131: MPARAM mp1;
132: MPARAM mp2;
133: {
134: if (msg == WM_COMMAND)
135: {
136: WinDismissDlg(hwnd, TRUE);
137: return(MPFROMSHORT(TRUE));
138: }
139: else return(WinDefDlgProc(hwnd, msg, mp1, mp2));
140: }
141:
142:
143: /**********************************************************************
144: General initialization
145: */
146:
147: BOOL CalcInit()
148: {
149: hab = WinInitialize(0);
150:
151: hmqCalc = WinCreateMsgQueue( hab, 0);
152:
153: return(TRUE);
154: }
155:
156: /**********************************************************************
157: main procedure
158: */
159:
160: VOID cdecl main()
161: {
162: QMSG qmsg;
163:
164: if (!CalcInit()) { /* general initialization */
165: WinAlarm(HWND_DESKTOP, 0xffff);
166: goto exit;
167: }
168:
169: WinLoadDlg(HWND_DESKTOP, HWND_DESKTOP, fnDlgCalc, NULL, CALCDLG, NULL);
170:
171: if (hwndCalc)
172: while (WinGetMsg( hab, (PQMSG)&qmsg, NULL, 0, 0))
173: WinDispatchMsg( hab, (PQMSG)&qmsg);
174:
175: exit: /* clean up */
176:
177: if (hwndMenu) WinDestroyWindow(hwndMenu);
178:
179: WinDestroyMsgQueue(hmqCalc);
180: WinTerminate(hab);
181:
182: DosExit(EXIT_PROCESS, 0); /* exit without error */
183: }
184:
185:
186: /*************************************************************************
187: Calc Dialog Window Procedure
188: */
189:
190:
191: TID idThread;
192: PID idProcess;
193: SWCNTRL swc;
194: HSWITCH hsw;
195: USHORT usWidthCalc, usHeightCalc;
196:
197: MRESULT EXPENTRY fnDlgCalc(hwnd, msg, mp1, mp2)
198: HWND hwnd;
199: USHORT msg;
200: MPARAM mp1;
201: MPARAM mp2;
202: {
203: RECTL rectl;
204: BOOL fClip;
205: USHORT fi, idCtrl;
206: MRESULT mresult;
207: USHORT afSWP;
208: PSWP pswp;
209:
210: static BOOL fMinimized;
211:
212:
213: switch (msg)
214: {
215: case WM_INITDLG:
216:
217: /* Set up the global state assumed by the dialog.
218: */
219: hwndCalc = hwnd;
220: hwndMenu = WinLoadMenu(hwnd, NULL, IDR_CALC);
221:
222: fMinimized = FALSE;
223:
224: hptrFinger = WinLoadPointer(HWND_DESKTOP, (HMODULE)NULL, IDP_FINGER);
225: hptrIcon = WinLoadPointer(HWND_DESKTOP, (HMODULE)NULL, IDR_CALC);
226:
227: WinSetWindowULong(hwndCalc, QWL_STYLE,
228: FS_ICON | WinQueryWindowULong(hwndCalc, QWL_STYLE)
229: );
230:
231: WinSendMsg(hwndCalc, WM_SETICON, (MPARAM) hptrIcon, 0L);
232: WinSendMsg(hwndCalc, WM_UPDATEFRAME, (MPARAM) 0L, 0L);
233:
234: WinQueryWindowRect(hwndCalc, &rectl);
235: usWidthCalc= (SHORT) (rectl.xRight - rectl.xLeft);
236: usHeightCalc= (SHORT) (rectl.yTop - rectl.yBottom);
237:
238: WinQueryWindowProcess(hwndCalc, &idProcess, &idThread);
239:
240: WinLoadString(NULL, NULL, 1, 30, (PSZ)szTitle);
241: WinLoadString(NULL, NULL, 2, 20, (PSZ)szErrorString);
242: WinLoadString(NULL, NULL, 3, 2, (PSZ)szPlusMinus);
243:
244: strcpy(swc.szSwtitle, szTitle);
245: swc.hwnd = hwndCalc;
246: swc.hwndIcon = hptrIcon;
247: swc.hprog = (ULONG)NULL;
248: swc.idProcess = idProcess;
249: swc.idSession = (USHORT)0;
250: swc.uchVisibility = SWL_VISIBLE;
251: swc.fbJump = SWL_JUMPABLE;
252: hsw = WinAddSwitchEntry((PSWCNTRL)&swc);
253:
254: InitCalc(); /* arithmetic initialization */
255:
256: WinSetActiveWindow(HWND_DESKTOP, hwndCalc);
257:
258: WinSetFocus(HWND_DESKTOP, hwndCalc);
259:
260: break;
261:
262: case WM_MINMAXFRAME:
263:
264: pswp= PVOIDFROMMP(mp1);
265:
266: if (pswp->fl & SWP_MINIMIZE)
267: fMinimized= TRUE;
268: else if (pswp->fl & SWP_RESTORE)
269: fMinimized= FALSE;
270:
271: return(WinDefDlgProc(hwnd, msg, mp1, mp2));
272:
273: break;
274:
275: case WM_DESTROY:
276:
277: WinDestroyPointer(hptrIcon ); hptrIcon = NULL;
278: WinDestroyPointer(hptrFinger); hptrFinger= NULL;
279:
280: break;
281:
282: case WM_INITMENU:
283:
284: fClip = FALSE;
285:
286: if (WinOpenClipbrd(NULL))
287: {
288: fClip = WinQueryClipbrdFmtInfo(NULL, CF_TEXT, (USHORT FAR *)&fi);
289: WinCloseClipbrd(NULL);
290: }
291:
292: WinSendMsg((HWND)mp2, MM_SETITEMATTR,
293: (MPARAM) MAKELONG(CMD_PASTE, TRUE),
294: (MPARAM) MAKELONG(MIA_DISABLED, fClip ? 0 : MIA_DISABLED));
295: break;
296:
297: case WM_ADJUSTWINDOWPOS:
298:
299: mresult= WinDefDlgProc(hwnd, msg, mp1, mp2);
300:
301: if (fMinimized) return(mresult);
302:
303: afSWP= (pswp= (PSWP) mp1)->fl;
304:
305: if ( afSWP & (SWP_SIZE | SWP_MAXIMIZE)
306: && !(afSWP & SWP_MINIMIZE)
307: )
308: {
309: pswp->y += pswp->cy - usHeightCalc;
310: pswp->cx = usWidthCalc;
311: pswp->cy = usHeightCalc;
312: }
313:
314: return(mresult);
315:
316:
317: case WM_COMMAND:
318:
319: fError = FALSE;
320:
321: idCtrl= SHORT1FROMMP(mp1);
322:
323: if ( SHORT1FROMMP(mp2) == BN_CLICKED
324: && idCtrl >= BUTTON_MC
325: && idCtrl <= BUTTON_CHANGE_SIGN
326: )
327: {
328: Evaluate(bButtonValues[idCtrl-BUTTON_MC]);
329: UpdateDisplay();
330: }
331: else
332: switch(idCtrl)
333: {
334: case CMD_COPY:
335: DataXCopy(); /* copy to clipboard */
336: break;
337: case CMD_PASTE:
338: DataXPaste(); /* paste from clipboard */
339: break;
340: case CMD_EXIT:
341: WinPostMsg(hwndCalc, WM_QUIT, 0L, 0L);
342: break;
343: case CMD_ABOUT:
344: WinDlgBox(HWND_DESKTOP, hwndCalc, (PFNWP)AboutDlgProc, NULL,
345: 1, (PSZ)NULL);
346: break;
347: }
348: break;
349:
350: case WM_CLOSE:
351: WinPostMsg(hwndCalc, WM_QUIT, 0L, 0L);
352: break;
353:
354: case WM_CONTROLPOINTER:
355: if (!fMinimized) return(hptrFinger);
356: else return(WinDefDlgProc(hwnd, msg, mp1, mp2));
357:
358: case WM_MOUSEMOVE:
359: if (!fMinimized) WinSetPointer(HWND_DESKTOP, hptrFinger);
360: break;
361:
362: case WM_BUTTON1DOWN:
363:
364: return(WinDefDlgProc(hwnd, WM_TRACKFRAME, (MPARAM) TF_MOVE, mp2));
365:
366: break;
367:
368: case WM_CHAR:
369:
370: fError = FALSE;
371:
372: if (SHORT1FROMMP(mp1) & KC_KEYUP)
373: {
374: if (CHAR4FROMMP(mp1) == mScan)
375: fMDown = FALSE; /* 'm' key went up */
376: }
377: else if (SHORT1FROMMP(mp1) & KC_CHAR)
378: {
379: if (InterpretChar(CHAR1FROMMP(mp2)))
380: UpdateDisplay();
381: else if ((CHAR1FROMMP(mp2)=='m') || (CHAR1FROMMP(mp2)=='M'))
382: {
383: mScan = CHAR4FROMMP(mp1); /* save 'm' key scan code */
384: fMDown = TRUE; /* 'm' key went down */
385: }
386: }
387: break;
388:
389: case WM_ERASEBACKGROUND:
390: if (WinQueryWindowULong(hwnd, QWL_STYLE) & WS_MINIMIZED)
391: WinValidateRect(hwnd, (PRECTL) mp2, TRUE);
392: return(WinDefDlgProc(hwnd, msg, mp1, mp2));
393: break;
394:
395: case WM_SETFOCUS:
396: if ((HWNDFROMMP(mp1)==hwndCalc) && !mp2);
397: fMDown = FALSE; /* since we are losing focus */
398:
399: default:
400: return(WinDefDlgProc(hwnd, msg, mp1, mp2));
401: break;
402: }
403: return(0L);
404: }
405:
406:
407: /*************************************************************************
408: translate & interpret keys (ie. locate in logical keyboard)
409: */
410:
411: BOOL InterpretChar(ch)
412: register CHAR ch;
413: {
414: BOOL fDone;
415: CHAR *chstep;
416:
417: fDone = FALSE;
418: chstep = bButtonValues;
419: switch (ch)
420: {
421: case 'n':
422: ch = szPlusMinus[0];
423: break;
424: case 27: /* xlate Escape into 'c' */
425: ch = 'c';
426: break;
427: case '\r': /* xlate Enter into '=' */
428: ch = '=';
429: break;
430: }
431:
432: if (fMDown) /* Do memory keys */
433: {
434: switch (ch)
435: {
436: case 'c':
437: case 'C':
438: ch = '\274';
439: break;
440: case 'r':
441: case 'R':
442: ch = '\273';
443: break;
444: case '+':
445: ch = '\272';
446: break;
447: case '-':
448: ch = '\271';
449: break;
450: }
451: }
452:
453: while (!fDone && *chstep)
454: {
455: if (*chstep++ == ch)
456: fDone = TRUE; /* char found in logical keyboard */
457: }
458:
459: if (fDone)
460: {
461: Evaluate(ch);
462: }
463:
464: return (fDone);
465: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.