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