home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / os2sdk / os2sdk11 / tk3 / calc / dcalc / dcalc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-02-20  |  10.0 KB  |  445 lines

  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. }
  445.