home *** CD-ROM | disk | FTP | other *** search
/ C Programming Starter Kit 2.0 / SamsPublishing-CProgrammingStarterKit-v2.0-Win31.iso / tybc4 / mrcalc.cpp < prev    next >
C/C++ Source or Header  |  1994-05-26  |  9KB  |  330 lines

  1. #include <ctype.h>
  2. #include <math.h>
  3. #include <stdio.h>
  4. #include <owl\applicat.h>
  5. #include <owl\button.h>
  6. #include <owl\edit.h>
  7. #include <owl\framewin.h>
  8. #include <owl\static.h>
  9. #include <owl\window.h>
  10. #include <owl\window.rh>
  11.  
  12. #include "mrcalc.h"
  13.  
  14. class TCalcWindow : public TWindow
  15. {
  16. public:
  17.    TCalcWindow(TWindow *parent = 0);
  18.    ~TCalcWindow();
  19.  
  20. protected:
  21.    virtual void SetupWindow();
  22.    virtual void EvLButtonDown(UINT modKeys, TPoint &point);
  23.  
  24.    void CmCalc();
  25.    void CmStore();
  26.    void CmExit();
  27.  
  28. private:
  29.    TStatic  *ErrMsgLabel;
  30.    TEdit    *Operand1, *Operator, *Operand2, *Result,
  31.             *ErrMsg, *Variable;
  32.    TButton  *Store;
  33.  
  34.    double get_number(TEdit *edit);
  35.    double get_var(int line);
  36.    void put_var(double val);
  37.  
  38.    DECLARE_RESPONSE_TABLE(TCalcWindow);
  39. };
  40. DEFINE_RESPONSE_TABLE1(TCalcWindow, TWindow)
  41.    EV_WM_LBUTTONDOWN,
  42.    EV_COMMAND(CM_EXIT, CmExit),
  43.    EV_BN_CLICKED(IDB_CALC, CmCalc),
  44.    EV_BN_CLICKED(IDB_STORE, CmStore),
  45.    EV_BN_CLICKED(IDB_EXIT, CmExit),
  46. END_RESPONSE_TABLE;
  47.  
  48. TCalcWindow::TCalcWindow(TWindow *parent)
  49. {
  50.    Init(parent, 0, 0);
  51.  
  52.    int   wlblspacing = 40,
  53.          hlblspacing = 5,
  54.          wlbl = 100,
  55.          hlbl = 20,
  56.          wbox = 100,
  57.          hbox = 30,
  58.          wboxspacing = 40,
  59.          hboxspacing = 40,
  60.          wbtn = 80,
  61.          hbtn = 30,
  62.          wbtnspacing = 30;
  63.    int   wlongbox = 4 * (wbox + wboxspacing);
  64.    int   wvarbox = 2 * wbox,
  65.          hvarbox = 3 * hbox;
  66.    int   x0 = 20, y0 = 30;
  67.    int   x, y;
  68.  
  69.    // First, create the labels for the edit text boxes.
  70.    //
  71.    x = x0;
  72.    y = y0;
  73.    new TStatic(this, -1, "Operand1", x, y, wlbl, hlbl);
  74.    x += wlbl + wlblspacing;
  75.    new TStatic(this, -1, "Operator", x, y, wlbl, hlbl);
  76.    x += wlbl + wlblspacing;
  77.    new TStatic(this, -1, "Operand2", x, y, wlbl, hlbl);
  78.    x += wlbl + wlblspacing;
  79.    new TStatic(this, -1, "Result", x, y, wlbl, hlbl);
  80.    x += wlbl + wlblspacing;
  81.  
  82.    // Now create the edit text boxes
  83.    //
  84.    x = x0;
  85.    y += hlbl + hlblspacing;
  86.    if (NULL != (Operand1 = new TEdit(this, IDE_OPERAND1, "",
  87.                                              x, y, wbox, hbox)))
  88.       Operand1->Attr.Style |= ES_UPPERCASE;
  89.    x += wbox + wboxspacing;
  90.    if (NULL != (Operator = new TEdit(this, IDE_OPERATOR, "",
  91.                                              x, y, wbox, hbox)))
  92.       Operator->Attr.Style |= ES_UPPERCASE;
  93.    x += wbox + wboxspacing;
  94.    if (NULL != (Operand2 = new TEdit(this, IDE_OPERAND2, "",
  95.                                              x, y, wbox, hbox)))
  96.       Operand2->Attr.Style |= ES_UPPERCASE;
  97.    x += wbox + wboxspacing;
  98.    Result = new TEdit(this, IDE_RESULT, "", x, y, wbox, hbox);
  99.    x += wbox + wboxspacing;
  100.  
  101.    // Now create the label and box for the error message
  102.    //
  103.    x = x0;
  104.    y += hbox + hboxspacing;
  105.    ErrMsgLabel = new TStatic( this, -1, "Error Message", x, y,
  106.                               wlbl, hlbl );
  107.    y += hlbl + hlblspacing;
  108.    ErrMsg = new TEdit(this, IDE_ERRMSG, "", x, y, wlongbox, hbox);
  109.  
  110.    // Create the label and box for the single-letter
  111.    // variable selection
  112.    //
  113.    y += hbox + hboxspacing;
  114.    new TStatic(this, -1, "Variables", x, y, wlbl, hlbl);
  115.    y += hlbl + hlblspacing;
  116.    char str[6 * ('Z' - 'A' + 1) + 1];
  117.    char *p = str;
  118.    for (char ch = 'A'; ch <= 'Z'; ++ch)
  119.       p += sprintf(p, "%c: 0\r\n", ch);
  120.    Variable = new TEdit(this, IDE_VARIABLE, str, x, y,
  121.                         wvarbox, hvarbox, 0, TRUE );
  122.  
  123.    // Finally create some buttons
  124.    //
  125.    x += wvarbox + wbtnspacing;
  126.    new TButton(this, IDB_CALC, "Calc", x, y, wbtn, hbtn);
  127.    x += wbtn + wbtnspacing;
  128.    Store = new TButton(this, IDB_STORE, "Store", x, y, wbtn, hbtn);
  129.    x += wbtn + wbtnspacing;
  130.    new TButton(this, IDB_EXIT, "Exit", x, y, wbtn, hbtn);
  131. }
  132.  
  133. TCalcWindow::~TCalcWindow()
  134. {
  135. }
  136.  
  137. void TCalcWindow::SetupWindow()
  138. {
  139.    TWindow::SetupWindow();    // Initialize the visual element
  140.  
  141.    // Keep the users out of the destination areas.
  142.    //
  143.    if (Result)
  144.       Result->SetReadOnly(TRUE);
  145.    if (ErrMsg)
  146.       ErrMsg->SetReadOnly(TRUE);
  147.    if (Variable)
  148.       Variable->SetReadOnly(TRUE);
  149. }
  150.  
  151. void TCalcWindow::EvLButtonDown(UINT /*modKeys*/, TPoint &point)
  152. {
  153.    if (     ErrMsgLabel
  154.          && (ErrMsgLabel->HWindow == ChildWindowFromPoint(point)) )
  155.       {
  156.       if (ErrMsg)
  157.          ErrMsg->Clear();
  158.       if (Store)
  159.          Store->EnableWindow(TRUE);
  160.       }
  161. }
  162.  
  163. double TCalcWindow::get_number(TEdit *edit)
  164. {
  165.    double rslt;
  166.    char *str;
  167.    int size;
  168.  
  169.    if (edit)
  170.       {
  171.       str = new char[size = edit->GetWindowTextLength() + 1];
  172.       if (str)
  173.          {
  174.          edit->GetWindowText(str, size);
  175.          if (isalpha(str[0]))
  176.             rslt = get_var(tolower(str[0]) - 'a');
  177.          else
  178.             rslt = atof(str);
  179.          delete str;
  180.          }
  181.       }
  182.    return rslt;
  183. }
  184.  
  185. double TCalcWindow::get_var(int line)
  186. {
  187.    double rslt = 0;
  188.    
  189.    if (Variable)
  190.       {
  191.       int size = Variable->GetLineLength(line) + 1;
  192.       char *str = new char[size];
  193.       if (str)
  194.          {
  195.          Variable->GetLine(str, size, line);
  196.          rslt = atof(str + 3);      // Don't want first 3 chars
  197.          delete str;
  198.          }
  199.       }
  200.    return rslt;
  201. }
  202.  
  203. void TCalcWindow::put_var(double var)
  204. {
  205.    if (Variable)
  206.       {
  207.       UINT start, end;
  208.       Variable->GetSelection(start, end);
  209.       if (start != end)
  210.          Variable->SetSelection(start, start);
  211.       int line = Variable->GetLineFromPos(-1);
  212.       int size = Variable->GetLineLength(line) + 1;
  213.       char *str = new char[size];
  214.       if (str)
  215.          {
  216.          Variable->GetLine(str, size, line);
  217.          sprintf(str, "%c: %g", str[0], var);
  218.          start = Variable->GetLineIndex(-1);
  219.          end = start + Variable->GetLineLength(-1);
  220.          Variable->SetSelection(start, end);
  221.          Variable->Insert(str);
  222.          delete str;
  223.          }
  224.       }
  225.    
  226. }
  227.  
  228. void TCalcWindow::CmCalc()
  229. {
  230.    double x, y, z = 0;
  231.    char  *str, *err = NULL;
  232.    int   size;
  233.  
  234.    x = get_number(Operand1);
  235.    y = get_number(Operand2);
  236.  
  237.    if (Operator)
  238.       {
  239.       str = new char[size = Operator->GetWindowTextLength() + 1];
  240.       if (str)
  241.          {
  242.          Operator->GetWindowText(str, size);
  243.          if (str[1] != '\0')
  244.             err = "Invalid operator";
  245.          else
  246.             switch (str[0])
  247.                {
  248.                case '+':
  249.                   z = x + y;
  250.                   break;
  251.                case '-':
  252.                   z = x - y;
  253.                   break;
  254.                case '*':
  255.                   z = x * y;
  256.                   break;
  257.                case '/':
  258.                   if (y)
  259.                      z = x / y;
  260.                   else
  261.                      err = "Division by zero error";
  262.                   break;
  263.                case '^':
  264.                   if (x > 0)
  265.                      z = exp(y * log(x));
  266.                   else
  267.                      err = "Can't raise power of negative numbers";
  268.                   break;
  269.                default:
  270.                   err = "Invalid operator";
  271.                   break;
  272.                }
  273.             if (ErrMsg)
  274.                if (!err)
  275.                   ErrMsg->Clear();
  276.                else
  277.                   ErrMsg->SetWindowText(err);
  278.             if (Store)
  279.                Store->EnableWindow(!err);
  280.             if (!err && Result)
  281.                {
  282.                char dest[81];
  283.                sprintf(dest, "%g", z);
  284.                Result->SetWindowText(dest);
  285.                }
  286.          delete str;
  287.          }
  288.       }
  289. }
  290.  
  291. void TCalcWindow::CmStore()
  292. {
  293.    if (Result)
  294.       {
  295.       int size = Result->GetWindowTextLength() + 1;
  296.       char *str = new char[size];
  297.       if (str)
  298.          {
  299.          Result->GetWindowText(str, size);
  300.          put_var(atof(str));
  301.          delete str;
  302.          }
  303.       }
  304. }
  305.  
  306. void TCalcWindow::CmExit()
  307. {
  308.    SendMessage(WM_CLOSE);
  309. }
  310.  
  311. class TCalcApp : public TApplication
  312. {
  313. public:
  314.    TCalcApp() : TApplication()
  315.       { nCmdShow = SW_SHOWMAXIMIZED; }
  316.  
  317.    void InitMainWindow()
  318.       {
  319.       SetMainWindow(new TFrameWindow(  0,
  320.                            "Mr. Calulator",
  321.                            new TCalcWindow ));
  322.       GetMainWindow()->AssignMenu("EXITMENU");
  323.       }
  324. };
  325.  
  326. int OwlMain(int, char *[])
  327. {
  328.    return TCalcApp().Run();
  329. }
  330.