home *** CD-ROM | disk | FTP | other *** search
/ Programming Windows (5th Edition) / Programming Windows, 5th ed. - Companion CD (097-0002183)(1999).iso / Chap11 / HexCalc / HexCalc.c next >
Encoding:
C/C++ Source or Header  |  1998-10-09  |  4.6 KB  |  145 lines

  1. /*----------------------------------------
  2.    HEXCALC.C -- Hexadecimal Calculator
  3.                 (c) Charles Petzold, 1998
  4.   ----------------------------------------*/
  5.  
  6. #include <windows.h>
  7.  
  8. LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
  9.  
  10. int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
  11.                     PSTR szCmdLine, int iCmdShow)
  12. {
  13.      static TCHAR szAppName[] = TEXT ("HexCalc") ;
  14.      HWND         hwnd ;
  15.      MSG          msg ;
  16.      WNDCLASS     wndclass ;
  17.      
  18.      wndclass.style         = CS_HREDRAW | CS_VREDRAW;
  19.      wndclass.lpfnWndProc   = WndProc ;
  20.      wndclass.cbClsExtra    = 0 ;
  21.      wndclass.cbWndExtra    = DLGWINDOWEXTRA ;    // Note!
  22.      wndclass.hInstance     = hInstance ;
  23.      wndclass.hIcon         = LoadIcon (hInstance, szAppName) ;
  24.      wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
  25.      wndclass.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1) ;
  26.      wndclass.lpszMenuName  = NULL ;
  27.      wndclass.lpszClassName = szAppName ;
  28.      
  29.      if (!RegisterClass (&wndclass))
  30.      {
  31.           MessageBox (NULL, TEXT ("This program requires Windows NT!"),
  32.                       szAppName, MB_ICONERROR) ;
  33.           return 0 ;
  34.      }
  35.      
  36.      hwnd = CreateDialog (hInstance, szAppName, 0, NULL) ;
  37.      
  38.      ShowWindow (hwnd, iCmdShow) ;
  39.      
  40.      while (GetMessage (&msg, NULL, 0, 0))
  41.      {
  42.           TranslateMessage (&msg) ;
  43.           DispatchMessage (&msg) ;
  44.      }
  45.      return msg.wParam ;
  46. }
  47.  
  48. void ShowNumber (HWND hwnd, UINT iNumber)
  49. {
  50.      TCHAR szBuffer[20] ;
  51.  
  52.      wsprintf (szBuffer, TEXT ("%X"), iNumber) ;
  53.      SetDlgItemText (hwnd, VK_ESCAPE, szBuffer) ;
  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: MAXDWORD ;
  70.      case '%': return iNum ? iFirstNum % iNum: MAXDWORD ;
  71.      default : return 0 ;
  72.      }
  73. }
  74.  
  75. LRESULT CALLBACK WndProc (HWND hwnd, UINT message, 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 (message)
  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 = (WPARAM) CharUpper ((TCHAR *) wParam)) == VK_RETURN)
  91.                wParam = '=' ;
  92.           
  93.           if (hButton = GetDlgItem (hwnd, wParam))
  94.           {
  95.                SendMessage (hButton, BM_SETSTATE, 1, 0) ;
  96.                Sleep (100) ;
  97.                SendMessage (hButton, BM_SETSTATE, 0, 0) ;
  98.           }
  99.           else
  100.           {
  101.                MessageBeep (0) ;
  102.                break ;
  103.           }
  104.                                         // fall through
  105.      case WM_COMMAND:
  106.           SetFocus (hwnd) ;
  107.           
  108.           if (LOWORD (wParam) == VK_BACK)         // backspace
  109.                ShowNumber (hwnd, iNumber /= 16) ;
  110.           
  111.           else if (LOWORD (wParam) == VK_ESCAPE)  // escape
  112.                ShowNumber (hwnd, iNumber = 0) ;
  113.           
  114.           else if (isxdigit (LOWORD (wParam)))    // hex digit
  115.           {
  116.                if (bNewNumber)
  117.                {
  118.                     iFirstNum = iNumber ;
  119.                     iNumber = 0 ;
  120.                }
  121.                bNewNumber = FALSE ;
  122.                
  123.                if (iNumber <= MAXDWORD >> 4)
  124.                     ShowNumber (hwnd, iNumber = 16 * iNumber + wParam -
  125.                     (isdigit (wParam) ? '0': 'A' - 10)) ;
  126.                else
  127.                     MessageBeep (0) ;
  128.           }
  129.           else                                    // operation
  130.           {
  131.                if (!bNewNumber)
  132.                     ShowNumber (hwnd, iNumber =
  133.                          CalcIt (iFirstNum, iOperation, iNumber)) ;
  134.                bNewNumber = TRUE ;
  135.                iOperation = LOWORD (wParam) ;
  136.           }
  137.           return 0 ;
  138.           
  139.      case WM_DESTROY:
  140.           PostQuitMessage (0) ;
  141.           return 0 ;
  142.      }
  143.      return DefWindowProc (hwnd, message, wParam, lParam) ;
  144. }
  145.