home *** CD-ROM | disk | FTP | other *** search
/ Programming Windows 95 / Programming Windows 95.iso / code / CHAP11 / HEXCALC.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-01-01  |  4.9 KB  |  146 lines

  1. /*----------------------------------------
  2.    HEXCALC.C -- Hexadecimal Calculator
  3.                 (c) Charles Petzold, 1996
  4.   ----------------------------------------*/
  5.  
  6. #include <windows.h>
  7. #include <limits.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <ctype.h>
  11.  
  12. LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
  13.  
  14. int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
  15.                     PSTR szCmdLine, int iCmdShow)
  16.      {
  17.      static char  szAppName[] = "HexCalc" ;
  18.      HWND         hwnd ;
  19.      MSG          msg ;
  20.      WNDCLASSEX   wndclass ;
  21.  
  22.      wndclass.cbSize        = sizeof (wndclass) ;
  23.      wndclass.style         = CS_HREDRAW | CS_VREDRAW;
  24.      wndclass.lpfnWndProc   = WndProc ;
  25.      wndclass.cbClsExtra    = 0 ;
  26.      wndclass.cbWndExtra    = DLGWINDOWEXTRA ;
  27.      wndclass.hInstance     = hInstance ;
  28.      wndclass.hIcon         = LoadIcon (hInstance, szAppName) ;
  29.      wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
  30.      wndclass.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1) ;
  31.      wndclass.lpszMenuName  = NULL ;
  32.      wndclass.lpszClassName = szAppName ;
  33.      wndclass.hIconSm       = LoadIcon (hInstance, szAppName) ;
  34.  
  35.      RegisterClassEx (&wndclass) ;
  36.  
  37.      hwnd = CreateDialog (hInstance, szAppName, 0, NULL) ;
  38.  
  39.      ShowWindow (hwnd, iCmdShow) ;
  40.  
  41.      while (GetMessage (&msg, NULL, 0, 0))
  42.           {
  43.           TranslateMessage (&msg) ;
  44.           DispatchMessage (&msg) ;
  45.           }
  46.      return msg.wParam ;
  47.      }
  48.  
  49. void ShowNumber (HWND hwnd, UINT iNumber)
  50.      {
  51.      char szBuffer[20] ;
  52.  
  53.      SetDlgItemText (hwnd, VK_ESCAPE, strupr (ltoa (iNumber, szBuffer, 16))) ;
  54.      }
  55.  
  56. DWORD CalcIt (UINT iFirstNum, int iOperation, UINT iNum)
  57.      {
  58.      switch (iOperation)
  59.           {
  60.           case '=' : return iNum ;
  61.           case '+' : return iFirstNum +  iNum ;
  62.           case '-' : return iFirstNum -  iNum ;
  63.           case '*' : return iFirstNum *  iNum ;
  64.           case '&' : return iFirstNum &  iNum ;
  65.           case '|' : return iFirstNum |  iNum ;
  66.           case '^' : return iFirstNum ^  iNum ;
  67.           case '<' : return iFirstNum << iNum ;
  68.           case '>' : return iFirstNum >> iNum ;
  69.           case '/' : return iNum ? iFirstNum / iNum : UINT_MAX ;
  70.           case '%' : return iNum ? iFirstNum % iNum : UINT_MAX ;
  71.           default  : return 0 ;
  72.           }
  73.      }
  74.  
  75. LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
  76.      {
  77.      static BOOL  bNewNumber = TRUE ;
  78.      static int   iOperation = '=' ;
  79.      static UINT  iNumber, iFirstNum ;
  80.      HWND         hButton ;
  81.  
  82.      switch (iMsg)
  83.           {
  84.           case WM_KEYDOWN :                   // left arrow --> backspace
  85.                if (wParam != VK_LEFT)
  86.                     break ;
  87.                wParam = VK_BACK ;
  88.                                              // fall through
  89.           case WM_CHAR :
  90.                if ((wParam = toupper (wParam)) == VK_RETURN)
  91.                     wParam = '=' ;
  92.  
  93.                hButton = GetDlgItem (hwnd, wParam) ;
  94.  
  95.                if (hButton != NULL)
  96.                     {
  97.                     SendMessage (hButton, BM_SETSTATE, 1, 0) ;
  98.                     SendMessage (hButton, BM_SETSTATE, 0, 0) ;
  99.                     }
  100.                else
  101.                     {
  102.                     MessageBeep (0) ;
  103.                     break ;
  104.                     }
  105.                                              // fall through
  106.           case WM_COMMAND :
  107.                SetFocus (hwnd) ;
  108.  
  109.                if (LOWORD (wParam) == VK_BACK)         // backspace
  110.                     ShowNumber (hwnd, iNumber /= 16) ;
  111.  
  112.                else if (LOWORD (wParam) == VK_ESCAPE)  // escape
  113.                     ShowNumber (hwnd, iNumber = 0) ;
  114.  
  115.                else if (isxdigit (LOWORD (wParam)))    // hex digit
  116.                     {
  117.                     if (bNewNumber)
  118.                          {
  119.                          iFirstNum = iNumber ;
  120.                          iNumber = 0 ;
  121.                          }
  122.                     bNewNumber = FALSE ;
  123.  
  124.                     if (iNumber <= UINT_MAX >> 4)
  125.                          ShowNumber (hwnd, iNumber = 16 * iNumber + wParam -
  126.                               (isdigit (wParam) ? '0' : 'A' - 10)) ;
  127.                     else
  128.                          MessageBeep (0) ;
  129.                     }
  130.                else                                    // operation
  131.                     {
  132.                     if (!bNewNumber)
  133.                          ShowNumber (hwnd, iNumber =
  134.                               CalcIt (iFirstNum, iOperation, iNumber)) ;
  135.                     bNewNumber = TRUE ;
  136.                     iOperation = LOWORD (wParam) ;
  137.                     }
  138.                return 0 ;
  139.  
  140.           case WM_DESTROY :
  141.                PostQuitMessage (0) ;
  142.                return 0 ;
  143.           }
  144.      return DefWindowProc (hwnd, iMsg, wParam, lParam) ;
  145.      }
  146.