home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: Science / Science.zip / HEXCALC2.ZIP / HEXCALC2.C < prev    next >
C/C++ Source or Header  |  1989-12-06  |  13KB  |  342 lines

  1. /*-------------------------------------------------------------------
  2.    HEXCALC2.C -- Hexadecimal Calculator with Clipboard Cut and Paste
  3.   -------------------------------------------------------------------*/
  4.  
  5. #define INCL_WIN
  6. #include <os2.h>
  7. #include <ctype.h>
  8. #include <limits.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include "hexcalc.h"
  12.  
  13. #define IDM_COPY    256
  14. #define IDM_PASTE   257
  15.  
  16. MRESULT EXPENTRY ClientWndProc (HWND, USHORT, MPARAM, MPARAM) ;
  17.  
  18. HAB  hab ;
  19.  
  20. USHORT base = 16;
  21.  
  22. int main (void)
  23.      {
  24.      HMQ  hmq ;
  25.      HWND hwndFrame ;
  26.      QMSG qmsg ;
  27.  
  28.      hab = WinInitialize (0) ;
  29.      hmq = WinCreateMsgQueue (hab, 0) ;
  30.  
  31.      WinRegisterClass (hab, CLIENTCLASS, ClientWndProc, 0L, 0) ;
  32.  
  33.      hwndFrame = WinLoadDlg (HWND_DESKTOP, HWND_DESKTOP,
  34.                              NULL, NULL, ID_HEXCALC, NULL) ;
  35.  
  36.      WinSendMsg (hwndFrame, WM_SETICON,
  37.                  WinLoadPointer (HWND_DESKTOP, NULL, ID_ICON), NULL) ;
  38.  
  39.      WinSetFocus (HWND_DESKTOP, WinWindowFromID (hwndFrame, FID_CLIENT)) ;
  40.  
  41.      while (WinGetMsg (hab, &qmsg, NULL, 0, 0))
  42.           WinDispatchMsg (hab, &qmsg) ;
  43.  
  44.      WinDestroyWindow (hwndFrame) ;
  45.      WinDestroyMsgQueue (hmq) ;
  46.      WinTerminate (hab) ;
  47.      return 0 ;
  48.      }
  49.  
  50. HACCEL AddItemsToSysMenu (HWND hwndFrame)
  51.      {
  52.      static CHAR     *szMenuText [3] = { NULL, "~Copy\tCtrl+Ins",
  53.                                                "~Paste\tShift+Ins" } ;
  54.      static MENUITEM mi [3] = {
  55.                               MIT_END, MIS_SEPARATOR, 0, 0,         NULL, NULL,
  56.                               MIT_END, MIS_TEXT,      0, IDM_COPY,  NULL, NULL,
  57.                               MIT_END, MIS_TEXT,      0, IDM_PASTE, NULL, NULL
  58.                               } ;
  59.      ACCELTABLE      *pacct ;
  60.      HACCEL          haccel ;
  61.      HWND            hwndSysMenu, hwndSysSubMenu ;
  62.      MENUITEM        miSysMenu ;
  63.      SHORT           idSysMenu, sItem ;
  64.  
  65.                               // Add items to system menu
  66.  
  67.      hwndSysMenu = WinWindowFromID (hwndFrame, FID_SYSMENU) ;
  68.      idSysMenu = SHORT1FROMMR (WinSendMsg (hwndSysMenu,
  69.                                            MM_ITEMIDFROMPOSITION,
  70.                                            NULL, NULL)) ;
  71.  
  72.      WinSendMsg (hwndSysMenu, MM_QUERYITEM,
  73.                  MPFROM2SHORT (idSysMenu, FALSE),
  74.                  MPFROMP (&miSysMenu)) ;
  75.  
  76.      hwndSysSubMenu = miSysMenu.hwndSubMenu ;
  77.  
  78.      for (sItem = 0 ; sItem < 3 ; sItem++)
  79.           WinSendMsg (hwndSysSubMenu, MM_INSERTITEM,
  80.                       MPFROMP (mi + sItem),
  81.                       MPFROMP (szMenuText [sItem])) ;
  82.  
  83.                               // Create and set accelerator table
  84.  
  85.      pacct = malloc (sizeof (ACCELTABLE) + sizeof (ACCEL)) ;
  86.  
  87.      pacct->cAccel        = 2 ;    // Number of accelerators
  88.      pacct->codepage      = 0 ;    // Not used
  89.  
  90.      pacct->aaccel[0].fs  = AF_VIRTUALKEY | AF_CONTROL ;
  91.      pacct->aaccel[0].key = VK_INSERT ;
  92.      pacct->aaccel[0].cmd = IDM_COPY ;
  93.  
  94.      pacct->aaccel[1].fs  = AF_VIRTUALKEY | AF_SHIFT ;
  95.      pacct->aaccel[1].key = VK_INSERT ;
  96.      pacct->aaccel[1].cmd = IDM_PASTE ;
  97.  
  98.      haccel = WinCreateAccelTable (hab, pacct) ;
  99.      WinSetAccelTable (hab, haccel, hwndFrame) ;
  100.  
  101.      free (pacct) ;
  102.  
  103.      return haccel ;
  104.      }
  105.  
  106. VOID EnableSysMenuItem (HWND hwnd, USHORT idItem, BOOL fEnable)
  107.      {
  108.      HWND hwndSysMenu ;
  109.  
  110.      hwndSysMenu = WinWindowFromID (WinQueryWindow (hwnd, QW_PARENT, FALSE),
  111.                                     FID_SYSMENU) ;
  112.  
  113.      WinSendMsg (hwndSysMenu, MM_SETITEMATTR,
  114.                  MPFROM2SHORT (idItem, TRUE),
  115.                  MPFROM2SHORT (MIA_DISABLED, fEnable ? 0 : MIA_DISABLED)) ;
  116.      }
  117.  
  118. void ShowNumber (HWND hwnd, ULONG ulNumber)
  119.      {
  120.      CHAR szBuffer [50] ;
  121.  
  122.      WinSetWindowText (WinWindowFromID (hwnd, ESCAPE),
  123.                        strupr (ltoa (ulNumber, szBuffer, base))) ;
  124.      }
  125.  
  126. ULONG CalcIt (ULONG ulFirstNum, SHORT sOperation, ULONG ulNum)
  127.      {
  128.      switch (sOperation)
  129.           {
  130.           case '=' : return ulNum ;
  131.           case '+' : return ulFirstNum +  ulNum ;
  132.           case '-' : return ulFirstNum -  ulNum ;
  133.           case '*' : return ulFirstNum *  ulNum ;
  134.           case '&' : return ulFirstNum &  ulNum ;
  135.           case '|' : return ulFirstNum |  ulNum ;
  136.           case '^' : return ulFirstNum ^  ulNum ;
  137.           case '<' : return ulFirstNum << ulNum ;
  138.           case '>' : return ulFirstNum >> ulNum ;
  139.           case '/' : return ulNum ? ulFirstNum / ulNum : ULONG_MAX ;
  140.           case '%' : return ulNum ? ulFirstNum % ulNum : ULONG_MAX ;
  141.           default  : return 0L ;
  142.           }
  143.      }
  144.  
  145. MRESULT EXPENTRY ClientWndProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
  146.      {
  147.      static BOOL   fNewNumber = TRUE ;
  148.      static HACCEL haccel ;
  149.      static ULONG  ulNumber, ulFirstNum ;
  150.      static SHORT  sOperation = '=' ;
  151.      HWND          hwndButton ;
  152.      PCHAR         pchClipText ;
  153.      QMSG          qmsg ;
  154.      SEL           selClipText ;
  155.      SHORT         s, sLen, idButton ;
  156.  
  157.      switch (msg)
  158.           {
  159.           case WM_CREATE:
  160.                haccel = AddItemsToSysMenu (
  161.                               WinQueryWindow (hwnd, QW_PARENT, FALSE)) ;
  162.                return 0 ;
  163.  
  164.           case WM_CHAR:
  165.                if (CHARMSG(&msg)->fs & KC_KEYUP)
  166.                     return 0 ;
  167.  
  168.                if (CHARMSG(&msg)->fs & KC_VIRTUALKEY)
  169.                     switch (CHARMSG(&msg)->vkey)
  170.                          {
  171.                          case VK_LEFT:
  172.                               if (!(CHARMSG(&msg)->fs & KC_CHAR))
  173.                                    {
  174.                                    CHARMSG(&msg)->chr = '\b' ;
  175.                                    CHARMSG(&msg)->fs |= KC_CHAR ;
  176.                                    }
  177.                               break ;
  178.  
  179.                          case VK_ESC:
  180.                               CHARMSG(&msg)->chr = ESCAPE ;
  181.                               CHARMSG(&msg)->fs |= KC_CHAR ;
  182.                               break ;
  183.  
  184.                          case VK_NEWLINE:
  185.                          case VK_ENTER:
  186.                               CHARMSG(&msg)->chr = '=' ;
  187.                               CHARMSG(&msg)->fs |= KC_CHAR ;
  188.                               break ;
  189.                          }
  190.  
  191.                if (CHARMSG(&msg)->fs & KC_CHAR)
  192.                     {
  193.                     CHARMSG(&msg)->chr = toupper (CHARMSG(&msg)->chr) ;
  194.  
  195.                     if (hwndButton = WinWindowFromID (hwnd,CHARMSG(&msg)->chr))
  196.                          WinSendMsg (hwndButton, BM_CLICK, NULL, NULL) ;
  197.                     else
  198.                          WinAlarm (HWND_DESKTOP, WA_ERROR) ;
  199.                     }
  200.                return 1 ;
  201.  
  202.           case WM_COMMAND:
  203.                idButton = COMMANDMSG(&msg)->cmd ;
  204.  
  205.                if (idButton == IDM_COPY)                    // "Copy"
  206.                     {
  207.                     hwndButton = WinWindowFromID (hwnd, ESCAPE) ;
  208.                     sLen = WinQueryWindowTextLength (hwndButton) + 1 ;
  209.  
  210.                     DosAllocSeg (sLen, &selClipText, SEG_GIVEABLE) ;
  211.                     pchClipText = MAKEP (selClipText, 0) ;
  212.                     WinQueryWindowText (hwndButton, sLen, pchClipText) ;
  213.  
  214.                     WinOpenClipbrd (hab) ;
  215.                     WinEmptyClipbrd (hab) ;
  216.                     WinSetClipbrdData (hab, (ULONG) selClipText, CF_TEXT,
  217.                                        CFI_SELECTOR) ;
  218.                     WinCloseClipbrd (hab) ;
  219.                     }
  220.  
  221.                else if (idButton == IDM_PASTE)              // "Paste"
  222.                     {
  223.                     EnableSysMenuItem (hwnd, IDM_COPY,  FALSE) ;
  224.                     EnableSysMenuItem (hwnd, IDM_PASTE, FALSE) ;
  225.  
  226.                     WinOpenClipbrd (hab) ;
  227.  
  228.                     selClipText = (SEL) WinQueryClipbrdData (hab, CF_TEXT) ;
  229.  
  230.                     if (selClipText != 0)
  231.                          {
  232.                          pchClipText = MAKEP (selClipText, 0) ;
  233.  
  234.                          for (s = 0 ; pchClipText[s] ; s++)
  235.                               {
  236.                               if (pchClipText[s] == '\r')
  237.                                    WinSendMsg (hwnd, WM_CHAR,
  238.                                                MPFROM2SHORT (KC_CHAR, 1),
  239.                                                MPFROM2SHORT ('=', 0)) ;
  240.  
  241.                               else if (pchClipText[s] != '\n' &&
  242.                                        pchClipText[s] != ' ')
  243.                                    WinSendMsg (hwnd, WM_CHAR,
  244.                                                MPFROM2SHORT (KC_CHAR, 1),
  245.                                                MPFROM2SHORT (pchClipText[s],
  246.                                                              0)) ;
  247.  
  248.                               while (WinPeekMsg (hab, &qmsg, NULL, 0, 0,
  249.                                                  PM_NOREMOVE))
  250.                                    {
  251.                                    if (qmsg.msg == WM_QUIT)
  252.                                         {
  253.                                         WinCloseClipbrd (hab) ;
  254.                                         return 0 ;
  255.                                         }
  256.                                    else
  257.                                         {
  258.                                         WinGetMsg (hab, &qmsg, NULL, 0, 0) ;
  259.                                         WinDispatchMsg (hab, &qmsg) ;
  260.                                         }
  261.                                    }
  262.                               }
  263.                          }
  264.                     WinCloseClipbrd (hab) ;
  265.  
  266.                     EnableSysMenuItem (hwnd, IDM_COPY,  TRUE) ;
  267.                     EnableSysMenuItem (hwnd, IDM_PASTE, TRUE) ;
  268.                     }
  269.  
  270.                else if (idButton == '\b')                   // backspace
  271.                     ShowNumber (hwnd, ulNumber /= 16) ;
  272.  
  273.                else if (idButton == ESCAPE)                 // escape
  274.                     ShowNumber (hwnd, ulNumber = 0L) ;
  275.  
  276.                else if (isxdigit (idButton))                // hex digit
  277.                     {
  278.                     if (fNewNumber)
  279.                          {
  280.                          ulFirstNum = ulNumber ;
  281.                          ulNumber = 0L ;
  282.                          }
  283.                     fNewNumber = FALSE ;
  284.  
  285.                     if (ulNumber <= ULONG_MAX >> 4) {
  286.                         if( base == 2 && (idButton != '0' && idButton != '1') ) {
  287.                                 WinAlarm (HWND_DESKTOP, WA_ERROR) ;
  288.                                 return( 0 );
  289.                         } else if( base == 8 ) {
  290.                                 if( !isdigit( idButton ) ||
  291.                                     ( idButton == '8' )  ||
  292.                                     ( idButton == '9' )    ) {
  293.                                         WinAlarm (HWND_DESKTOP, WA_ERROR) ;
  294.                                         return( 0 );
  295.                                 }
  296.                         } else if( base == 10 && !isdigit( idButton ) ) {
  297.                                 WinAlarm (HWND_DESKTOP, WA_ERROR) ;
  298.                                 return( 0 );
  299.                         }
  300.  
  301.                          ShowNumber (hwnd,
  302.                               ulNumber = base * ulNumber + idButton -
  303.                                    (isdigit (idButton) ? '0' : 'A' - 10)) ;
  304.                     } else
  305.                          WinAlarm (HWND_DESKTOP, WA_ERROR) ;
  306.                     }
  307.                else if(  idButton == 9000 ) {
  308.                         base = 16;
  309.                         ShowNumber ( hwnd, ulNumber );
  310.                } else if( idButton == 9001 ) {
  311.                         base = 2;
  312.                         ShowNumber ( hwnd, ulNumber );
  313.                } else if( idButton == 9002 ) {
  314.                         base = 10;
  315.                         ShowNumber ( hwnd, ulNumber );
  316.                } else if( idButton == 9003 ) {
  317.                         base = 8;
  318.                         ShowNumber ( hwnd, ulNumber );
  319.                } else                                         // operation
  320.                     {
  321.                     if (!fNewNumber)
  322.                          ShowNumber (hwnd, ulNumber =
  323.                               CalcIt (ulFirstNum, sOperation, ulNumber)) ;
  324.                     fNewNumber = TRUE ;
  325.                     sOperation = idButton ;
  326.                     }
  327.                return 0 ;
  328.  
  329.           case WM_BUTTON1DOWN:
  330.                WinAlarm (HWND_DESKTOP, WA_ERROR) ;
  331.                break ;
  332.  
  333.           case WM_ERASEBACKGROUND:
  334.                return 1 ;
  335.  
  336.           case WM_DESTROY:
  337.                WinDestroyAccelTable (haccel) ;
  338.                return 0 ;
  339.           }
  340.      return WinDefWindowProc (hwnd, msg, mp1, mp2) ;
  341.      }
  342.