//-------------------------------------------------------------
//  Hex Calculator identical to Petzold's classic using OWL 2.0
//  by Fook H. Eng  09/20/94 (818) 572-9983, CIS id 76545,255
//-------------------------------------------------------------
This is a version of a hexidecimal calculator implemented in C++ using OWL II.
From the user's point of view, the calculator program is identical to
Petzold's hexCalc program in his classic book Programming for Windows 3.1.
His formulation of the calculator algorithm was so elegant and concise that,
in so far as pragmatically feasible, I've extracted his technique verbatim.

The key issues here is to use a single frame window and a single dialog. The
dialog, contrary to usual practices, does not have close dialog options in the
form of OK and Cancel buttons.  Thus the dialog never closes. However, never
fear, it will vanish when the main window is closed via the close option from
the sysmenu button.  Also contrary to normal practice, the main window does
not have the resize border and the normal maximize button is not present,
since it really does not make any sense to enlarge the calculator.

Let's look at the code. The dialog class TCalc is derived from class TDialog.
It overrides the three virtual functions inherited from somewhere along the
ancestral line.  These functions are EvPaint, EvCommand, and EvCtlColor. The
other functions - ShowNumber, CalcKey, and CalcIt are our implementations to
the new class.  Two data members are background brushes - white and purple.

Some people would style the overridden virtual functions specifically with
the key word virtual, like so:

    virtual LRESULT EvCommand();
    virtual void    EvPaint();
    ...

The usage of the keyword virtual in this manner is not a requirement in C++
when a virtual function is overridden, and I would prefer to reserve the
inclusion of that keyword to designate virtual functions which I create in
the derived class.  Thus my usage of the keyword virtual tantamounts to
declaring that here is a virtual function created to be pass on to all
posterity, thereby making a distinction from an inherited virtual which is
being overridden.  Whichever style you choose, try to be consistent.  But
if you are not consistent, I regret to note, you will not be lacking for
company in this spaghetti infested brotherhood of programming community.

The response table shows we want to trap WM_PAINT and WM_CTLCOLOR messages.
We also want to trap the notification messages the controls send to its parent
window as well as the messages sent when an accelerator key is pressed. These
are the WM_COMMAND messages, for which OWL II will provide without our specific
requests for same.  So we don't make that request here.

Look at the EvCtlColor function.  There is a brushChoice parameter which is
toggled each time this function is invoked.  This bit of hanky panky is for an
honorable educational purpose.  I am learning Windows at this stage and I am
not totally sure of what Windows does and when it does things, so I place a
brush color change toggle here. Sure beats cluttering the screen with message
boxes, don't you think?

In the EvPaint function this bit of chicanery is repeated for the drawing of
an ellipse in the lower right 2/3rd of the dialog real estate. Run this
program, minimize it and then restore it.  Is the background unchanged?
How about the ellipse?  Wholly or partially cover the calculator with another
window.  Now, make the calculator active again.  Did any color change?
Either wholly or partially?  Like I said, I don't totally know what Windows
does or when it does what it does.  I'm sure it will give you a better insight
into Windows' behavior to ponder the segmented multicolor calculator which you
will eventually obtain.

Look at the declaration of the dialog in the .rc file.  For the pushbuttons,
We choose to specify the id associated with the text "A" to be 65, the id
associated with "B" to be 66, etc.  ie, we set the id to be the ascii number
corresponding to the single letter text of the pushbutton. This is Petzold's
creative use of control ids. With this clever choice of id-text associations,
we can pass the control id directly to the CalcKey function without further
translation, as we do in the overridden virtual function EvCommand.  The
calculator dialog also respond to keypresses from the key board as specified
through the accelerator table in .rc file.  The "^" key is meant to designate
C's exclusive OR binary operation.  But you can see that we deviated from the
("char", id_value, type) accelerator statement format when we came to its
accelerator statement.  We use the alternate (ascii_value, id_value, type)
format instead.  Why?  Well, accelerator table syntax accepts control
characters input if they are accompanied by the leadin "^", so we skin the
cat differently.  Also we selected the id_value for these keys in a creative
manner so that we could pass the id_value to the CalcKey function with the
same convenience as for the button presses.

In the normal template for a window program with a dialog window, a main_Win
class is derived from class TFrameWindow, a main_App class is derived from
class TApplication, and an any_Dlg class is derived somehow.  In our case,
we bypass the main_Win class derivation because there is nothing special
that we want do there.  And the only message we want the main window to
respond to would be through the sysmenu button and that we can accomplish
without deriving a special main_Win class.  Still a main_Win of some kind
must exist. This comes about through a statement in the overridden virtual
function TCalcApp::InitMainWindow,

    MainWindow = new TFrameWindow(0, "HexCalc II", calcWin, TRUE);

This statement declares a main window directly from the TFrameWindow class,
designates the caption "HexCalc II", specifies the client dialog calcWin,
and shrinks the window down to the size of the client window.  Finally, the
statement,

    MainWindow->Attr.Style &= ~(WS_MAXIMIZEBOX | WS_THICKFRAME);

strips the normal maximizing and resizing features from the main window.

