home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 10 / 10.iso / l / l360 / 3.ddi / WINDOWS.@EM / WINCALC.CBL < prev    next >
Encoding:
Text File  |  1991-04-08  |  75.8 KB  |  1,715 lines

  1.       $set ans85 mf noosvs nobound
  2.       ****************************************************************
  3.       *
  4.       *                (C) Micro Focus Ltd. 1989,1991
  5.       *
  6.       *                       WINCALC.CBL
  7.       *
  8.       * Example program: Windows 'RPN Calculator'
  9.       *
  10.       * A number of extensions to the COBOL language are used in
  11.       * this program - see the comments in WINHELLO.CBL for details
  12.       *
  13.       * Application files:
  14.       *     WINCALC.CBL      -   COBOL source file
  15.       *     WINCALC.RES      -   Resources, created from :
  16.       *       WINCALC.CUR   -   Hand icon for Area Sensitive Pointer
  17.       *       WINCALC.ICO   -   Minimize Icon
  18.       *       WINCALC.RC    -   Menu and Accelerate Table definition
  19.       *       WINCALC.DLG   -   Dialog definition
  20.       *
  21.       * Tools used:
  22.       *     COBOL           -   COBOL compiler      .CBL
  23.       *     LINK            -
  24.       *     RC              -   Resource compiler   .RC .DLG
  25.       *     SDKPAINT        -   Icon editor creates .ICO and .CUR
  26.       *
  27.       * To compile:
  28.       *
  29.       *    cobol wincalc target(286);
  30.       *    link wincalc,,,,wincalc.def;
  31.       *    rc wincalc
  32.       *
  33.       * where wincalc.def contains the lines:
  34.       *
  35.       *    NAME            WinCalc
  36.       *    DESCRIPTION     'Windows RPN Calculator.'
  37.       *    EXETYPE         WINDOWS 3.0
  38.       *    STUB            'WINSTUB.EXE'
  39.       *    CODE            PRELOAD FIXED
  40.       *    DATA            PRELOAD FIXED MULTIPLE
  41.       *    STACKSIZE       16384
  42.       *    HEAPSIZE        1024
  43.       *    EXPORTS         MWndProc
  44.       *                    BWndProc
  45.       *                    DlgProc
  46.       *
  47.       * This example program uses Windows to implement:
  48.       *     A Standard Window with a Client Window Procedure
  49.       *     Action Bar and pull downs (CUA conforming)
  50.       *     Accelerator Keys
  51.       *     Sending and Receiving messages
  52.       *     Child Windows
  53.       *     Subclassing
  54.       *     WindowWords
  55.       *     An Area Sensitive Pointer (The pointer changes shape
  56.       *                                when located over a
  57.       *                                'pressable' button)
  58.       *     Dialog Boxes
  59.       *     Message Boxes
  60.       *     Automatic window repositioning/resizing
  61.       *
  62.       * The Windows calls used are:
  63.       *
  64.       *     LoadIcon            :   loads an icon
  65.       *     LoadCursor          :   loads a pointer
  66.       *     GetStockObject      :   gets a system value
  67.       *     GetModuleFileName   :   Get name of this module
  68.       *     RegisterClass       :   Register window class
  69.       *     LoadMenu            :   loads a menu resource
  70.       *     LoadAccelerators    :   loads an accelerator table
  71.       *     CreateWindow        :   Create child window
  72.       *     ShowWindow          :   makes a window visible
  73.       *     UpdateWindow        :   sends paint message to the winproc
  74.       *     DestroyWindow       :   Destroy window
  75.       *     GetMessage          :   Get message from message queue
  76.       *     TranslateAccelerator:   Tests for an accelerator key
  77.       *     TranslateMessage    :   Translate message information
  78.       *     DispatchMessage     :   Despatch message to WinProc
  79.       *     SendMessage         :   Synchronous message
  80.       *     PostMessage         :   Asynchronous message
  81.       *     BeginPaint          :
  82.       *     GetClientRect       :   Get client area dimensions
  83.       *     FillRect            :   Fill a rectangle with a color
  84.       *     EndPaint            :
  85.       *     MessageBox          :   Initiate Message Box
  86.       *     DialogBox           :   Initiate Dialog Box
  87.       *     EndDialog           :   Terminate dialog box
  88.       *     DefWindowProc       :   Default window proc
  89.       *     CallWindowProc      :   Call a window procedure
  90.       *     SetWindowLong       :   Set window words
  91.       *     GetWindowWord       :   Retrieve window word
  92.       *     GetWindowLong       :   Retrieve window words
  93.       *     SetWindowText       :   Assign text to child window
  94.       *     SetCursor           :   Set the mouse pointer shape
  95.       *     SendDlgItemMessage  :   Send message to dialog box item
  96.       *     SetDlgItemInt       :   Send number to dialog box item
  97.       *     GetDlgItemInt       :   Get number from dialog box item
  98.       *     GetDlgItem          :   Get the handle of a dilaog box item
  99.       *     SetFocus            :   Set input focus to an item
  100.       *     MoveWindow          :   Size and Position window
  101.       *     MessageBeep         :   Sound the bell
  102.       *
  103.       ****************************************************************
  104.  
  105.       ****************************************************************
  106.       *
  107.       *     Enable the PASCAL calling convention (number 3)
  108.       *     and call it WINAPI because it is used for WINAPI
  109.       *     functions.  (We will use it for COBOL to COBOL calls
  110.       *     as well.
  111.       *
  112.       ****************************************************************
  113.         special-names.
  114.             call-convention 3 is WINAPI.
  115.  
  116.         working-storage section.
  117.  
  118.        78 debug-ctrl                   value 0.
  119.  
  120.       ****************************************************************
  121.       *
  122.       * The following been taken from the Windows SDK Header files.
  123.       *
  124.       ****************************************************************
  125.         78  WM-CREATE           value   h"01".
  126.         78  WM-SIZE             value   h"05".
  127.         78  WM-COMMAND          value   h"0111".
  128.         78  WM-PAINT            value   h"0f".
  129.         78  WM-QUIT             value   h"12".
  130.         78  WM-INITDLG          value   h"0110".
  131.         78  WM-ERASEBACKGROUND  value   h"0014".
  132.         78  WM-MOUSEMOVE        value   h"0200".
  133.         78  EM-LIMITTEXT        value   h"0415".
  134.  
  135.         78  WC-BUTTON               value "button" & x"00".
  136.         78  WC-STATIC               value "static" & x"00".
  137.         78  GCW-HCURSOR             value -12.
  138.         78  GWW-ID                  value -12.
  139.         78  GWL-WNDPROC             value -4.
  140.         78  DID-OK                  value 1.
  141.         78  DID-CANCEL              value 2.
  142.  
  143.         01  work-data.
  144.             03  hab                 pointer.
  145.             03  hmq                 pointer.
  146.             03  hwndClient          pic 9(4) comp-5.
  147.             03  hwndFrame           pic 9(4) comp-5.
  148.             03  hwndTemp            pic 9(4) comp-5.
  149.             03  hwndMenu            pic 9(4) comp-5.
  150.             03  hwndAccel           pic 9(4) comp-5.
  151.             03  qmsg.
  152.                 05  qmsghwnd        pic 9(4) comp-5.
  153.                 05  qmsgmsg         pic 9(4) comp-5.
  154.                 05  qmsgmp1         pic 9(4) comp-5.
  155.                 05  qmsgmp2         pic s9(9) comp-5.
  156.                 05  qmsgtime        pic 9(9) comp-5.
  157.                 05  qmsgptl.
  158.                     07  qmsgptlx    pic 9(4) comp-5.
  159.                     07  qmsgptly    pic 9(4) comp-5.
  160.  
  161.             03  ptrH                pic 9(4) comp-5.
  162.             03  pidInfo.
  163.                 05  pid             pic xx comp-5.
  164.                 05  tid             pic xx comp-5.
  165.                 05  ppid            pic xx comp-5.
  166.  
  167.             03  loop-flag           pic x value 'C'.
  168.                 88  loop-end            value 'E'.
  169.             03  bool                pic 9(4) comp-5.
  170.                 88  boolTRUE            value 1.
  171.                 88  boolFALSE           value 0.
  172.  
  173.  
  174.       ****************************************************************
  175.       *
  176.       * hwndTable contains details of each of the windows used in
  177.       *         this application.
  178.       *         The fields are:
  179.       *
  180.       *     SquareX:    number of buttons horizontally
  181.       *     SquareY:    number of buttons vertically
  182.       *
  183.       *     id*     The offset into the array of this item,
  184.       *             this is used to calculate the ID and WM for
  185.       *             each button.
  186.       *     hwnd*   Storage for the window handle.  This is only
  187.       *             used for windows with variable contents
  188.       *             (Display and Base in this example.)
  189.       *     text*   The text to put on the button
  190.       *     winXL   The left horizontal position  (in button co-ords)
  191.       *     winYB   The bottom vertical position  (in button co-ords)
  192.       *     winXR   The right horizontal position (in button co-ords)
  193.       *     winYT   The top vertical position     (in button co-ords)
  194.       *
  195.       *               [base][   number display  ]
  196.       *               [Hex] [+/-] [D] [E] [F] [/]
  197.       *               [Dec] [Clx] [A] [B] [C] [*]
  198.       *               [Oct] [x-y] [7] [8] [9] [-]
  199.       *               [Bin]  [^]  [4] [5] [6] [+]
  200.       *               [1/x]  [V]  [1] [2] [3] [Ent]
  201.       *               [y^x] [Clr] [  0  ] [.] [er]
  202.       *
  203.       ****************************************************************
  204.             03  hwndTable-x.
  205.         78  hwndTS          value next.
  206.  
  207.         78  RelativeButton  value 3.
  208.         78  RelativeGap     value 1.
  209.         78  ButtonGap       value RelativeButton + RelativeGap.
  210.         78  SquareX         value 6.
  211.         78  SquareY         value 7.
  212.  
  213.         78  idDisplay       value 1.
  214.                 05  hwndDisplay     pic 9(4) comp-5.
  215.                 05  textDisplay     pic x(5).
  216.                 05  filler          pic xx   comp-5 value 1.
  217.                 05  filler          pic xx   comp-5 value 6.
  218.                 05  filler          pic xx   comp-5 value 5.
  219.                 05  filler          pic xx   comp-5 value 6.
  220.         78  id0             value 2.
  221.                 05  hwnd0           pic 9(4) comp-5.
  222.                 05  text0           pic x(5) value '0'.
  223.                 05  filler          pic xx   comp-5 value 2.
  224.                 05  filler          pic xx   comp-5 value 0.
  225.                 05  filler          pic xx   comp-5 value 3.
  226.                 05  filler          pic xx   comp-5 value 0.
  227.         78  id1             value 3.
  228.                 05  hwnd1           pic 9(4) comp-5.
  229.                 05  text1           pic x(5) value '1'.
  230.                 05  filler          pic xx   comp-5 value 2.
  231.                 05  filler          pic xx   comp-5 value 1.
  232.                 05  filler          pic xx   comp-5 value 2.
  233.                 05  filler          pic xx   comp-5 value 1.
  234.         78  id2             value 4.
  235.                 05  hwnd2           pic 9(4) comp-5.
  236.                 05  text2           pic x(5) value '2'.
  237.                 05  filler          pic xx   comp-5 value 3.
  238.                 05  filler          pic xx   comp-5 value 1.
  239.                 05  filler          pic xx   comp-5 value 3.
  240.                 05  filler          pic xx   comp-5 value 1.
  241.         78  id3             value 5.
  242.                 05  hwnd3           pic 9(4) comp-5.
  243.                 05  text3           pic x(5) value '3'.
  244.                 05  filler          pic xx   comp-5 value 4.
  245.                 05  filler          pic xx   comp-5 value 1.
  246.                 05  filler          pic xx   comp-5 value 4.
  247.                 05  filler          pic xx   comp-5 value 1.
  248.         78  id4             value 6.
  249.                 05  hwnd4           pic 9(4) comp-5.
  250.                 05  text4           pic x(5) value '4'.
  251.                 05  filler          pic xx   comp-5 value 2.
  252.                 05  filler          pic xx   comp-5 value 2.
  253.                 05  filler          pic xx   comp-5 value 2.
  254.                 05  filler          pic xx   comp-5 value 2.
  255.         78  id5             value 7.
  256.                 05  hwnd5           pic 9(4) comp-5.
  257.                 05  text5           pic x(5) value '5'.
  258.                 05  filler          pic xx   comp-5 value 3.
  259.                 05  filler          pic xx   comp-5 value 2.
  260.                 05  filler          pic xx   comp-5 value 3.
  261.                 05  filler          pic xx   comp-5 value 2.
  262.         78  id6             value 8.
  263.                 05  hwnd6           pic 9(4) comp-5.
  264.                 05  text6           pic x(5) value '6'.
  265.                 05  filler          pic xx   comp-5 value 4.
  266.                 05  filler          pic xx   comp-5 value 2.
  267.                 05  filler          pic xx   comp-5 value 4.
  268.                 05  filler          pic xx   comp-5 value 2.
  269.         78  id7             value 9.
  270.                 05  hwnd7           pic 9(4) comp-5.
  271.                 05  text7           pic x(5) value '7'.
  272.                 05  filler          pic xx   comp-5 value 2.
  273.                 05  filler          pic xx   comp-5 value 3.
  274.                 05  filler          pic xx   comp-5 value 2.
  275.                 05  filler          pic xx   comp-5 value 3.
  276.         78  id8             value 10.
  277.                 05  hwnd8           pic 9(4) comp-5.
  278.                 05  text8           pic x(5) value '8'.
  279.                 05  filler          pic xx   comp-5 value 3.
  280.                 05  filler          pic xx   comp-5 value 3.
  281.                 05  filler          pic xx   comp-5 value 3.
  282.                 05  filler          pic xx   comp-5 value 3.
  283.         78  id9             value 11.
  284.                 05  hwnd9           pic 9(4) comp-5.
  285.                 05  text9           pic x(5) value '9'.
  286.                 05  filler          pic xx   comp-5 value 4.
  287.                 05  filler          pic xx   comp-5 value 3.
  288.                 05  filler          pic xx   comp-5 value 4.
  289.                 05  filler          pic xx   comp-5 value 3.
  290.         78  idA             value 12.
  291.                 05  hwndA           pic 9(4) comp-5.
  292.                 05  textA           pic x(5) value 'A'.
  293.                 05  filler          pic xx   comp-5 value 2.
  294.                 05  filler          pic xx   comp-5 value 4.
  295.                 05  filler          pic xx   comp-5 value 2.
  296.                 05  filler          pic xx   comp-5 value 4.
  297.         78  idB             value 13.
  298.                 05  hwndB           pic 9(4) comp-5.
  299.                 05  textB           pic x(5) value 'B'.
  300.                 05  filler          pic xx   comp-5 value 3.
  301.                 05  filler          pic xx   comp-5 value 4.
  302.                 05  filler          pic xx   comp-5 value 3.
  303.                 05  filler          pic xx   comp-5 value 4.
  304.         78  idC             value 14.
  305.                 05  hwndC           pic 9(4) comp-5.
  306.                 05  textC           pic x(5) value 'C'.
  307.                 05  filler          pic xx   comp-5 value 4.
  308.                 05  filler          pic xx   comp-5 value 4.
  309.                 05  filler          pic xx   comp-5 value 4.
  310.                 05  filler          pic xx   comp-5 value 4.
  311.         78  idD             value 15.
  312.                 05  hwndD           pic 9(4) comp-5.
  313.                 05  textD           pic x(5) value 'D'.
  314.                 05  filler          pic xx   comp-5 value 2.
  315.                 05  filler          pic xx   comp-5 value 5.
  316.                 05  filler          pic xx   comp-5 value 2.
  317.                 05  filler          pic xx   comp-5 value 5.
  318.         78  idE             value 16.
  319.                 05  hwndE           pic 9(4) comp-5.
  320.                 05  textE           pic x(5) value 'E'.
  321.                 05  filler          pic xx   comp-5 value 3.
  322.                 05  filler          pic xx   comp-5 value 5.
  323.                 05  filler          pic xx   comp-5 value 3.
  324.                 05  filler          pic xx   comp-5 value 5.
  325.         78  idF             value 17.
  326.                 05  hwndF           pic 9(4) comp-5.
  327.                 05  textF           pic x(5) value 'F'.
  328.                 05  filler          pic xx   comp-5 value 4.
  329.                 05  filler          pic xx   comp-5 value 5.
  330.                 05  filler          pic xx   comp-5 value 4.
  331.                 05  filler          pic xx   comp-5 value 5.
  332.         78  idDP            value 18.
  333.                 05  hwndDP          pic 9(4) comp-5.
  334.                 05  textDP          pic x(5) value '.'.
  335.                 05  filler          pic xx   comp-5 value 4.
  336.                 05  filler          pic xx   comp-5 value 0.
  337.                 05  filler          pic xx   comp-5 value 4.
  338.                 05  filler          pic xx   comp-5 value 0.
  339.         78  idChs           value 19.
  340.                 05  hwndChs         pic 9(4) comp-5.
  341.                 05  textChs         pic x(5) value '+/-'.
  342.                 05  filler          pic xx   comp-5 value 1.
  343.                 05  filler          pic xx   comp-5 value 5.
  344.                 05  filler          pic xx   comp-5 value 1.
  345.                 05  filler          pic xx   comp-5 value 5.
  346.         78  idPlus          value 20.
  347.                 05  hwndPlus        pic 9(4) comp-5.
  348.                 05  textPlus        pic x(5) value '+'.
  349.                 05  filler          pic xx   comp-5 value 5.
  350.                 05  filler          pic xx   comp-5 value 2.
  351.                 05  filler          pic xx   comp-5 value 5.
  352.                 05  filler          pic xx   comp-5 value 2.
  353.         78  idMinus         value 21.
  354.                 05  hwndMinus       pic 9(4) comp-5.
  355.                 05  textMinus       pic x(5) value '-'.
  356.                 05  filler          pic xx   comp-5 value 5.
  357.                 05  filler          pic xx   comp-5 value 3.
  358.                 05  filler          pic xx   comp-5 value 5.
  359.                 05  filler          pic xx   comp-5 value 3.
  360.         78  idMultiply      value 22.
  361.                 05  hwndMultiply    pic 9(4) comp-5.
  362.                 05  textMultiply    pic x(5) value 'x'.
  363.                 05  filler          pic xx   comp-5 value 5.
  364.                 05  filler          pic xx   comp-5 value 4.
  365.                 05  filler          pic xx   comp-5 value 5.
  366.                 05  filler          pic xx   comp-5 value 4.
  367.         78  idDivide        value 23.
  368.                 05  hwndDivide      pic 9(4) comp-5.
  369.                 05  textDivide      pic x(5) value '/'.
  370.                 05  filler          pic xx   comp-5 value 5.
  371.                 05  filler          pic xx   comp-5 value 5.
  372.                 05  filler          pic xx   comp-5 value 5.
  373.                 05  filler          pic xx   comp-5 value 5.
  374.         78  idEnter         value 24.
  375.                 05  hwndEnter       pic 9(4) comp-5.
  376.                 05  textEnter       pic x(5) value 'Enter'.
  377.                 05  filler          pic xx   comp-5 value 5.
  378.                 05  filler          pic xx   comp-5 value 0.
  379.                 05  filler          pic xx   comp-5 value 5.
  380.                 05  filler          pic xx   comp-5 value 1.
  381.         78  idRollDown      value 25.
  382.                 05  hwndRollDown    pic 9(4) comp-5.
  383.                 05  textRollDown    pic x(5) value x'5264'.
  384.                 05  filler          pic xx   comp-5 value 1.
  385.                 05  filler          pic xx   comp-5 value 0.
  386.                 05  filler          pic xx   comp-5 value 1.
  387.                 05  filler          pic xx   comp-5 value 0.
  388.         78  idRollUp        value 26.
  389.                 05  hwndRollUp      pic 9(4) comp-5.
  390.                 05  textRollUp      pic x(5) value x'5275'.
  391.                 05  filler          pic xx   comp-5 value 1.
  392.                 05  filler          pic xx   comp-5 value 1.
  393.                 05  filler          pic xx   comp-5 value 1.
  394.                 05  filler          pic xx   comp-5 value 1.
  395.         78  idClear         value 27.
  396.                 05  hwndClear       pic 9(4) comp-5.
  397.                 05  textClear       pic x(5) value 'Clear'.
  398.                 05  filler          pic xx   comp-5 value 1.
  399.                 05  filler          pic xx   comp-5 value 4.
  400.                 05  filler          pic xx   comp-5 value 1.
  401.                 05  filler          pic xx   comp-5 value 4.
  402.         78  idClx           value 28.
  403.                 05  hwndClx         pic 9(4) comp-5.
  404.                 05  textClx         pic x(5) value 'Clr-X'.
  405.                 05  filler          pic xx   comp-5 value 1.
  406.                 05  filler          pic xx   comp-5 value 3.
  407.                 05  filler          pic xx   comp-5 value 1.
  408.                 05  filler          pic xx   comp-5 value 3.
  409.         78  idHex           value 29.
  410.                 05  hwndHex         pic 9(4) comp-5.
  411.                 05  textHex         pic x(5) value x'486578'.
  412.                 05  filler          pic xx   comp-5 value 0.
  413.                 05  filler          pic xx   comp-5 value 5.
  414.                 05  filler          pic xx   comp-5 value 0.
  415.                 05  filler          pic xx   comp-5 value 5.
  416.         78  idDec           value 30.
  417.                 05  hwndDec         pic 9(4) comp-5.
  418.                 05  textDec         pic x(5) value x'446563'.
  419.                 05  filler          pic xx   comp-5 value 0.
  420.                 05  filler          pic xx   comp-5 value 4.
  421.                 05  filler          pic xx   comp-5 value 0.
  422.                 05  filler          pic xx   comp-5 value 4.
  423.         78  idOct           value 31.
  424.                 05  hwndOct         pic 9(4) comp-5.
  425.                 05  textOct         pic x(5) value x'4f6374'.
  426.                 05  filler          pic xx   comp-5 value 0.
  427.                 05  filler          pic xx   comp-5 value 3.
  428.                 05  filler          pic xx   comp-5 value 0.
  429.                 05  filler          pic xx   comp-5 value 3.
  430.         78  idBin           value 32.
  431.                 05  hwndBin         pic 9(4) comp-5.
  432.                 05  textBin         pic x(5) value x'42696e'.
  433.                 05  filler          pic xx   comp-5 value 0.
  434.                 05  filler          pic xx   comp-5 value 2.
  435.                 05  filler          pic xx   comp-5 value 0.
  436.                 05  filler          pic xx   comp-5 value 2.
  437.         78  idPower         value 33.
  438.                 05  hwndPower       pic 9(4) comp-5.
  439.                 05  textPower       pic x(5) value 'y^x'.
  440.                 05  filler          pic xx   comp-5 value 0.
  441.                 05  filler          pic xx   comp-5 value 0.
  442.                 05  filler          pic xx   comp-5 value 0.
  443.                 05  filler          pic xx   comp-5 value 0.
  444.         78  idRecip         value 34.
  445.                 05  hwndRecip       pic 9(4) comp-5.
  446.                 05  textRecip       pic x(5) value '1/x'.
  447.                 05  filler          pic xx   comp-5 value 0.
  448.                 05  filler          pic xx   comp-5 value 1.
  449.                 05  filler          pic xx   comp-5 value 0.
  450.                 05  filler          pic xx   comp-5 value 1.
  451.         78  idXchg          value 35.
  452.                 05  hwndXchg        pic 9(4) comp-5.
  453.                 05  textXchg        pic x(5) value x'783c3e79'.
  454.                 05  filler          pic xx   comp-5 value 1.
  455.                 05  filler          pic xx   comp-5 value 2.
  456.                 05  filler          pic xx   comp-5 value 1.
  457.                 05  filler          pic xx   comp-5 value 2.
  458.         78  idBase          value 36.
  459.                 05  hwndBase        pic 9(4) comp-5.
  460.                 05  textBase        pic x(5).
  461.                 05  filler          pic xx   comp-5 value 0.
  462.                 05  filler          pic xx   comp-5 value 6.
  463.                 05  filler          pic xx   comp-5 value 0.
  464.                 05  filler          pic xx   comp-5 value 6.
  465.  
  466.         78  hwndTableEnd    value next.
  467.         78  hwndTableSize   value hwndTableEnd
  468.                                         - hwndTS.
  469.         78  hwndTableCount  value hwndTableSize / 15.
  470.         78  hwndButtonLast  value hwndTableCount - 1.
  471.  
  472.             03  hwndTable redefines hwndTable-x.
  473.               04  winItem         occurs hwndTableCount.
  474.                 05  hwndItem        pic 9(4) comp-5.
  475.                 05  hwndText        pic x(5).
  476.                 05  winXL           pic xx comp-5.
  477.                 05  winYB           pic xx comp-5.
  478.                 05  winXR           pic xx comp-5.
  479.                 05  winYT           pic xx comp-5.
  480.  
  481.             03 DefProcTable.
  482.                 05  DefWndProc      procedure-pointer
  483.                                     occurs hwndTableCount.
  484.  
  485.         78  WM-USER                 value   h"4000".
  486.         78  WM-UPDATEDISPLAY        value   h"4001".
  487.         78  WM-NUMBER               value   h"4002".
  488.         78  WM-ABOUT                value   h"400d".
  489.         78  WM-CUSTOM               value   h"400e".
  490.         78  WM-EXIT                 value   h"400f".
  491.         78  WM-BUTTONS              value   h"4010".
  492.         78  WM-0                    value   WM-BUTTONS + id0.
  493.         78  WM-1                    value   WM-BUTTONS + id1.
  494.         78  WM-2                    value   WM-BUTTONS + id2.
  495.         78  WM-3                    value   WM-BUTTONS + id3.
  496.         78  WM-4                    value   WM-BUTTONS + id4.
  497.         78  WM-5                    value   WM-BUTTONS + id5.
  498.         78  WM-6                    value   WM-BUTTONS + id6.
  499.         78  WM-7                    value   WM-BUTTONS + id7.
  500.         78  WM-8                    value   WM-BUTTONS + id8.
  501.         78  WM-9                    value   WM-BUTTONS + id9.
  502.         78  WM-A                    value   WM-BUTTONS + idA.
  503.         78  WM-B                    value   WM-BUTTONS + idB.
  504.         78  WM-C                    value   WM-BUTTONS + idC.
  505.         78  WM-D                    value   WM-BUTTONS + idD.
  506.         78  WM-E                    value   WM-BUTTONS + idE.
  507.         78  WM-F                    value   WM-BUTTONS + idF.
  508.         78  WM-DP                   value   WM-BUTTONS + idDP.
  509.         78  WM-CHS                  value   WM-BUTTONS + idCHS.
  510.         78  WM-PLUS                 value   WM-BUTTONS + idPlus.
  511.         78  WM-MINUS                value   WM-BUTTONS + idMinus.
  512.         78  WM-MULTIPLY             value   WM-BUTTONS + idMultiply.
  513.         78  WM-DIVIDE               value   WM-BUTTONS + idDivide.
  514.         78  WM-ENTER                value   WM-BUTTONS + idEnter.
  515.         78  WM-ROLLDOWN             value   WM-BUTTONS + idRollDown.
  516.         78  WM-ROLLUP               value   WM-BUTTONS + idRollUp.
  517.         78  WM-CLEAR                value   WM-BUTTONS + idClear.
  518.         78  WM-CLX                  value   WM-BUTTONS + idClx.
  519.         78  WM-HEX                  value   WM-BUTTONS + idHex.
  520.         78  WM-DEC                  value   WM-BUTTONS + idDec.
  521.         78  WM-OCT                  value   WM-BUTTONS + idOct.
  522.         78  WM-BIN                  value   WM-BUTTONS + idBin.
  523.         78  WM-POWER                value   WM-BUTTONS + idPower.
  524.         78  WM-RECIP                value   WM-BUTTONS + idRecip.
  525.         78  WM-XCHG                 value   WM-BUTTONS + idXchg.
  526.  
  527.         78  DI-BASEENTRY            value   "BaseEntry" & x"00".
  528.         78  DI-BASE                 value   4.
  529.  
  530.  
  531.       ****************************************************************
  532.       *
  533.       * Class styles are defined in the header files, so we have
  534.       * to enquire of the C header files to get the appropriate
  535.       * numbers.  CSClass     =     h"0003"   is CS_VREDRAW
  536.       *                                     with CS_HREDRAW
  537.       *           DisplayStyle= h"50000002"   is SS_RIGHT
  538.       *                                     with WS_VISIBLE
  539.       *                                     with WS_CHILD
  540.       *           BaseStyle   = h"50000001"   is SS_CENTER
  541.       *                                     with WS_VISIBLE
  542.       *                                     with WS_CHILD
  543.       *           ButtonStyle = h"50000000"   is WS_VISIBLE
  544.       *                                     with WS_CHILD
  545.       *           ctldata     = h"10cf0000"   is WS_OVERLAPPED
  546.       *                                     with WS_CAPTION
  547.       *                                      and WS_SYSMENU
  548.       *                                      and WS_SIZEBOX
  549.       *                                      and WS_MINIMIZEBOX
  550.       *                                      and WS_MAXIMIZEBOX
  551.       *
  552.       ****************************************************************
  553.             03  CSClass             pic 9(4) comp-5 value h"0003".
  554.             03  DisplayStyle        pic 9(9) comp-5 value h"50000002".
  555.             03  BaseStyle           pic 9(9) comp-5 value h"50000001".
  556.             03  ButtonStyle         pic 9(9) comp-5 value h"50000000".
  557.             03  ctldata             pic 9(9) comp-5 value h"00cf0000".
  558.  
  559.       ****************************************************************
  560.       *
  561.       * ASCIIZ strings to pass to Windows.
  562.       *
  563.       ****************************************************************
  564.             03  MyClass             pic x(8) value 'RPNCalc' & x"00".
  565.             03  AboutText           pic x(137) value
  566.                     'This application is written in COBOL.'
  567.                 &   ' For more information on writing for Windows in CO'
  568.                 &   'BOL, see the WINHELLO.CBL example program source.'
  569.                 &   x"00".
  570.             03  AboutTitle          pic x(15) value
  571.                    'RPN Calculator' & x"00".
  572.  
  573.       ****************************************************************
  574.       *
  575.       * Internal registers - we use COMP-3 for efficiency with
  576.       *     very awkward numbers (18 9s in this case)
  577.       *
  578.       *     CalcRegisters is the set of registers
  579.       *     CalcRegister  is a table of the individual registers
  580.       *     Reg           is the value area
  581.       *     RegDP         is the Fraction pointer for entering
  582.       *                             non-integers
  583.       *     modeFlag      indicates what last happened:
  584.       *                             ENTER key
  585.       *                             Number key (or DP)
  586.       *                             Function key
  587.       *
  588.       *     RegInt      )
  589.       *     RegFrac     ) are work areas
  590.       *     RegWork     )
  591.       *     Digit9/X      are used for creating ASCII digits
  592.       *
  593.       *     gBase         is the current (global) base
  594.       *     gBaseD        is the maximum sensible digits in fraction
  595.       *     gBase9        is used for displaying the base
  596.       *
  597.       *     RegSE         is the Size Error indicator
  598.       *
  599.       *     CalcRegisterDisplay is used for displaying a register.
  600.       *
  601.       ****************************************************************
  602.             03  CalcRegisters.
  603.               04  CalcRegister occurs 7.
  604.                 05  Reg                 pic s9(9)v9(9) comp-3.
  605.         78  RegX                value 1.
  606.         78  RegY                value 2.
  607.         78  RegZ                value 3.
  608.         78  RegT                value 4.
  609.         78  RegLX               value 5.
  610.             03  RegDP                   pic xx comp-5.
  611.             03  modeFlag                pic x.
  612.                 88  modeEnter           value 'E'.
  613.                 88  modeFunction        value 'F'.
  614.                 88  modeNumber          value 'N'.
  615.             03  RegInt                  pic 9(9) comp-3.
  616.             03  RegFrac                 pic v9(9) comp-3.
  617.             03  RegWork                 pic s9(9)v9(9) comp-3.
  618.             03  Digit9                  pic x  comp-5.
  619.             03  DigitX redefines Digit9 pic x.
  620.             03  gBase                   pic xx comp-5.
  621.             03  gBaseSav                pic xx comp-5.
  622.             03  gBaseD                  pic xx comp-5.
  623.         78  HexgBaseD           value 8.
  624.         78  DecgBaseD           value 9.
  625.         78  OctgBaseD           value 10.
  626.         78  BingBaseD           value 30.
  627.             03  gBase9bra               pic x value '('.
  628.             03  gBase9                  pic z9.
  629.             03  gBase9ket               pic x value ')'.
  630.             03  gBase9Null              pic x value x'00'.
  631.             03  RegSE                   pic x.
  632.                 88  SizeError           value 'E'.
  633.                 88  NoSizeError         value ' '.
  634.  
  635.             03  CalcRegisterDisplay.
  636.                 05  CalcRegX        pic x(50).
  637.                 05                  pic xxxx    value x'20202000'.
  638.                 05  CalcRegBase     pic x(70).
  639.                 05  CalcReg9 redefines CalcRegBase
  640.                                     pic -(9)9.9(9).
  641.  
  642.             03  ModSize                 pic xx comp-5.
  643.             03  ModName.
  644.                 05 ModName-Char         pic x occurs 255.
  645.  
  646.             03  WndClass.
  647.                 05  cstyle              pic 9(4) comp-5.
  648.                 05  lpfnWndProc         procedure-pointer.
  649.                 05  cbClsExtra          pic s9(4) comp-5.
  650.                 05  cbWndExtra          pic s9(4) comp-5.
  651.                 05  hInstance           pic 9(4) comp-5.
  652.                 05  hIcon               pic 9(4) comp-5.
  653.                 05  hCursor             pic 9(4) comp-5.
  654.                 05  hbrBackground       pic 9(4) comp-5.
  655.                 05  lpszMenuName        pointer.
  656.                 05  lpszClassName       pointer.
  657.  
  658.         local-storage section.
  659.         01  hps                 pointer.
  660.         01  ppaint.
  661.             03  hdc                     pic x(4) comp-5.
  662.             03 fErase                   pic s9(4) comp-5.
  663.             03  rcl.
  664.                 05  xLeft               pic s9(4) comp-5.
  665.                 05  yTop                pic s9(4) comp-5.
  666.                 05  xRight              pic s9(4) comp-5.
  667.                 05  yBottom             pic s9(4) comp-5.
  668.             03 fRestore                 pic s9(4) comp-5.
  669.             03 fUpdate                  pic s9(4) comp-5.
  670.             03 rgbdata                  pic x occurs 16.
  671.         01  rcs.
  672.             03  sxLeft          pic x(2) comp-5.
  673.             03  syBottom        pic x(2) comp-5.
  674.             03  sxRight         pic x(2) comp-5.
  675.             03  syTop           pic x(2) comp-5.
  676.  
  677.         01  ppl.
  678.             03  x               pic x(2) comp-5.
  679.             03  y               pic x(2) comp-5.
  680.         01  mresult             pic x(4) comp-5.
  681.  
  682.         01  workarea.
  683.             03  i               pic xx   comp-5.
  684.             03  j               pic xx   comp-5.
  685.             03  cx              pic xx   comp-5.
  686.             03  cy              pic xx   comp-5.
  687.             03  hwndWork        pic xx   comp-5.
  688.             03  str             pic x(8).
  689.             03  WndProc         procedure-pointer.
  690.  
  691.         linkage section.
  692.         01  hwnd                pic xx   comp-5.
  693.         01  msg                 pic xx   comp-5.
  694.         01  mp1                 pic xx   comp-5.
  695.         01  Style redefines mp1 pic xxxx comp-5.
  696.         01  mp2                 pic xxxx comp-5.
  697.         01  redefines mp2.
  698.             03  mp2w1           pic xx   comp-5.
  699.             03  mp2w2           pic xx   comp-5.
  700.         01  Basex               pic xx   comp-5.
  701.         01  Basey               pic xx   comp-5.
  702.         01  Sizex               pic xx   comp-5.
  703.         01  Sizey               pic xx   comp-5.
  704.         01  PointSize.
  705.             03  psx             pic xx   comp-5.
  706.             03  psy             pic xx   comp-5.
  707.         01  Text1               pic x(20).
  708.  
  709.         01  hInst                   pic xx   comp-5.
  710.         01  hPrevInstance           pic xx   comp-5.
  711.         01  lpszCmdLine             pic x(120).
  712.         01  nCmdShow                pic xx   comp-5.
  713.  
  714.         procedure division WINAPI using  by value hInst
  715.                                   by value hPrevInstance
  716.                                   by reference lpszCmdLine
  717.                                   by value nCmdShow.
  718.         MyWinMain section.
  719.             if hPrevInstance = 0
  720.                 move CSClass to cstyle
  721.                 set lpfnWndProc to entry "MWndProc"
  722.                 move 0 to cbClsExtra
  723.                 move 0 to cbWndExtra
  724.                 move hInst to hInstance
  725.                 call WINAPI "__LoadIcon" using
  726.                                          by value hInstance
  727.                                          by reference "CalcIcon" & x"00"
  728.                         returning hIcon
  729.                 call WINAPI "__LoadCursor" using by value 0 size 2
  730.                                 by value h"00007f00" size 4
  731.                         returning hCursor
  732.                 call WINAPI "__GetStockObject" using by value 0 size 2
  733.                         returning hbrBackground
  734.                 set lpszMenuName to NULL
  735.                 set lpszClassName to address of MyClass
  736.                 call WINAPI '__RegisterClass' using WndClass
  737.                         returning bool
  738.                 if boolFALSE
  739.                         exit program returning 0
  740.                 end-if
  741.             end-if
  742.  
  743.       * get the name of the application
  744.             call WINAPI '__GetModuleFileName'
  745.                         using           by value hInstance
  746.                                         by reference ModName
  747.                                         by value ModSize
  748.                         returning ModSize
  749.       * strip the pathname from the module name
  750.             perform until ModName = 0 or
  751.                           ModName-Char (Modsize) = "\"
  752.                 subtract 1 from Modsize
  753.             end-perform
  754.             add 1 to Modsize
  755.  
  756.       * load the area sensitive pointer from the resource file
  757.             call WINAPI '__LoadCursor'
  758.                         using by value hInstance
  759.                               by reference "CalcCursor" & x"00"
  760.                         returning ptrH
  761.  
  762.       * load the menu from the resource file
  763.             call WINAPI '__LoadMenu'
  764.                         using by value hInstance
  765.                               by reference "CalcMenuMenu" & x"00"
  766.                         returning hwndMenu
  767.  
  768.       * load the accelerators from the resource file
  769.             call WINAPI '__LoadAccelerators'
  770.                         using by value hInstance
  771.                               by reference "CalcAccel" & x"00"
  772.                         returning hwndAccel
  773.  
  774.       * create the main window
  775.             call WINAPI "__CreateWindow" using
  776.                               by reference MyClass
  777.                               by reference Modname-Char (Modsize)
  778.                               by value     ctldata
  779.                               by value     h"8000"     size 2
  780.                               by value     0           size 2
  781.                               by value     h"8000"     size 2
  782.                               by value     0           size 2
  783.                               by value     0           size 2
  784.                               by value     hwndMenu
  785.                               by value     hInstance
  786.                               by value     0           size 4
  787.                         returning hwndFrame
  788.             call WINAPI "__ShowWindow" using
  789.                               by value hwndFrame
  790.                               by value nCmdShow
  791.             call WINAPI "__UpdateWindow" using by value hwndFrame
  792.  
  793.             if hwndFrame not = 0
  794.  
  795.       ****************************************************************
  796.       *
  797.       * This in-line PERFORM implements the message loop.
  798.       *
  799.       ****************************************************************
  800.                 perform until loop-end
  801.                     call WINAPI '__GetMessage'
  802.                                 using by reference qmsg
  803.                                       by value 0        size 2
  804.                                       by value 0        size 2
  805.                                       by value 0        size 2
  806.                                 returning bool
  807.  
  808.                     if boolFALSE
  809.                         set loop-end to true
  810.                     else
  811.                         call WINAPI '__TranslateAccelerator'
  812.                                     using by value hwndFrame
  813.                                           by value hwndAccel
  814.                                           by reference qmsg
  815.                                     returning bool
  816.                         if boolFALSE
  817.                            call WINAPI '__TranslateMessage'
  818.                                            using by reference qmsg
  819.                            call WINAPI '__DispatchMessage'
  820.                                            using by reference qmsg
  821.                         end-if
  822.  
  823.                 end-perform
  824.  
  825.                 call WINAPI '__DestroyWindow'
  826.                             using by value hwndFrame
  827.  
  828.             end-if
  829.  
  830.             stop run.
  831.  
  832.  
  833.       ****************************************************************
  834.       *
  835.       * Calculator's Window Procedure
  836.       *
  837.       ****************************************************************
  838.         MyWndProc-S section.
  839.         entry 'MWndProc' using by value hwnd
  840.                               by value msg
  841.                               by value mp1
  842.                               by value mp2.
  843.  
  844.             move 0 to mresult
  845.             evaluate msg
  846.  
  847.       ****************************************************************
  848.       *
  849.       * We process the CREATE message
  850.       *     We create User Buttons for each of the screen areas.
  851.       *
  852.       ****************************************************************
  853.                 when WM-CREATE
  854.                     call WINAPI '__CreateDisplay'
  855.                                 using by value hwnd
  856.                                       by value DisplayStyle
  857.                                       by value idDisplay    size 2
  858.                                 returning hwndDisplay
  859.                     call WINAPI '__CreateDisplay'
  860.                                 using by value hwnd
  861.                                       by value BaseStyle
  862.                                       by value idBase       size 2
  863.                                 returning hwndBase
  864.  
  865.                     move id0 to i
  866.                     perform until i > hwndButtonLast
  867.                         call WINAPI '__CreateButton'
  868.                                     using by value hwnd
  869.                                           by value i
  870.                                     returning hwndTemp
  871.                         move hwndTemp to hwndItem(i)
  872.                         add 1 to i
  873.                     end-perform
  874.  
  875.                     move 10 to gBase
  876.                     move 0 to gBaseSav
  877.                     set NoSizeError to true
  878.                     call WINAPI '__PostMessage'
  879.                                 using by value hwnd
  880.                                       by value WM-CLEAR size 2
  881.                                       by value 0        size 2
  882.                                       by value 0        size 4
  883.  
  884.       ****************************************************************
  885.       *
  886.       * Button Presses come to the Window through the WM-COMMAND
  887.       *             message, with mp1 as the Button Id.
  888.       *         This Button Id is set the same as the message
  889.       *             number which processes it.
  890.       *         So we simply generate a message...
  891.       *         Size Error condition is removed by any button,
  892.       *             which then has no effect.
  893.       *
  894.       ****************************************************************
  895.                 when    WM-COMMAND
  896.                     if mp1 > WM-USER
  897.                         if SizeError
  898.                             set NoSizeError to true
  899.                             perform UpdateD
  900.                         else
  901.                             call WINAPI '__SendMessage'
  902.                                         using by value hwnd
  903.                                               by value mp1
  904.                                               by value 0 size 2
  905.                                               by value mp2
  906.                         end-if
  907.                     end-if
  908.  
  909.       ****************************************************************
  910.       *
  911.       * We process the SIZE message
  912.       *     This involves positioning the individual buttons
  913.       *     in the correct place.
  914.       *
  915.       *     mp2 contains the current size (w1 = x dimensions, w2 = y)
  916.       *
  917.       *     We partition the available space into SquareX by SquareY
  918.       *         boxes, and pass these size chunks to PositionWindow
  919.       *
  920.       ****************************************************************
  921.                 when    WM-SIZE
  922.                     move mp2w1 to x
  923.                     move mp2w2 to y
  924.                     move SquareX to i
  925.                     multiply ButtonGap by i
  926.                     add RelativeGap to i
  927.                     divide i into x
  928.                     move SquareY to i
  929.                     multiply ButtonGap by i
  930.                     add RelativeGap to i
  931.                     divide i into y
  932.  
  933.                     perform varying i from 1 by 1
  934.                             until i > hwndTableCount
  935.  
  936.                         call WINAPI '__PositionWindow'
  937.                                     using by value hwndItem(i)
  938.                                           by value winXL(i)
  939.                                           by value winYB(i)
  940.                                           by value winXR(i)
  941.                                           by value winYT(i)
  942.                                           by reference ppl
  943.  
  944.                     end-perform
  945.  
  946.       ****************************************************************
  947.       *
  948.       * We have to process the PAINT message
  949.       * The sequence of actions is:
  950.       *
  951.       *     Get Handle-To-Presentation-Space (HPS) for painting
  952.       *                         in the client window
  953.       *     (Any drawing required could be put here...)
  954.       *     Release the HPS.
  955.       *
  956.       *
  957.       * WM-ERASEBACKGROUND is processed to enable the Frame to erase
  958.       *     the backdrop of the ClientArea.
  959.       *
  960.       ****************************************************************
  961.                 when    WM-PAINT
  962.                     call WINAPI '__BeginPaint'
  963.                                 using by value hwnd
  964.                                       by reference ppaint
  965.                                 returning hps
  966.  
  967.                     call WINAPI '__GetClientRect'
  968.                                 using by value hwnd
  969.                                       by reference rcl
  970.                     call WINAPI '__FillRect'
  971.                                 using by value hps
  972.                                       by reference rcl
  973.                                       by value hbrBackground
  974.  
  975.                     call WINAPI '__EndPaint'
  976.                                 using by value hwnd
  977.                                       by reference ppaint
  978.  
  979.                 when    WM-ERASEBACKGROUND
  980.                     move 1 to mresult
  981.                     exit program returning mresult
  982.  
  983.  
  984.       ****************************************************************
  985.       *
  986.       * We process our User defined messages
  987.       *
  988.       ****************************************************************
  989.       *
  990.       * WM-UPDATEDISPLAY updates the display window with the
  991.       *                  current RegX value in the correct base
  992.       *
  993.       *         We have to watch out for the Error condition
  994.       *         We use COBOL number conversion for Base 10
  995.       *                 and do it by hand for other bases.
  996.       *                 Fractional parts are limited by space
  997.       *                 or sensible significance (gBaseD)
  998.       *         We only update the BASE window if required
  999.       *
  1000.       ****************************************************************
  1001.                 when    WM-UPDATEDISPLAY
  1002.                     if SizeError
  1003.                         move length of CalcRegX to j
  1004.                         subtract 5 from j
  1005.                         move 'Error' to CalcRegX(j:5)
  1006.                     else
  1007.                         move all '0' to CalcRegBase
  1008.                         if gBase = 10
  1009.       *     COBOL Edited fields are useful for Decimal...
  1010.                             move Reg(RegX) to CalcReg9
  1011.                             move length of CalcReg9 to i
  1012.                         else
  1013.       *     Except for Base 10, we have to do it the hard way.
  1014.                             move length of CalcRegBase to j
  1015.       *     Initialize the DP
  1016.                             divide 2 into j
  1017.                             move '.' to CalcRegBase(j:1)
  1018.                             subtract 1 from j giving i
  1019.                             add 1 to j
  1020.       *     Fill in the Integral part
  1021.                             move Reg(RegX) to RegInt
  1022.                             perform until RegInt = 0
  1023.                                 divide gBase into RegInt
  1024.                                         giving RegInt
  1025.                                         remainder Digit9
  1026.                                 perform EnterDigit
  1027.                                 subtract 1 from i
  1028.                             end-perform
  1029.       *     If Integer is zero, we show the zero
  1030.                             if j = i + 2
  1031.                                 subtract 1 from i
  1032.                             end-if
  1033.       *     Fill in the sign
  1034.                             if Reg(RegX) < 0
  1035.                                 move '-' to CalcRegBase(i:1)
  1036.                                 subtract 1 from i
  1037.                             end-if
  1038.       *     SPACE fill the unused part
  1039.                             move spaces to CalcRegBase(1:i)
  1040.       *     Prepare for the fraction part
  1041.                             move j to i
  1042.                             move length of CalcRegBase to j
  1043.       *     Calculate how many digits are sensible
  1044.                             if j > gBaseD
  1045.                                 move gBaseD to j
  1046.                                 add i to j
  1047.                                 add 1 to j
  1048.                             end-if
  1049.       *     Fill in the fraction part
  1050.                             move Reg(RegX) to RegFrac
  1051.                             perform until RegFrac = 0 or i = j
  1052.                                 multiply RegFrac by gBase
  1053.                                             giving RegFrac
  1054.                                                    Digit9
  1055.                                 perform EnterDigit
  1056.                                 add 1 to i
  1057.                             end-perform
  1058.                             move length of CalcRegBase to i
  1059.                         end-if
  1060.  
  1061.       *     Now transfer to the display area
  1062.                         move spaces to CalcRegX
  1063.                         move length of CalcRegX to j
  1064.                         move 0 to cx
  1065.                         move 0 to cy
  1066.                         perform until i = 0 or CalcRegBase(i:1) = space
  1067.                             if CalcRegBase(i:1) not = '0'
  1068.                                or j < (length of CalcRegX)
  1069.                                 move CalcRegBase(i:1) to CalcRegX(j:1)
  1070.                                 if cy = 0
  1071.                                     add 1 to cx
  1072.                                 end-if
  1073.                                 if CalcRegBase(i:1) = '.'
  1074.                                     move 1 to cy
  1075.                                 end-if
  1076.                                 subtract 1 from j
  1077.                             end-if
  1078.                             subtract 1 from i
  1079.                         end-perform
  1080.  
  1081.       *     Special handling for trailing zeros on entered fraction
  1082.                         if modeNumber and RegDP > cx
  1083.                             subtract cx from RegDP giving cx
  1084.                             move j to i
  1085.                             subtract cx from j
  1086.                             move CalcRegX(i:) to CalcRegX(j:)
  1087.                             move length of CalcRegX to i
  1088.                             subtract cx from i
  1089.                             add 1 to i
  1090.                             move all '0' to CalcRegX(i:)
  1091.                         end-if
  1092.                     end-if
  1093.  
  1094.       *     And display...
  1095.  
  1096.                     call WINAPI '__SetWindowText'
  1097.                                 using by value hwndDisplay
  1098.                                       by reference CalcRegX(j:1)
  1099.                     if gBase not = gBaseSav
  1100.                         move gBase to gBase9
  1101.                         move gBase to gBaseSav
  1102.                         call WINAPI '__SetWindowText'
  1103.                                     using by value hwndBase
  1104.                                           by reference gBase9Bra
  1105.                     end-if
  1106.  
  1107.       ****************************************************************
  1108.       *
  1109.       * WM-n messages are dispatched to WM-NUMBER with mp1 as the
  1110.       *             number entered
  1111.       *
  1112.       ****************************************************************
  1113.                 when    WM-0 thru WM-F
  1114.                     subtract WM-0 from msg
  1115.                     call WINAPI '__SendMessage'
  1116.                                 using by value hwnd
  1117.                                       by value WM-NUMBER size 2
  1118.                                       by value msg
  1119.                                       by value 0        size 4
  1120.  
  1121.       ****************************************************************
  1122.       *
  1123.       * WM-NUMBER must check the validity of the entered digit:
  1124.       *                 it must less than the current base
  1125.       *                 it must result in a valid number
  1126.       *                 fractional digits have to be handled
  1127.       *                     in a different way.
  1128.       * WM-DP           - Begin entry of fractional part
  1129.       * WM-CHS          - X -> -X
  1130.       *
  1131.       ****************************************************************
  1132.                 when    WM-NUMBER
  1133.                     if mp1 >= gBase
  1134.                         perform SoundBeep
  1135.                     else
  1136.                         perform CheckMode
  1137.                         if RegDP = 0
  1138.                             multiply gBase by Reg(RegX)
  1139.                             on size error
  1140.                                 perform SoundBeep
  1141.                             not on size error
  1142.                                 add mp1 to Reg(RegX)
  1143.                                 on size error
  1144.                                     perform SoundBeep
  1145.                                     divide gBase into Reg(RegX)
  1146.                                 end-add
  1147.                             end-multiply
  1148.                         else
  1149.                             move 1 to RegWork
  1150.                             perform varying i from 1 by 1
  1151.                                     until i > RegDP
  1152.                                 divide gBase into RegWork
  1153.                             end-perform
  1154.                             if RegWork not = 0
  1155.                                 multiply mp1 by RegWork
  1156.                                 add RegWork to Reg(RegX)
  1157.                                 on size error
  1158.                                     perform SoundBeep
  1159.                                 not on size error
  1160.                                     add 1 to RegDP
  1161.                                 end-add
  1162.                             end-if
  1163.                         end-if
  1164.                         perform UpdateDRaw
  1165.                     end-if
  1166.  
  1167.                 when    WM-DP
  1168.                     perform CheckMode
  1169.                     if RegDP = 0
  1170.                         move 1 to RegDP
  1171.                     end-if
  1172.                     perform UpdateDRaw
  1173.  
  1174.                 when    WM-CHS
  1175.                     compute Reg(RegX) = - Reg(RegX)
  1176.                     perform UpdateDRaw
  1177.  
  1178.       ****************************************************************
  1179.       * General Functions:
  1180.       *     UpdateDRaw  - Update the display
  1181.       *     UpdateD     - Update the display after a function
  1182.       *     ZeroReg     - Zero a register
  1183.       *
  1184.       *
  1185.       * WM-ENTER        - End input of the current number
  1186.       * WM-ROLLUP       - X -> Y -> Z -> T -> X
  1187.       * WM-ROLLDOWN     - X -> T -> Z -> Y -> X
  1188.       * WM-CLEAR        - 0 -> X, Y, Z, T
  1189.       * WM-CLX          - 0 -> X
  1190.       * WM-XCHG         - X -> Y -> X
  1191.       * WM-PLUS         - Y+X -> X, T -> Z -> Y
  1192.       * WM-MINUS        - Y-X -> X, T -> Z -> Y
  1193.       * WM-MULTIPLY     - Y*X -> X, T -> Z -> Y
  1194.       * WM-DIVIDE       - Y/X -> X, T -> Z -> Y
  1195.       * WM-POWER        - Y^X -> X, T -> Z -> Y
  1196.       * WM-RECIP        - 1/X -> X
  1197.       * WM-HEX          - Set base as 16
  1198.       * WM-DEC          - Set base as 10
  1199.       * WM-OCT          - Set base as  8
  1200.       * WM-BIN          - Set base as  2
  1201.       * WM-CUSTOM       - Set base using Dialog Box
  1202.       * WM-EXIT         - Exits Calculator
  1203.       * WM-ABOUT        - Basic Help
  1204.       *
  1205.       ****************************************************************
  1206.                 when    WM-ENTER
  1207.                     set modeEnter to true
  1208.                     perform RollEnter
  1209.  
  1210.                 when    WM-ROLLUP
  1211.                     perform RollUp
  1212.                     perform UpdateD
  1213.  
  1214.                 when    WM-ROLLDOWN
  1215.                     perform RollDown
  1216.                     perform UpdateD
  1217.  
  1218.                 when    WM-CLEAR
  1219.                     perform varying i from RegX by 1
  1220.                             until i > RegLX
  1221.                         call '__ZeroReg' using by value i
  1222.                     end-perform
  1223.                     perform UpdateD
  1224.  
  1225.                 when    WM-CLX
  1226.                     call '__ZeroReg' using by value RegX size 2
  1227.                     perform UpdateD
  1228.  
  1229.                 when    WM-XCHG
  1230.                     move Reg(RegX) to Reg(RegLX)
  1231.                     move Reg(RegY) to Reg(RegX)
  1232.                     move Reg(RegLX) to Reg(RegY)
  1233.                     perform UpdateDRaw
  1234.  
  1235.                 when    WM-PLUS
  1236.                     perform RollAction
  1237.                     add Reg(RegLX) to Reg(RegX)
  1238.                         on size error set SizeError to true
  1239.                     end-add
  1240.                     perform UpdateD
  1241.  
  1242.                 when    WM-MINUS
  1243.                     perform RollAction
  1244.                     subtract Reg(RegLX) from Reg(RegX)
  1245.                         on size error set SizeError to true
  1246.                     end-subtract
  1247.                     perform UpdateD
  1248.  
  1249.                 when    WM-MULTIPLY
  1250.                     perform RollAction
  1251.                     multiply Reg(RegLX) by Reg(RegX)
  1252.                         on size error set SizeError to true
  1253.                     end-multiply
  1254.                     perform UpdateD
  1255.  
  1256.                 when    WM-DIVIDE
  1257.                     perform RollAction
  1258.                     divide Reg(RegLX) into Reg(RegX)
  1259.                         on size error set SizeError to true
  1260.                     end-divide
  1261.                     perform UpdateD
  1262.  
  1263.                 when    WM-POWER
  1264.                     perform RollAction
  1265.                     compute Reg(RegX) = Reg(RegX) ** Reg(RegLX)
  1266.                         on size error set SizeError to true
  1267.                     end-compute
  1268.                     perform UpdateD
  1269.  
  1270.                 when    WM-RECIP
  1271.                     move Reg(RegX) to Reg(RegLX)
  1272.                     compute Reg(RegX) = 1 / Reg(RegX)
  1273.                         on size error set SizeError to true
  1274.                     end-compute
  1275.                     perform UpdateD
  1276.  
  1277.                 when    WM-HEX
  1278.                     move 16 to gBase
  1279.                     move HexgBaseD to gBaseD
  1280.                     perform UpdateD
  1281.  
  1282.                 when    WM-DEC
  1283.                     move 10 to gBase
  1284.                     move DecgBaseD to gBaseD
  1285.                     perform UpdateD
  1286.  
  1287.                 when    WM-OCT
  1288.                     move  8 to gBase
  1289.                     move OctgBaseD to gBaseD
  1290.                     perform UpdateD
  1291.  
  1292.                 when    WM-BIN
  1293.                     move  2 to gBase
  1294.                     move BingBaseD to gBaseD
  1295.                     perform UpdateD
  1296.  
  1297.                 when    WM-CUSTOM
  1298.                     set WndProc to ENTRY 'DlgProc'
  1299.                     call WINAPI '__DialogBox'
  1300.                                 using by value hInstance
  1301.                                       by reference DI-BASEENTRY
  1302.                                       by value hwnd
  1303.                                       by value WndProc
  1304.  
  1305.                     move 1 to RegWork
  1306.                     move 0 to gBaseD
  1307.                     perform until RegWork = 0
  1308.                         divide gBase into RegWork
  1309.                         add 1 to gBaseD
  1310.                     end-perform
  1311.                     perform UpdateD
  1312.  
  1313.                 when    WM-EXIT
  1314.                     call WINAPI '__PostMessage'
  1315.                                 using by value hwnd
  1316.                                       by value WM-QUIT size 2
  1317.                                       by value 0 size 2
  1318.                                       by value 0 size 4
  1319.  
  1320.                 when    WM-ABOUT
  1321.                     call WINAPI '__MessageBox'
  1322.                                 using by value hwnd
  1323.                                       by reference AboutText
  1324.                                       by reference AboutTitle
  1325.                                       by value 0 size 2
  1326.  
  1327.       ****************************************************************
  1328.       *
  1329.       *  All other messages are despatched to the default
  1330.       *  window procedure according to the Windows rules.
  1331.       *
  1332.       ****************************************************************
  1333.  
  1334.                 when other
  1335.                     call WINAPI '__DefWindowProc'
  1336.                                 using by value hwnd
  1337.                                       by value msg
  1338.                                       by value mp1
  1339.                                       by value mp2
  1340.                                 returning mresult
  1341.  
  1342.             end-evaluate
  1343.  
  1344.             exit program returning mresult.
  1345.  
  1346.       ****************************************************************
  1347.       *
  1348.       * Button Window Procedure (after subclassing)
  1349.       *
  1350.       *  This simply changes the pointer when over a button
  1351.       *
  1352.       ****************************************************************
  1353.         ButtonWndProc-S section.
  1354.         entry 'BWndProc' using by value hwnd
  1355.                               by value msg
  1356.                               by value mp1
  1357.                               by value mp2.
  1358.  
  1359.             move 0 to mresult
  1360.             evaluate msg
  1361.                 when WM-MOUSEMOVE
  1362.                     call WINAPI '__GetWindowWord'
  1363.                                 using by value hwnd
  1364.                                       by value GWW-ID size 2
  1365.                                 returning i
  1366.                     evaluate i
  1367.                         when WM-0 thru WM-F
  1368.                             subtract WM-BUTTONS from i
  1369.                             subtract id0 from i
  1370.                             if i < gBase
  1371.                                 move 1 to i
  1372.                             else
  1373.                                 move 0 to i
  1374.                             end-if
  1375.                         when other
  1376.                             move 1 to i
  1377.                     end-evaluate
  1378.                     if i = 1
  1379.                         call WINAPI '__SetCursor'
  1380.                                     using by value ptrH
  1381.                     else
  1382.                         call WINAPI '__SetCursor'
  1383.                                     using by value hCursor
  1384.                     end-if
  1385.                     move 1 to mresult
  1386.  
  1387.                 when other
  1388.  
  1389.                     call WINAPI '__GetWindowWord'
  1390.                                 using by value hwnd
  1391.                                       by value GWW-ID size 2
  1392.                                 returning i
  1393.                     subtract WM-BUTTONS from i
  1394.                     set WndProc TO DefWndProc (i)
  1395.  
  1396.                     call WINAPI '__CallWindowProc'
  1397.                                 using by value WndProc
  1398.                                       by value hwnd
  1399.                                       by value msg
  1400.                                       by value mp1
  1401.                                       by value mp2
  1402.                                 returning mresult
  1403.  
  1404.             end-evaluate
  1405.  
  1406.             exit program returning mresult.
  1407.  
  1408.       ****************************************************************
  1409.       *
  1410.       * Dialog Box procedure
  1411.       *
  1412.       ****************************************************************
  1413.         DialogWndProc-S section.
  1414.         entry 'DlgProc' using by value hwnd
  1415.                               by value msg
  1416.                               by value mp1
  1417.                               by value mp2.
  1418.  
  1419.             move 0 to mresult
  1420.             evaluate msg
  1421.                 when    WM-INITDLG
  1422.                     call WINAPI '__SendDlgItemMessage'
  1423.                                 using by value hwnd
  1424.                                       by value DI-BASE         size 2
  1425.                                       by value EM-LIMITTEXT    size 2
  1426.                                       by value 3               size 2
  1427.                                       by value 0               size 4
  1428.                     call WINAPI '__SetDlgItemInt'
  1429.                                 using by value hwnd
  1430.                                       by value DI-BASE size 2
  1431.                                       by value gBase
  1432.                                       by value 0       size 2
  1433.  
  1434.       * set input focus onto the Base entry field
  1435.                     call WINAPI '__GetDlgItem'
  1436.                                 using by value hwnd
  1437.                                       by value DI-BASE size 2
  1438.                                 returning hwndWork
  1439.                     call WINAPI '__SetFocus'
  1440.                                 using by value hwndWork
  1441.  
  1442.                 when    WM-COMMAND
  1443.                     evaluate mp1
  1444.                         when DID-OK
  1445.                             call WINAPI '__GetDlgItemInt'
  1446.                                         using by value hwnd
  1447.                                               by value DI-BASE size 2
  1448.                                               by reference i
  1449.                                               by value 0       size 2
  1450.                                         returning j
  1451.                             if j < 2 or j > 36
  1452.                                 perform SoundBeep
  1453.                             else
  1454.                                 move j to gBase
  1455.                             end-if
  1456.  
  1457.                             call WINAPI '__EndDialog'
  1458.                                         using by value hwnd
  1459.                                               by value 1 size 2
  1460.  
  1461.                         when DID-CANCEL
  1462.                             call WINAPI '__EndDialog'
  1463.                                         using by value hwnd
  1464.                                               by value 1 size 2
  1465.  
  1466.                     end-evaluate
  1467.  
  1468.             end-evaluate
  1469.  
  1470.             exit program returning mresult.
  1471.  
  1472.  
  1473.       ****************************************************************
  1474.       *
  1475.       * Position Window: We use the input parameters to calculate
  1476.       *                  the actual position and size of a window
  1477.       *                  And then issue a WinSetWindowPos to
  1478.       *                  place the window correctly.
  1479.       *
  1480.       ****************************************************************
  1481.         PositionWindow-S Section.
  1482.         entry 'PositionWindow' using by value hwnd
  1483.                                      by value BaseX
  1484.                                      by value BaseY
  1485.                                      by value SizeX
  1486.                                      by value SizeY
  1487.                                      by reference PointSize.
  1488.  
  1489.             move     BaseX       to sxLeft
  1490.             multiply ButtonGap   by sxLeft
  1491.             add      RelativeGap to sxLeft
  1492.             multiply psx         by sxLeft
  1493.  
  1494.             move     SizeX       to sxRight
  1495.             add      RelativeGap to sxRight
  1496.             multiply ButtonGap   by sxRight
  1497.             multiply psx         by sxRight
  1498.             subtract sxLeft    from sxRight
  1499.  
  1500.             move     6           to syTop
  1501.             subtract SizeY       from syTop
  1502.             multiply ButtonGap   by syTop
  1503.             add      RelativeGap to syTop
  1504.             multiply psy         by syTop
  1505.  
  1506.             move     6           to syBottom
  1507.             subtract BaseY       from syBottom
  1508.             add      RelativeGap to syBottom
  1509.             multiply ButtonGap   by syBottom
  1510.             multiply psy         by syBottom
  1511.             subtract syTop       from syBottom
  1512.  
  1513.       * The following is more descriptive but less efficient.
  1514.       *
  1515.       * compute sxLeft   =
  1516.       *         psx * ( ButtonGapRatio * BaseX + RelativeGap )
  1517.       * compute sxRight  =
  1518.       *         psx * ButtonGapRatio * ( SizeX + RelativeGap )
  1519.       *               - sxLeft
  1520.       * compute syBottom =
  1521.       *         psy *  ButtonGapRatio * (BaseY + RelativeGap )
  1522.       *               - syTop
  1523.       * compute syTop    =
  1524.       *         psy * ( ButtonGapRatio * SizeY + RelativeGap )
  1525.  
  1526.             call WINAPI '__MoveWindow'
  1527.                         using by value hwnd
  1528.                               by value sxLeft
  1529.                               by value syTop
  1530.                               by value sxRight
  1531.                               by value syBottom
  1532.                               by value 1           size 2
  1533.  
  1534.             exit program.
  1535.  
  1536.  
  1537.       ****************************************************************
  1538.       *
  1539.       * CreateDisplay: Create windows to be used for outputing
  1540.       *                numbers to the screen
  1541.       *                This is used for the X Register and the BASE
  1542.       *
  1543.       ****************************************************************
  1544.         CreateDisplay-S Section.
  1545.         entry 'CreateDisplay' using by value hwnd
  1546.                                     by value Style
  1547.                                     by value msg.
  1548.  
  1549.             call WINAPI '__CreateWindow'
  1550.                         using by reference WC-STATIC
  1551.                               by value      0           size 4
  1552.                               by value      Style
  1553.                               by value      0            size 2
  1554.                               by value      0            size 2
  1555.                               by value      0            size 2
  1556.                               by value      0            size 2
  1557.                               by value      hwnd
  1558.                               by value      msg
  1559.                               by value      hInstance
  1560.                               by value      0           size 4
  1561.  
  1562.                         returning hwnd
  1563.  
  1564.             exit program returning hwnd.
  1565.  
  1566.  
  1567.       ****************************************************************
  1568.       *
  1569.       * CreateButton: Each BUTTON on the screen needs to be
  1570.       *               created as a separate window.
  1571.       *               We give it a ID (which it sends to its owner
  1572.       *               when it is pressed) identical to the
  1573.       *               message id of its processing routine.
  1574.       *               We also initialize the text.
  1575.       *               We subclass the buttons for pointer control
  1576.       *
  1577.       ****************************************************************
  1578.         CreateButton-S Section.
  1579.         entry 'CreateButton' using by value hwnd
  1580.                                    by value msg.
  1581.  
  1582.             move msg to i
  1583.             add WM-BUTTONS to i
  1584.  
  1585.       * The string to WinSetWindowText should be NULL terminated
  1586.             move hwndText(msg) to str
  1587.             inspect str replacing first space by x'00'
  1588.  
  1589.             call WINAPI '__CreateWindow'
  1590.                         using by reference  WC-BUTTON
  1591.                               by reference  str
  1592.                               by value      ButtonStyle
  1593.                               by value      0           size 2
  1594.                               by value      0           size 2
  1595.                               by value      0           size 2
  1596.                               by value      0           size 2
  1597.                               by value      hwnd
  1598.                               by value      i
  1599.                               by value      hInstance
  1600.                               by value      0           size 4
  1601.  
  1602.                         returning hwnd
  1603.  
  1604.       * save the pointer to the default procedure for the button
  1605.             call WINAPI '__GetWindowLong'
  1606.                         using by value hwnd
  1607.                               by value GWL-WNDPROC      size 2
  1608.                         returning WndProc
  1609.             subtract WM-BUTTONS from i
  1610.             set DefWndProc (i) to WndProc
  1611.  
  1612.       * turn off the default cursor for the button
  1613.             call WINAPI '__SetClassWord'
  1614.                         using by value hwnd
  1615.                               by value GCW-HCURSOR      size 2
  1616.                               by value 0                size 2
  1617.                         returning j
  1618.  
  1619.       * subclass the button
  1620.             set WndProc to ENTRY 'BWndProc'
  1621.             call WINAPI '__SetWindowLong'
  1622.                         using by value hwnd
  1623.                               by value GWL-WNDPROC      size 2
  1624.                               by value WndProc
  1625.                         returning WndProc
  1626.  
  1627.             exit program returning hwnd.
  1628.  
  1629.       ****************************************************************
  1630.       *
  1631.       * ZeroReg - a function which sets register 'msg' to zero.
  1632.       *           This has been localised to minimise the impact
  1633.       *           of a change in the internal definition of the
  1634.       *           registers.
  1635.       *
  1636.       ****************************************************************
  1637.         ZeroReg-S Section.
  1638.         entry 'ZeroReg' using by value msg.
  1639.  
  1640.             move 0 to Reg(msg)
  1641.             move 0 to RegDP
  1642.             exit program.
  1643.  
  1644.       ****************************************************************
  1645.       *
  1646.       * SoundBeep - Sound the bell.
  1647.       *
  1648.       ****************************************************************
  1649.         SoundBeep Section.
  1650.             call WINAPI '__MessageBeep'
  1651.                         using by value 0 size 2.
  1652.  
  1653.       ****************************************************************
  1654.       *
  1655.       * Miscellaneous Subroutines:
  1656.       *
  1657.       * UpdateDRaw  -   Generate a message to force update of RegX
  1658.       * UpdateD     -   Also sets mode to Function
  1659.       * RollEnter   -   Register Rolling for ENTER
  1660.       * RollUp      -   Register Rolling for ROLLUP
  1661.       * RollDown    -   Register Rolling for ROLLDOWN
  1662.       * RollAction  -   Register Rolling for PLUS/MINUS etc.
  1663.       * EnterDigit  -   Turn Digit9 to ASCII (DigitX) and store
  1664.       * CheckMode   -   Handles the mode checking for entry of
  1665.       *                     a digit or a DP char.
  1666.       *
  1667.       ****************************************************************
  1668.         UpdateD Section.
  1669.             set modeFunction to true
  1670.             perform UpdateDRaw.
  1671.  
  1672.         UpdateDRaw Section.
  1673.             call WINAPI '__SendMessage'
  1674.                         using by value hwnd
  1675.                               by value WM-UPDATEDISPLAY size 2
  1676.                               by value 0                size 2
  1677.                               by value 0                size 4.
  1678.  
  1679.         RollEnter Section.
  1680.             move Reg(RegZ) to Reg(RegT)
  1681.             move Reg(RegY) to Reg(RegZ)
  1682.             move Reg(RegX) to Reg(RegY).
  1683.  
  1684.         RollUp Section.
  1685.             move Reg(RegT) to RegWork
  1686.             perform RollEnter
  1687.             move RegWork to Reg(RegX).
  1688.  
  1689.         RollDown Section.
  1690.             perform RollAction
  1691.             move Reg(RegLX) to Reg(RegT).
  1692.  
  1693.         RollAction Section.
  1694.             move Reg(RegX) to Reg(RegLX)
  1695.             move Reg(RegY) to Reg(RegX)
  1696.             move Reg(RegZ) to Reg(RegY)
  1697.             move Reg(RegT) to Reg(RegZ).
  1698.  
  1699.         EnterDigit Section.
  1700.             if Digit9 > 9
  1701.                 add 7 to Digit9
  1702.             end-if
  1703.             add h"30" to Digit9
  1704.             move DigitX to CalcRegBase(i:1).
  1705.  
  1706.         CheckMode Section.
  1707.             if modeFunction
  1708.                 perform RollEnter
  1709.                 set modeEnter to true
  1710.             end-if
  1711.             if modeEnter
  1712.                 call '__ZeroReg' using by value RegX size 2
  1713.             end-if
  1714.             set modeNumber to true.
  1715.