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