|
|
1.1 root 1: /****************************** Module Header *********************************/
2: /* */
3: /* Module Name: calc.c - Calc application */
4: /* */
5: /* OS/2 Presentation Manager version of Calc, ported from Windows version */
6: /* */
7: /* Created by Microsoft, IBM Corporation, 1990 */
8: /* */
9: /* DISCLAIMER OF WARRANTIES. The following [enclosed] code is */
10: /* sample code created by Microsoft Corporation and/or IBM */
11: /* Corporation. This sample code is not part of any standard */
12: /* Microsoft or IBM product and is provided to you solely for */
13: /* the purpose of assisting you in the development of your */
14: /* applications. The code is provided "AS IS", without */
15: /* warranty of any kind. Neither Microsoft nor IBM shall be */
16: /* liable for any damages arising out of your use of the sample */
17: /* code, even if they have been advised of the possibility of */
18: /* such damages. */
19: /* */
20: /******************************************************************************/
21:
22: #define INCL_WININPUT
23: #define INCL_WINPOINTERS
24: #define INCL_WINMENUS
25: #define INCL_WINSYS
26: #define INCL_WINCLIPBOARD
27: #define INCL_GPIPRIMITIVES
28: #define INCL_GPIBITMAPS
29: #define INCL_GPILCIDS
30: #define INCL_DEV
31: #define INCL_ERRORS
32: #define INCL_DOSPROCESS
33: #define INCL_DOSSEMAPHORES
34: #define INCL_DOSNLS
35: #include <os2.h>
36: #include <string.h>
37: #include <stdlib.h>
38: #include <stdio.h>
39: #include "calc.h"
40:
41: /******************************************************************************/
42: /* */
43: /* GLOBAL VARIABLES */
44: /* */
45: /******************************************************************************/
46:
47: CHAR chLastKey, chCurrKey;
48: CHAR szreg1[20], szreg2[20], szmem[20], szregx[20];
49: CHAR szTitle[30], szErrorString[20], szPlusMinus[2];
50: SHORT sCharWidth, sCharHeight;
51: extern BOOL fError;
52: BOOL fValueInMemory = FALSE;
53: BOOL fMDown = FALSE; /* TRUE iff 'm' key depressed */
54: UCHAR uchMScan = 0; /* scan code for 'm' key */
55:
56: #define TOLOWER(x) ( (((x) >= 'A') && ((x) <= 'Z')) ? (x)|0x20 : (x))
57: #define WIDTHCONST 28
58: #define CXCHARS 37
59: #define CYCHARS 13
60:
61: HAB hab;
62: HDC hdcLocal; /* Local used for button bitmap */
63: HPS hpsLocal;
64: HDC hdcSqr; /* Sqr used for square-root bitmap */
65: HPS hpsSqr;
66: HBITMAP hbmLocal, hbmSqr;
67: HMQ hmqCalc;
68: HWND hwndCalc, hwndMenu;
69: HWND hwndCalcFrame;
70: HPS hpsCalc;
71: HDC hdcCalc;
72: HPOINTER hptrFinger;
73:
74: DEVOPENSTRUC dop = /* used by DevOpenDC */
75: {
76: NULL, "DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL
77: };
78:
79: static char achKeys[25] = /* keyboard keys */
80: {
81: '\271', '0', '.', '\261', '+', '=',
82: '\272', '1', '2', '3', '-', 'c',
83: '\273', '4', '5', '6', '*', '%',
84: '\274', '7', '8', '9', '/', 'q',
85: NULL
86: };
87:
88: static CHAR achDKeys[25] = /* 4th key is plusminus */
89: {
90: ' ', '0', '.', '+', '+', '=',
91: ' ', '1', '2', '3', '-', 'C',
92: ' ', '4', '5', '6', '*', '%',
93: ' ', '7', '8', '9', '/', ' ',
94: NULL
95: };
96:
97: /******************************************************************************/
98: /* */
99: /* PROCEDURE DECLARATIONS */
100: /* */
101: /******************************************************************************/
102:
103: VOID FarStrcpy( PSZ, PSZ);
104: MPARAM EXPENTRY AboutDlgProc( HWND, USHORT, MPARAM, MPARAM);
105: BOOL CalcInit(VOID);
106: VOID CalcPaint( HWND, HPS);
107: VOID CalcTextOut( HPS, INT, INT, PCH, INT);
108: MRESULT EXPENTRY CalcWndProc( HWND, USHORT, MPARAM, MPARAM);
109: VOID cdecl main(VOID);
110: VOID DataXCopy( VOID);
111: VOID DataXPaste( VOID);
112: VOID DrawNumbers( HPS);
113: VOID Evaluate(BYTE);
114: BOOL FlashSqr( HPS, PWPOINT);
115: VOID FlipKey( HPS, INT, INT);
116: VOID FrameKey( HPS, INT, INT);
117: VOID InitCalc( VOID);
118: BOOL InterpretChar( CHAR);
119: VOID ProcessKey( PWPOINT);
120: BOOL PSInit( VOID);
121: CHAR Translate( PWPOINT);
122: VOID UpdateDisplay( VOID);
123:
124:
125: /******************************************************************************/
126: /******************************************************************************/
127: VOID CalcTextOut( hps, iX, iY, pch, iCount)
128:
129: HPS hps;
130: INT iX, iY;
131: PCH pch;
132: INT iCount;
133: {
134: POINTL ptl;
135:
136: ptl.x = iX;
137: ptl.y = iY;
138:
139: GpiSetColor( hps, CLR_BLACK);
140: GpiCharStringAt( hps, (PPOINTL)&ptl, (LONG)iCount, (PSZ)pch);
141: }
142:
143:
144: /******************************************************************************/
145: /* Write the appropriate number or error string to the display area */
146: /* and mark memory-in-use if appropriate. */
147: /******************************************************************************/
148: VOID
149: UpdateDisplay()
150: {
151: RECTL rcl;
152:
153: rcl.xLeft = (6 * sCharWidth);
154: rcl.yBottom = 1050 * sCharHeight / 100;
155: rcl.xRight = rcl.xLeft + (12 * sCharWidth);
156: rcl.yTop = rcl.yBottom + (3 * sCharHeight) / 2;
157:
158: WinFillRect( hpsCalc, &rcl, CLR_WHITE); /* paint display area white */
159: if( fError)
160: WinDrawText( hpsCalc
161: , -1
162: , szErrorString
163: , &rcl
164: , CLR_BLACK
165: , CLR_WHITE
166: , DT_RIGHT | DT_VCENTER );
167: else
168: WinDrawText( hpsCalc
169: , -1
170: , szreg1
171: , &rcl
172: , CLR_BLACK
173: , CLR_WHITE
174: , DT_RIGHT | DT_VCENTER );
175:
176: if (fValueInMemory) /* little black square shows mem use */
177: {
178: rcl.xLeft = (6 * sCharWidth);
179: rcl.yBottom = 1050 * sCharHeight / 100;
180: rcl.xRight = rcl.xLeft + (sCharWidth / 2);
181: rcl.yTop = rcl.yBottom + (sCharHeight / 2);
182: WinFillRect( hpsCalc, &rcl, CLR_BLACK);
183: }
184: }
185:
186:
187: /******************************************************************************/
188: /* Display helpful info */
189: /******************************************************************************/
190: MPARAM EXPENTRY
191: AboutDlgProc( hwnd, msg, mp1, mp2)
192:
193: HWND hwnd;
194: USHORT msg;
195: MPARAM mp1;
196: MPARAM mp2;
197: {
198: if (msg == WM_COMMAND)
199: {
200: WinDismissDlg(hwnd, TRUE);
201: return(MPFROMSHORT(TRUE));
202: }
203: else return(WinDefDlgProc( hwnd, msg, mp1, mp2));
204: }
205:
206:
207: /******************************************************************************/
208: /* General initialization */
209: /******************************************************************************/
210: BOOL
211: CalcInit()
212: {
213: hab = WinInitialize( NULL);
214:
215: hmqCalc = WinCreateMsgQueue( hab, 0);
216: if( !hmqCalc)
217: return(FALSE);
218:
219: WinLoadString( NULL, NULL, 1, 30, (PSZ)szTitle);
220: WinLoadString( NULL, NULL, 2, 20, (PSZ)szErrorString);
221: WinLoadString( NULL, NULL, 3, 2, (PSZ)szPlusMinus);
222:
223: if (!WinRegisterClass( hab, szTitle, CalcWndProc, CS_SIZEREDRAW, 0))
224: return(FALSE);
225:
226: hptrFinger = WinLoadPointer( HWND_DESKTOP, (HMODULE)NULL, IDP_FINGER);
227:
228: InitCalc(); /* arithmetic initialization */
229:
230: return(TRUE);
231: }
232:
233: /******************************************************************************/
234: /* main procedure */
235: /******************************************************************************/
236: VOID cdecl
237: main()
238: {
239: QMSG qmsg;
240: ULONG ulFCF;
241:
242: if (!CalcInit()) { /* general initialization */
243: WinAlarm(HWND_DESKTOP, WA_ERROR);
244: goto exit;
245: }
246:
247: if (!PSInit()) { /* presentation spaces & bitmaps */
248: WinAlarm(HWND_DESKTOP, WA_ERROR);
249: goto exit;
250: }
251:
252: ulFCF = FCF_STANDARD & ~(LONG)(FCF_SIZEBORDER | FCF_MAXBUTTON);
253: hwndCalcFrame = WinCreateStdWindow( HWND_DESKTOP
254: , WS_VISIBLE | FS_BORDER
255: , &ulFCF
256: , szTitle
257: , NULL
258: , 0L
259: , NULL
260: , IDR_CALC
261: , &hwndCalc);
262:
263: WinSetWindowPos( hwndCalcFrame
264: , (HWND)NULL
265: , 2
266: , 2
267: , CXCHARS * sCharWidth
268: , CYCHARS * sCharHeight
269: + (SHORT)WinQuerySysValue( HWND_DESKTOP
270: , SV_CYTITLEBAR )
271: + (SHORT)WinQuerySysValue( HWND_DESKTOP
272: , SV_CYMENU )
273: , SWP_MOVE | SWP_SIZE );
274:
275: while (WinGetMsg( hab, &qmsg, NULL, 0, 0))
276: WinDispatchMsg( hab, &qmsg);
277:
278: exit: /* clean up */
279: if (hdcSqr) /* square-root bitmap */
280: {
281: GpiDestroyPS( hpsSqr);
282: if (hbmSqr)
283: GpiDeleteBitmap( hbmSqr);
284: }
285:
286: if (hdcLocal) /* keypad button */
287: {
288: GpiDestroyPS( hpsLocal);
289: if (hbmLocal)
290: GpiDeleteBitmap( hbmLocal);
291: }
292:
293: WinDestroyWindow(hwndCalcFrame);
294:
295: WinDestroyMsgQueue(hmqCalc);
296: WinTerminate(hab);
297:
298: DosExit(EXIT_PROCESS, 0); /* exit without error */
299: }
300:
301:
302: /******************************************************************************/
303: /* Calc Window Procedure */
304: /******************************************************************************/
305: MRESULT EXPENTRY
306: CalcWndProc(hwnd, msg, mp1, mp2)
307:
308: HWND hwnd;
309: USHORT msg;
310: MPARAM mp1;
311: MPARAM mp2;
312: {
313: HPS hps;
314: RECTL rclPaint;
315: WPOINT wpt;
316: BOOL fClip;
317: USHORT usFmtInfo;
318: RECTL rcl;
319: SIZEL sizl;
320:
321: switch (msg)
322: {
323: case WM_CREATE:
324: hdcCalc = WinOpenWindowDC( hwnd);
325: WinQueryWindowRect( hwnd, &rcl);
326: sizl.cx = rcl.xRight - rcl.xLeft;
327: sizl.cy = rcl.yTop - rcl.yBottom;
328: hpsCalc = GpiCreatePS( hab
329: , hdcCalc
330: , &sizl
331: , GPIA_ASSOC | PU_PELS );
332: break;
333:
334: case WM_DESTROY:
335: WinDestroyPointer(hptrFinger);
336: GpiDestroyPS( hpsSqr);
337: GpiDeleteBitmap( hbmSqr);
338: GpiDestroyPS( hpsLocal);
339: GpiDeleteBitmap( hbmLocal);
340: break;
341:
342: case WM_INITMENU:
343: fClip = FALSE;
344: if (WinOpenClipbrd( hab))
345: {
346: fClip = WinQueryClipbrdFmtInfo( hab, CF_TEXT, &usFmtInfo);
347: WinCloseClipbrd( hab);
348: }
349: WinSendMsg((HWND)mp2, MM_SETITEMATTR,
350: (MPARAM) MAKELONG(CMD_PASTE, TRUE),
351: (MPARAM) MAKELONG(MIA_DISABLED, fClip ? 0 : MIA_DISABLED));
352: break;
353:
354: case WM_PAINT:
355: hps = WinBeginPaint(hwnd, NULL, &rclPaint);
356: CalcPaint( hwnd, hps); /* re-draw calculator */
357: WinEndPaint(hps);
358: break;
359:
360: case WM_COMMAND:
361: if (fError)
362: break;
363: switch(LOUSHORT(mp1))
364: {
365: case CMD_COPY:
366: DataXCopy(); /* copy to clipboard */
367: break;
368: case CMD_PASTE:
369: DataXPaste(); /* paste from clipboard */
370: break;
371: case CMD_EXIT:
372: WinPostMsg( hwndCalcFrame, WM_QUIT, 0L, 0L);
373: break;
374: case CMD_ABOUT:
375: WinDlgBox( HWND_DESKTOP
376: , hwndCalcFrame
377: , (PFNWP)AboutDlgProc
378: , NULL
379: , 1
380: , (PSZ)NULL );
381: break;
382: }
383: break;
384:
385: case WM_CLOSE:
386: WinPostMsg(hwndCalcFrame, WM_QUIT, 0L, 0L);
387: break;
388:
389: case WM_MOUSEMOVE:
390: WinSetPointer( HWND_DESKTOP, hptrFinger);
391: break;
392:
393: case WM_BUTTON1DOWN:
394: wpt.x = LOUSHORT(mp1);
395: wpt.y = HIUSHORT(mp1);
396: ProcessKey( &wpt);
397: goto dwp;
398: break;
399:
400: case WM_CHAR:
401: if (SHORT1FROMMP(mp1) & KC_KEYUP)
402: {
403: if (CHAR4FROMMP(mp1) == uchMScan)
404: fMDown = FALSE; /* 'm' key went up */
405: }
406: else if (SHORT1FROMMP(mp1) & KC_CHAR)
407: {
408: if (InterpretChar(CHAR1FROMMP(mp2)))
409: UpdateDisplay();
410: else if ((CHAR1FROMMP(mp2)=='m') || (CHAR1FROMMP(mp2)=='M'))
411: {
412: uchMScan = CHAR4FROMMP(mp1); /* save 'm' key scan code */
413: fMDown = TRUE; /* 'm' key went down */
414: }
415: }
416: break;
417:
418: case WM_ACTIVATE:
419: if (HIUSHORT(mp1))
420: WinSetFocus( HWND_DESKTOP, hwndCalc);
421: break;
422:
423: case WM_SETFOCUS:
424: if ((HWNDFROMMP(mp1)==hwndCalc) && !mp2);
425: fMDown = FALSE; /* since we are losing focus */
426: break;
427:
428: dwp:
429: default:
430: return(WinDefWindowProc(hwnd, msg, mp1, mp2));
431: break;
432: }
433: return(0L);
434: }
435:
436:
437: /******************************************************************************/
438: /* translate & interpret keys (ie. locate in logical keyboard) */
439: /******************************************************************************/
440: BOOL
441: InterpretChar( ch)
442:
443: CHAR ch;
444: {
445: BOOL fDone;
446: NPCH pchStep;
447: INT i;
448:
449: fDone = FALSE;
450: pchStep = achKeys;
451: switch (ch)
452: {
453: case 'n':
454: ch = szPlusMinus[0];
455: break;
456: case 27: /* xlate Escape into 'c' */
457: ch = 'c';
458: break;
459: case '\r': /* xlate Enter into '=' */
460: ch = '=';
461: break;
462: }
463:
464: if (fMDown) /* Do memory keys */
465: {
466: switch (ch)
467: {
468: case 'c':
469: case 'C':
470: ch = '\274';
471: break;
472: case 'r':
473: case 'R':
474: ch = '\273';
475: break;
476: case '+':
477: ch = '\272';
478: break;
479: case '-':
480: ch = '\271';
481: break;
482: }
483: }
484:
485: while (!fDone && *pchStep)
486: {
487: if (*pchStep++ == ch)
488: fDone = TRUE; /* char found in logical keyboard */
489: }
490: if (fDone)
491: {
492: chLastKey = chCurrKey;
493: i = pchStep - achKeys - 1;
494: FlipKey( hpsCalc, i/6, i%6);
495: Evaluate( achKeys[i]);
496: }
497: return (fDone);
498: }
499:
500:
501: /******************************************************************************/
502: /* briefly reverse the shading on one of the keys */
503: /******************************************************************************/
504: VOID
505: FlipKey( hps, iRow, iCol)
506:
507: HPS hps;
508: INT iRow, iCol;
509: {
510: RECTL rcl;
511:
512: rcl.xLeft = (iCol * 6 * sCharWidth) + (14 * sCharWidth / 10);
513: rcl.yBottom = (165 * sCharHeight / 100) + (2 * iRow * sCharHeight);
514: rcl.xRight = rcl.xLeft + (11 * sCharWidth / 3);
515: rcl.yTop = rcl.yBottom + (7 * sCharHeight / 4);
516: WinInvertRect( hps, &rcl);
517: DosSleep( 50L);
518: WinInvertRect( hps, &rcl);
519: }
520:
521:
522: /******************************************************************************/
523: /* compute whether a point is over a button and flash the button if so */
524: /******************************************************************************/
525: BOOL
526: FlashSqr( hps, pwpt)
527:
528: HPS hps;
529: PWPOINT pwpt;
530: {
531: INT iRow, iCol;
532: BOOL fDone;
533:
534: /* find x range */
535: fDone = FALSE;
536: iCol = 0;
537: iRow = 3;
538: while (!fDone && iCol<6)
539: {
540: if (pwpt->x < (iCol * 6 * sCharWidth)
541: + (14 * sCharWidth / 10)
542: + (11*sCharWidth/3) )
543: {
544: if (pwpt->x > (iCol * 6 * sCharWidth) + (14 * sCharWidth / 10))
545: fDone = TRUE;
546: else
547: return FALSE;
548: }
549: else
550: iCol++;
551: }
552: if (!fDone)
553: return FALSE;
554: fDone = FALSE;
555: while (!fDone && iRow >= 0)
556: {
557: if (pwpt->y > ((165 * sCharHeight / 100) + (2 * iRow * sCharHeight)))
558: {
559: if (pwpt->y < (165 * sCharHeight / 100)
560: + (2 * iRow * sCharHeight)
561: + (7 * sCharHeight / 4) )
562: fDone = TRUE;
563: else
564: return FALSE;
565: }
566: else
567: iRow--;
568: }
569: if (!fDone)
570: return FALSE;
571: pwpt->x = iCol;
572: pwpt->y = iRow;
573: FlipKey( hps, iRow, iCol);
574: return TRUE;
575: }
576:
577:
578: /******************************************************************************/
579: /* which key is point on? */
580: /******************************************************************************/
581: CHAR
582: Translate( pwpt)
583:
584: PWPOINT pwpt;
585: {
586: return( achKeys[ pwpt->y * 6 + pwpt->x]);
587: }
588:
589:
590: /******************************************************************************/
591: /* invoke flashing, point-to-key translation, and result-display update */
592: /******************************************************************************/
593: VOID
594: ProcessKey( pwpt)
595:
596: PWPOINT pwpt;
597: {
598: BOOL fFlashed;
599:
600: chLastKey = chCurrKey;
601: fFlashed = FlashSqr( hpsCalc, pwpt);
602:
603: if (fFlashed)
604: Evaluate( (BYTE)Translate( pwpt));
605: UpdateDisplay();
606: }
607:
608:
609: /******************************************************************************/
610: /* draw a blank key */
611: /******************************************************************************/
612: VOID
613: FrameKey(hps, iRow, iCol)
614:
615: HPS hps;
616: INT iRow, iCol;
617: {
618: POINTL aptl[3];
619:
620: aptl[0].x = (iCol * 6 * sCharWidth) + (14 * sCharWidth / 10);
621: aptl[0].y = (165 * sCharHeight / 100) + (2 * iRow * sCharHeight);
622: aptl[1].x = (11 * sCharWidth / 3) + (aptl[0].x);
623: aptl[1].y = (7 * sCharHeight / 4) + (aptl[0].y);
624: aptl[2].x = 0;
625: aptl[2].y = 0;
626: GpiBitBlt( hps, hpsLocal, 3L, aptl, ROP_SRCCOPY, BBO_IGNORE);
627: }
628:
629:
630: /******************************************************************************/
631: /* draw the keys and fill in numbers */
632: /******************************************************************************/
633: VOID
634: DrawNumbers(hps)
635:
636: HPS hps;
637: {
638: INT iRow, iCol;
639:
640: /* Draw the keys and fill in the numbers we can */
641: for (iRow = 0; iRow < 4; iRow++)
642: {
643: for (iCol = 0; iCol < 6; iCol++)
644: {
645: FrameKey( hps, iRow, iCol);
646: CalcTextOut( hps
647: , (iCol * 6 * sCharWidth)
648: + (WIDTHCONST * sCharWidth / 10)
649: , (iRow + 1) * 2 * sCharHeight
650: , (PSZ)(achDKeys + (iRow * 6) + iCol)
651: , 1 );
652: }
653: }
654: }
655:
656:
657: /******************************************************************************/
658: /* redraw the whole calculator */
659: /******************************************************************************/
660: VOID
661: CalcPaint( hwnd, hps)
662:
663: HWND hwnd;
664: HPS hps;
665: {
666: RECTL rclDst;
667: CHARBUNDLE cbnd;
668: INT iX, iY;
669:
670: WinQueryWindowRect( hwnd, &rclDst);
671: WinFillRect( hps, &rclDst, CLR_GREEN);
672:
673: DrawNumbers(hps);
674: CalcTextOut(hps, iX = (11 * sCharWidth / 5) + 1, iY = 2 * sCharHeight,
675: (PSZ)"M-", 2);
676: CalcTextOut(hps, iX, iY + 2 * sCharHeight, (PSZ)"M+", 2);
677: CalcTextOut(hps, iX, iY + 4 * sCharHeight, (PSZ)"MR", 2);
678: CalcTextOut(hps, iX, iY + 6 * sCharHeight, (PSZ)"MC", 2);
679:
680: /* Draw the minus of the plus/minus button */
681: cbnd.usBackMixMode = FM_LEAVEALONE;
682: GpiSetAttrs( hps, PRIM_CHAR, CBB_BACK_MIX_MODE, 0L, &cbnd);
683: iX = (3 * 6 * sCharWidth) + (WIDTHCONST * sCharWidth / 10);
684: CalcTextOut( hps, iX, iY + sCharHeight / 4, (PSZ)"_", 1);
685:
686: /* Draw the square root bitmap */
687: rclDst.xLeft = 160 * sCharWidth / 5;
688: rclDst.yBottom = 31 * sCharHeight / 4;
689: rclDst.xRight = rclDst.xLeft + 2 * sCharWidth;
690: rclDst.yTop = rclDst.yBottom + (3 * sCharHeight / 2);
691: WinDrawBitmap( hps
692: , hbmSqr
693: , NULL
694: , (PPOINTL)&rclDst
695: , CLR_WHITE
696: , CLR_BLACK
697: , DBM_STRETCH );
698:
699: UpdateDisplay();
700: }
701:
702:
703: /******************************************************************************/
704: /* initialize the bitmaps for a blank key and for the square-root sign */
705: /******************************************************************************/
706: BOOL
707: PSInit()
708: {
709: HPS hps;
710: FONTMETRICS fm;
711: POINTL ptl;
712: SIZEL sizl;
713: BITMAPINFOHEADER bmp;
714: POINTL aptl[4];
715: LONG alCaps[2];
716:
717: /**************************************************************************/
718: /* compute the units of horizontal and vertical distance based on font */
719: /**************************************************************************/
720: hps = WinGetPS( HWND_DESKTOP);
721: GpiQueryFontMetrics( hps, (LONG)sizeof(FONTMETRICS), &fm);
722: sCharHeight = (SHORT)(fm.lEmHeight); /* avg height of uppercase character */
723: sCharWidth = (SHORT)(fm.lEmInc); /* usually 'M' increment */
724: WinReleasePS( hps);
725:
726: /**************************************************************************/
727: /* prepare the square root bitmap */
728: /**************************************************************************/
729: hdcSqr = DevOpenDC( hab, OD_MEMORY, "*", 3L, (PDEVOPENDATA)&dop, NULL);
730: if( !hdcSqr)
731: return(FALSE);
732:
733: sizl.cx = sizl.cy = 0L;
734: hpsSqr = GpiCreatePS( hab
735: , hdcSqr
736: , &sizl
737: , PU_PELS | GPIT_MICRO | GPIA_ASSOC );
738: hbmSqr = GpiLoadBitmap( hpsSqr, NULL, IDB_SQR, 0L, 0L);
739:
740: /**************************************************************************/
741: /* prepare the bitmap of a blank key */
742: /**************************************************************************/
743: hdcLocal = DevOpenDC( hab, OD_MEMORY, "*", 3L, (PDEVOPENDATA)&dop, NULL);
744: if( !hdcLocal)
745: return(FALSE);
746:
747: sizl.cx = sizl.cy = 0L;
748: hpsLocal = GpiCreatePS( hab
749: , hdcLocal
750: , &sizl
751: , PU_PELS | GPIT_MICRO | GPIA_ASSOC );
752: bmp.cbFix = 12;
753: bmp.cx = 11 * sCharWidth / 3;
754: bmp.cy = sCharHeight * 2;
755: DevQueryCaps( hdcLocal, CAPS_COLOR_PLANES, 2L, alCaps);
756: bmp.cPlanes = (USHORT)alCaps[0];
757: bmp.cBitCount = (USHORT)alCaps[1];
758: hbmLocal = GpiCreateBitmap( hpsLocal, (PBITMAPINFOHEADER2)&bmp, 0L, NULL, NULL);
759: if( !hbmLocal )
760: return(FALSE);
761: GpiSetBitmap( hpsLocal, hbmLocal);
762:
763: aptl[0].x = aptl[0].y = 0;
764: aptl[1].x = 11 * sCharWidth / 3;
765: aptl[1].y = 7 * sCharHeight / 4;
766: aptl[2].x = aptl[2].y = 0;
767: aptl[3].x = aptl[1].x;
768: aptl[3].y = aptl[1].y;
769: GpiSetColor( hpsLocal, CLR_GREEN); /* match the background to client */
770: GpiBitBlt( hpsLocal, NULL, 2L, aptl, ROP_PATCOPY, BBO_IGNORE);
771:
772: /* Draw the rounded rect */
773: ptl.x = 0;
774: ptl.y = 0;
775: GpiSetCurrentPosition( hpsLocal, &ptl);
776: ptl.x = (11 * sCharWidth / 3) - 1;
777: ptl.y = (7 * sCharHeight / 4) - 1;
778: GpiSetColor( hpsLocal, CLR_WHITE); /* white interior */
779: GpiBox( hpsLocal
780: , DRO_FILL
781: , &ptl
782: , (LONG)sCharWidth
783: , (LONG)(sCharHeight / 2) );
784: ptl.x = 0;
785: ptl.y = 0;
786: GpiSetCurrentPosition( hpsLocal, &ptl);
787: ptl.x = (11 * sCharWidth / 3) - 1;
788: ptl.y = (7 * sCharHeight / 4) - 1;
789: GpiSetColor( hpsLocal, CLR_BLACK); /* black border */
790: GpiBox( hpsLocal
791: , DRO_OUTLINE
792: , &ptl
793: , (LONG)sCharWidth
794: , (LONG)(sCharHeight / 2) );
795: return( TRUE);
796: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.