home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / msysjour / vol03 / 01 / hexcalc.all next >
Text File  |  1988-03-07  |  17KB  |  525 lines

  1. Microsoft Systems Journal
  2. Volume 3; Issue 1; January, 1988
  3.  
  4. Code Listings For:
  5.  
  6.     Hexcalc
  7.     pp. 39-48
  8.  
  9. Author(s): Charles Petzold
  10. Title:     HEXCALC: An Instructive Pop-Up Calculator for Microsoft Windows
  11.  
  12.  
  13.  
  14. Figure 2w
  15. =========
  16.  
  17. #--------------------------------------
  18. # HEXCALCW make file (Windows version)
  19. #--------------------------------------
  20.  
  21. hexcalcw.obj: hexcalcw.c
  22.      cl -c -D LINT_ARGS -Gsw -Os -W2 -Zp hexcalcw.c
  23.  
  24. hexcalcw.res : hexcalcw.rc hexcalcw.ico
  25.      rc -r hexcalcw.rc
  26.  
  27. hexcalcw.exe: hexcalcw.obj hexcalcw.def hexcalcw.res
  28.      link4 hexcalcw, /align:16, /map, slibw, hexcalcw
  29.      rc hexcalcw.res
  30.  
  31.  
  32.  
  33. Figure 3w
  34. =========
  35.  
  36.  
  37. /*-----------------------------------------------
  38.    HEXCALCW.RC resource script (Windows version)
  39.   -----------------------------------------------*/
  40.  
  41. #include <windows.h>
  42.  
  43. HexCalcW ICON hexcalcw.ico
  44.  
  45. HexCalcW DIALOG 32768, 0, 102, 122
  46.      STYLE WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX
  47.      CLASS "HexCalcW"
  48.      CAPTION "Hex Calculator"
  49.      BEGIN
  50.           PUSHBUTTON "D",       68,  8,  24, 14, 14
  51.           PUSHBUTTON "A",       65,  8,  40, 14, 14
  52.           PUSHBUTTON "7",       55,  8,  56, 14, 14
  53.           PUSHBUTTON "4",       52,  8,  72, 14, 14
  54.           PUSHBUTTON "1",       49,  8,  88, 14, 14
  55.           PUSHBUTTON "0",       48,  8, 104, 14, 14
  56.           PUSHBUTTON "0",       27, 26,   4, 50, 14
  57.           PUSHBUTTON "E",       69, 26,  24, 14, 14
  58.           PUSHBUTTON "B",       66, 26,  40, 14, 14
  59.           PUSHBUTTON "8",       56, 26,  56, 14, 14
  60.           PUSHBUTTON "5",       53, 26,  72, 14, 14
  61.           PUSHBUTTON "2",       50, 26,  88, 14, 14
  62.           PUSHBUTTON "Back",     8, 26, 104, 32, 14
  63.           PUSHBUTTON "C",       67, 44,  40, 14, 14
  64.           PUSHBUTTON "F",       70, 44,  24, 14, 14
  65.           PUSHBUTTON "9",       57, 44,  56, 14, 14
  66.           PUSHBUTTON "6",       54, 44,  72, 14, 14
  67.           PUSHBUTTON "3",       51, 44,  88, 14, 14
  68.           PUSHBUTTON "+",       43, 62,  24, 14, 14
  69.           PUSHBUTTON "-",       45, 62,  40, 14, 14
  70.           PUSHBUTTON "*",       42, 62,  56, 14, 14
  71.           PUSHBUTTON "/",       47, 62,  72, 14, 14
  72.           PUSHBUTTON "%",       37, 62,  88, 14, 14
  73.           PUSHBUTTON "Equals",  61, 62, 104, 32, 14
  74.           PUSHBUTTON "&&",      38, 80,  24, 14, 14
  75.           PUSHBUTTON "|",      124, 80,  40, 14, 14
  76.           PUSHBUTTON "^",       94, 80,  56, 14, 14
  77.           PUSHBUTTON "<",       60, 80,  72, 14, 14
  78.           PUSHBUTTON ">",       62, 80,  88, 14, 14
  79.      END
  80.  
  81.  
  82. Figure 4w
  83. =========
  84.  
  85.  
  86. ;-------------------------------------------------------
  87. ; HEXCALCW.DEF module definition file (Windows version)
  88. ;-------------------------------------------------------
  89.  
  90. NAME           HexCalcW
  91. DESCRIPTION    'Hexadecimal Calculator (C) Charles Petzold 1987'
  92. STUB           'WINSTUB.EXE'
  93. CODE           MOVEABLE
  94. DATA           MOVEABLE MULTIPLE
  95. HEAPSIZE       1024
  96. STACKSIZE      4096
  97. EXPORTS        WndProc
  98.  
  99.  
  100. Figure 6w
  101. =========
  102.  
  103.  
  104. /*--------------------------------------------------------
  105.    HEXCALCW.C -- Hexadecimal Calculator (Windows version)
  106.   --------------------------------------------------------*/
  107.  
  108. #include <windows.h>
  109. #include <limits.h>
  110. #include <stdlib.h>
  111. #include <string.h>
  112. #include <ctype.h>
  113.  
  114. long FAR PASCAL WndProc (HWND, unsigned, WORD, LONG) ;
  115.  
  116. int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
  117.      HANDLE      hInstance, hPrevInstance;
  118.      LPSTR       lpszCmdLine;
  119.      int         nCmdShow;
  120.      {
  121.      static char szAppName [] = "HexCalcW" ;
  122.      HWND        hWnd ;
  123.      MSG         msg;
  124.      WNDCLASS    wndclass ;
  125.  
  126.      if (!hPrevInstance)
  127.           {
  128.           wndclass.style          = CS_HREDRAW | CS_VREDRAW;
  129.           wndclass.lpfnWndProc    = WndProc ;
  130.           wndclass.cbClsExtra     = 0 ;
  131.           wndclass.cbWndExtra     = 0 ;
  132.           wndclass.hInstance      = hInstance ;
  133.           wndclass.hIcon          = LoadIcon (hInstance, szAppName) ;
  134.           wndclass.hCursor        = LoadCursor (NULL, IDC_ARROW) ;
  135.           wndclass.hbrBackground  = COLOR_WINDOW + 1 ;
  136.           wndclass.lpszMenuName   = NULL ;
  137.           wndclass.lpszClassName  = szAppName ;
  138.  
  139.           if (!RegisterClass (&wndclass))
  140.                return FALSE ;
  141.           }
  142.  
  143.      hWnd = CreateDialog (hInstance, szAppName, 0, NULL) ;
  144.  
  145.      ShowWindow (hWnd, nCmdShow) ;
  146.  
  147.      while (GetMessage (&msg, NULL, 0, 0))
  148.           {
  149.           TranslateMessage (&msg) ;
  150.           DispatchMessage (&msg) ;
  151.           }
  152.      return msg.wParam ;
  153.      }
  154.  
  155. void ShowNumber (hWnd, dwNumber)
  156.      HWND  hWnd ;
  157.      DWORD dwNumber ;
  158.      {
  159.      char  szBuffer [20] ;
  160.  
  161.      SetDlgItemText (hWnd, VK_ESCAPE,
  162.                          strupr (ltoa (dwNumber, szBuffer, 16))) ;
  163.      }
  164.  
  165. DWORD CalcIt (dwFirstNum, nOperation, dwNum)
  166.      DWORD dwFirstNum, dwNum ;
  167.      short nOperation ;
  168.      {
  169.      switch (nOperation)
  170.           {
  171.           case '=' : return dwNum ;
  172.           case '+' : return dwFirstNum +  dwNum ;
  173.           case '-' : return dwFirstNum -  dwNum ;
  174.           case '*' : return dwFirstNum *  dwNum ;
  175.           case '&' : return dwFirstNum &  dwNum ;
  176.           case '|' : return dwFirstNum |  dwNum ;
  177.           case '^' : return dwFirstNum ^  dwNum ;
  178.           case '<' : return dwFirstNum << dwNum ;
  179.           case '>' : return dwFirstNum >> dwNum ;
  180.           case '/' : return dwNum ? dwFirstNum / dwNum : ULONG_MAX ;
  181.           case '%' : return dwNum ? dwFirstNum % dwNum : ULONG_MAX ;
  182.           default  : return 0L ;
  183.           }
  184.      }
  185.  
  186. long FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
  187.      HWND         hWnd;
  188.      unsigned     iMessage;
  189.      WORD         wParam;
  190.      LONG         lParam;
  191.      {
  192.      static BOOL  bNewNumber = TRUE ;
  193.      static DWORD dwNumber, dwFirstNum ;
  194.      static short nOperation = '=' ;
  195.      HWND         hButton ;
  196.  
  197.      switch (iMessage)
  198.           {
  199.           case WM_KEYDOWN:              /* left arrow --> backspace */
  200.                if (wParam != VK_LEFT)
  201.                     break ;
  202.                wParam = VK_BACK ;
  203.                                              /* fall through */
  204.           case WM_CHAR:
  205.                if ((wParam = toupper (wParam)) == VK_RETURN)
  206.                     wParam = '=' ;
  207.  
  208.                if (hButton = GetDlgItem (hWnd, wParam))
  209.                     {
  210.                     SendMessage (hButton, BM_SETSTATE, 1, 0L) ;
  211.                     SendMessage (hButton, BM_SETSTATE, 0, 0L) ;
  212.                     }
  213.                else
  214.                     {
  215.                     MessageBeep (0) ;
  216.                     break ;
  217.                     }
  218.                                              /* fall through */
  219.           case WM_COMMAND:
  220.                SetFocus (hWnd) ;
  221.  
  222.                if (wParam == VK_BACK)                  /* backspace */
  223.                     ShowNumber (hWnd, dwNumber /= 16) ;
  224.  
  225.                else if (wParam == VK_ESCAPE)           /* escape */
  226.                     ShowNumber (hWnd, dwNumber = 0L) ;
  227.  
  228.                else if (isxdigit (wParam))             /* hex digit */
  229.                     {
  230.                     if (bNewNumber)
  231.                          {
  232.                          dwFirstNum = dwNumber ;
  233.                          dwNumber = 0L ;
  234.                          }
  235.                     bNewNumber = FALSE ;
  236.  
  237.                     if (dwNumber <= ULONG_MAX >> 4)
  238.                          ShowNumber (hWnd, dwNumber =
  239.                               16 * dwNumber + wParam -
  240.                               (isdigit (wParam) ? '0' : 'A' - 10)) ;
  241.                     else
  242.                          MessageBeep (0) ;
  243.                     }
  244.                else                                    /* operation */
  245.                     {
  246.                     if (!bNewNumber)
  247.                          ShowNumber (hWnd, dwNumber =
  248.                               CalcIt (dwFirstNum, nOperation,
  249.                                       dwNumber)) ;
  250.                     bNewNumber = TRUE ;
  251.                     nOperation = wParam ;
  252.                     }
  253.                break ;
  254.  
  255.           case WM_DESTROY:
  256.                PostQuitMessage (0) ;
  257.                break ;
  258.  
  259.           default :
  260.                return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
  261.           }
  262.      return 0L ;
  263.      }
  264.  
  265.  
  266. Figure 2pm
  267. =========
  268.  
  269.  
  270. #------------------------------------------------
  271. # HEXCALCP make file (OS/2 Presentation Manager)
  272. #------------------------------------------------
  273.  
  274. hexcalcp.obj: hexcalcp.c hexcalcp.h
  275.      cl -c -D LINT_ARGS -G2sw -W2 -Zp hexcalcp.c
  276.  
  277. hexcalcp.res : hexcalcp.rc hexcalcp.h
  278.      rc -r hexcalcp.rc
  279.  
  280. hexcalcp.exe: hexcalcp.obj hexcalcp.def hexcalcp.res
  281.      link hexcalcp, /align:16, /map, slibc5 os2, hexcalcp
  282.      rc hexcalcp.res
  283.  
  284.  
  285. Figure 3pm
  286. =========
  287.  
  288.  
  289. /*---------------------------------------------------------
  290.    HEXCALCP.RC resource script (OS/2 Presentation Manager)
  291.   ---------------------------------------------------------*/
  292.  
  293. #include <os2.h>
  294. #include "hexcalcp.h"
  295.  
  296. WINDOWTEMPLATE ID_HEXCALC
  297.     {
  298.     FRAME "Hex Calculator", 1, 110, 40, 102, 122, WS_VISIBLE |
  299.                 FS_TITLEBAR | FS_SYSMENU | FS_MINMAX | FS_BORDER
  300.         {
  301.         WINDOW "", FID_CLIENT, 0, 0, 102, 122, "HexCalcP", WS_VISIBLE
  302.             {
  303.             PUSHBUTTON "D",       68,  8,  88, 14, 14, BS_NOMOUSEFOCUS
  304.             PUSHBUTTON "A",       65,  8,  72, 14, 14, BS_NOMOUSEFOCUS
  305.             PUSHBUTTON "7",       55,  8,  56, 14, 14, BS_NOMOUSEFOCUS
  306.             PUSHBUTTON "4",       52,  8,  40, 14, 14, BS_NOMOUSEFOCUS
  307.             PUSHBUTTON "1",       49,  8,  24, 14, 14, BS_NOMOUSEFOCUS
  308.             PUSHBUTTON "0",       48,  8,   4, 14, 14, BS_NOMOUSEFOCUS
  309.             PUSHBUTTON "0",       27, 26, 104, 50, 14, BS_NOMOUSEFOCUS
  310.             PUSHBUTTON "E",       69, 26,  88, 14, 14, BS_NOMOUSEFOCUS
  311.             PUSHBUTTON "B",       66, 26,  72, 14, 14, BS_NOMOUSEFOCUS
  312.             PUSHBUTTON "8",       56, 26,  56, 14, 14, BS_NOMOUSEFOCUS
  313.             PUSHBUTTON "5",       53, 26,  40, 14, 14, BS_NOMOUSEFOCUS
  314.             PUSHBUTTON "2",       50, 26,  24, 14, 14, BS_NOMOUSEFOCUS
  315.             PUSHBUTTON "Back",     8, 26,   4, 32, 14, BS_NOMOUSEFOCUS
  316.             PUSHBUTTON "F",       70, 44,  88, 14, 14, BS_NOMOUSEFOCUS
  317.             PUSHBUTTON "C",       67, 44,  72, 14, 14, BS_NOMOUSEFOCUS
  318.             PUSHBUTTON "9",       57, 44,  56, 14, 14, BS_NOMOUSEFOCUS
  319.             PUSHBUTTON "6",       54, 44,  40, 14, 14, BS_NOMOUSEFOCUS
  320.             PUSHBUTTON "3",       51, 44,  24, 14, 14, BS_NOMOUSEFOCUS
  321.             PUSHBUTTON "+",       43, 62,  88, 14, 14, BS_NOMOUSEFOCUS
  322.             PUSHBUTTON "-",       45, 62,  72, 14, 14, BS_NOMOUSEFOCUS
  323.             PUSHBUTTON "*",       42, 62,  56, 14, 14, BS_NOMOUSEFOCUS
  324.             PUSHBUTTON "/",       47, 62,  40, 14, 14, BS_NOMOUSEFOCUS
  325.             PUSHBUTTON "%",       37, 62,  24, 14, 14, BS_NOMOUSEFOCUS
  326.             PUSHBUTTON "Equals",  61, 62,   4, 32, 14, BS_NOMOUSEFOCUS
  327.             PUSHBUTTON "&",       38, 80,  88, 14, 14, BS_NOMOUSEFOCUS
  328.             PUSHBUTTON "|",      124, 80,  72, 14, 14, BS_NOMOUSEFOCUS
  329.             PUSHBUTTON "^",       94, 80,  56, 14, 14, BS_NOMOUSEFOCUS
  330.             PUSHBUTTON "<",       60, 80,  40, 14, 14, BS_NOMOUSEFOCUS
  331.             PUSHBUTTON ">",       62, 80,  24, 14, 14, BS_NOMOUSEFOCUS
  332.             }
  333.         }
  334.     }
  335.  
  336.  
  337.  
  338. Figure 4pm
  339. =========
  340.  
  341.  
  342. ;-----------------------------------------------------------------
  343. ; HEXCALCP.DEF module definition file (OS/2 Presentation Manager)
  344. ;-----------------------------------------------------------------
  345.  
  346. NAME           HEXCALCP
  347. DESCRIPTION    'Hexadecimal Calculator (C) Charles Petzold 1987'
  348. STUB           'OS2STUB.EXE'
  349. HEAPSIZE       1024
  350. STACKSIZE      4096
  351. EXPORTS        ClientWndProc
  352.  
  353.  
  354.  
  355. Figure 5pm
  356. =========
  357.  
  358.  
  359. /*----------------------------------------------------
  360.    HEXCALCP.H header file (OS/2 Presentation Manager)
  361.   ----------------------------------------------------*/
  362.  
  363. #define ID_HEXCALC 1
  364.  
  365.  
  366.  
  367. Figure 6pm
  368. =========
  369.  
  370.  
  371. /*------------------------------------------------------------------
  372.    HEXCALCP.C -- Hexadecimal Calculator (OS/2 Presentation Manager)
  373.   ------------------------------------------------------------------*/
  374.  
  375. #include <os2.h>
  376. #include <limits.h>
  377. #include <stdlib.h>
  378. #include <string.h>
  379. #include <ctype.h>
  380. #include "hexcalcp.h"
  381.  
  382. ULONG EXPENTRY ClientWndProc (HWND, USHORT, ULONG, ULONG) ;
  383.  
  384. main ()
  385.      {
  386.      static CHAR szClassName [] = "HexCalcP" ;
  387.      HAB         hAB ;
  388.      HMQ         hMQ ;
  389.      HWND        hWnd ;
  390.      QMSG        qmsg ;
  391.  
  392.      hAB = WinInitialize () ;
  393.      hMQ = WinCreateMsgQueue (hAB, 0) ;
  394.  
  395.      WinRegisterClass (hAB, szClassName, ClientWndProc, 0L, 0, NULL) ;
  396.  
  397.      hWnd = WinLoadDlg (HWND_DESKTOP, HWND_DESKTOP,
  398.                                       NULL, NULL, ID_HEXCALC, NULL) ;
  399.  
  400.      WinSetFocus (HWND_DESKTOP, WinWindowFromID (hWnd, FID_CLIENT)) ;
  401.  
  402.      while (WinGetMsg (hAB, &qmsg, NULL, 0, 0))
  403.           WinDispatchMsg (hAB, &qmsg) ;
  404.  
  405.      WinDestroyWindow (hWnd) ;
  406.      WinDestroyMsgQueue (hMQ) ;
  407.      WinTerminate (hAB) ;
  408.  
  409.      return 0 ;
  410.      }
  411.  
  412. void ShowNumber (hWnd, lNumber)
  413.      HWND  hWnd ;
  414.      ULONG lNumber ;
  415.      {
  416.      CHAR  szBuffer [20] ;
  417.      HWND  hWndResult ;
  418.  
  419.      hWndResult = WinWindowFromID (hWnd, VK_ESCAPE) ;
  420.  
  421.      WinSetWindowText (hWndResult,
  422.                          strupr (ltoa (lNumber, szBuffer, 16))) ;
  423.      }
  424.  
  425. ULONG CalcIt (lFirstNum, iOperation, lNum)
  426.      ULONG lFirstNum, lNum ;
  427.      SHORT iOperation ;
  428.      {
  429.      switch (iOperation)
  430.           {
  431.           case '=' : return lNum ;
  432.           case '+' : return lFirstNum +  lNum ;
  433.           case '-' : return lFirstNum -  lNum ;
  434.           case '*' : return lFirstNum *  lNum ;
  435.           case '&' : return lFirstNum &  lNum ;
  436.           case '|' : return lFirstNum |  lNum ;
  437.           case '^' : return lFirstNum ^  lNum ;
  438.           case '<' : return lFirstNum << lNum ;
  439.           case '>' : return lFirstNum >> lNum ;
  440.           case '/' : return lNum ? lFirstNum / lNum : ULONG_MAX ;
  441.           case '%' : return lNum ? lFirstNum % lNum : ULONG_MAX ;
  442.           default  : return 0L ;
  443.           }
  444.      }
  445.  
  446. ULONG EXPENTRY ClientWndProc (hWnd, nMessage, lParam1, lParam2)
  447.      HWND         hWnd ;
  448.      USHORT       nMessage ;
  449.      ULONG        lParam1 ;
  450.      ULONG        lParam2 ;
  451.      {
  452.      static BOOL  bNewNumber = TRUE ;
  453.      static ULONG lNumber, lFirstNum ;
  454.      static SHORT iOperation = '=' ;
  455.      HWND         hWndButton ;
  456.      SHORT        idButton ;
  457.  
  458.      switch (nMessage)
  459.           {
  460.           case WM_CHAR:
  461.                if (lParam1 & KC_KEYUP)
  462.                     break ;
  463.  
  464.                if (HIUSHORT (lParam2) == VK_LEFT)   /* left arrow to */
  465.                     LOUSHORT (lParam2) = VK_BACK ;  /*   backspace   */
  466.  
  467.                if (HIUSHORT (lParam2) == VK_RETURN) /* return to     */
  468.                     LOUSHORT (lParam2) = '=' ;      /*   equals      */
  469.  
  470.                if (LOUSHORT (lParam2) == 0)
  471.                     break ;
  472.  
  473.                LOUSHORT (lParam2) = toupper (LOUSHORT (lParam2)) ;
  474.  
  475.                if (hWndButton =
  476.                          WinWindowFromID (hWnd, LOUSHORT (lParam2)))
  477.                     WinSendMsg (hWndButton, BM_CLICK, 0L, 0L) ;
  478.                else
  479.                     WinAlarm (HWND_DESKTOP, WA_ERROR) ;
  480.  
  481.                return 1L ;
  482.  
  483.           case WM_COMMAND:
  484.                idButton = LOUSHORT (lParam1) ;
  485.  
  486.                if (idButton == VK_BACK)                /* backspace */
  487.                     ShowNumber (hWnd, lNumber /= 16) ;
  488.  
  489.                else if (idButton == VK_ESCAPE)         /* escape    */
  490.                     ShowNumber (hWnd, lNumber = 0L) ;
  491.  
  492.                else if (isxdigit (idButton))           /* hex digit */
  493.                     {
  494.                     if (bNewNumber)
  495.                          {
  496.                          lFirstNum = lNumber ;
  497.                          lNumber = 0L ;
  498.                          }
  499.                     bNewNumber = FALSE ;
  500.  
  501.                     if (lNumber <= ULONG_MAX >> 4)
  502.                          ShowNumber (hWnd, lNumber = 
  503.                               16 * lNumber + idButton -
  504.                               (isdigit (idButton) ? '0' : 'A' - 10)) ;
  505.                     else
  506.                          WinAlarm (HWND_DESKTOP, WA_ERROR) ;
  507.                     }
  508.                else                                    /* operation */
  509.                     {
  510.                     if (!bNewNumber)
  511.                          ShowNumber (hWnd, lNumber =
  512.                               CalcIt (lFirstNum, iOperation, lNumber)) ;
  513.                     bNewNumber = TRUE ;
  514.                     iOperation = idButton ;
  515.                     }
  516.                break ;
  517.  
  518.           default :
  519.                return WinDefWindowProc (hWnd, nMessage, lParam1,
  520.                                                         lParam2) ;
  521.           }
  522.      return 0L ;
  523.      }
  524.  
  525.