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

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