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