home *** CD-ROM | disk | FTP | other *** search
/ C Programming Starter Kit 2.0 / SamsPublishing-CProgrammingStarterKit-v2.0-Win31.iso / tybc4 / calcjr.cpp < prev    next >
C/C++ Source or Header  |  1994-05-26  |  7KB  |  261 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\combobox.h>
  7. #include <owl\edit.h>
  8. #include <owl\framewin.h>
  9. #include <owl\static.h>
  10. #include <owl\window.h>
  11. #include <owl\window.rh>
  12.  
  13. #include "calcjr.h"
  14.  
  15. class THistoryBox : public TComboBox
  16. {
  17. public:
  18.    THistoryBox(TWindow  *parent,
  19.                int      id,
  20.                int x, int y, int w, int h,
  21.                UINT     textLen,
  22.                int      historyLen,
  23.                TModule  *module = 0);
  24.  
  25.    void EvKillFocus(HWND);
  26.  
  27. private:
  28.    int history;
  29.  
  30.    DECLARE_RESPONSE_TABLE(THistoryBox);
  31. };
  32. DEFINE_RESPONSE_TABLE1(THistoryBox, TComboBox)
  33.    EV_WM_KILLFOCUS,
  34. END_RESPONSE_TABLE;
  35.  
  36. THistoryBox::THistoryBox(  TWindow *parent,
  37.                            int id,
  38.                            int x, int y, int w, int h,
  39.                            UINT textLen,
  40.                            int historyLen,
  41.                            TModule *module )
  42.    : TComboBox(parent, id, x, y, w, h, CBS_DROPDOWN, textLen, module)
  43. {
  44.    Attr.Style &= ~CBS_SORT;      // We don't want to sort
  45.    history = historyLen;
  46. }
  47.  
  48. void THistoryBox::EvKillFocus(HWND)
  49. {
  50.    int len = GetTextLen() + 1;
  51.    char *str = new char[len];
  52.    if (str)
  53.       {
  54.       GetText(str, len);
  55.       int ix = FindExactString(str, -1);
  56.       if (ix < 0)
  57.          {
  58.          InsertString(str, 0);
  59.          while (GetCount() >= history)
  60.             DeleteString(GetCount() - 1);
  61.          }
  62.       else if (ix > 0)
  63.          {
  64.          DeleteString(ix);
  65.          InsertString(str, 0);
  66.          SetSelIndex(0);
  67.          }
  68.       delete str;
  69.       }
  70. }
  71.  
  72. class TCalcJrWindow : public TWindow
  73. {
  74. public:
  75.    TCalcJrWindow(TWindow *parent = 0);
  76.  
  77. protected:
  78.    virtual void SetupWindow();
  79.  
  80.    void CmCalc();
  81.    void CmExit();
  82.  
  83. private:
  84.    TComboBox   *Operator;
  85.    THistoryBox *Operand1, *Operand2, *Result;
  86.    TEdit       *ErrMsg;
  87.  
  88.    DECLARE_RESPONSE_TABLE(TCalcJrWindow);
  89. };
  90. DEFINE_RESPONSE_TABLE1(TCalcJrWindow, TWindow)
  91.    EV_BN_CLICKED(IDB_CALC, CmCalc),
  92.    EV_BN_CLICKED(IDB_EXIT, CmExit),
  93. END_RESPONSE_TABLE;
  94.  
  95. TCalcJrWindow::TCalcJrWindow(TWindow *parent)
  96. {
  97.    Init(parent, 0, 0);
  98.  
  99.    new TStatic(this, -1, "Operand1", 20, 30, 100, 20);
  100.    new TStatic(this, -1, "Operator", 160, 30, 100, 20);
  101.    new TStatic(this, -1, "Operand2", 300, 30, 100, 20);
  102.    new TStatic(this, -1, "Result", 440, 30, 100, 20);
  103.  
  104.    Operand1 = new THistoryBox(this, IDC_OPERAND1, 20, 55, 100, 150,
  105.                                              0, 30);
  106.    Operator = new TComboBox(this, IDC_OPERATOR, 160, 55, 100, 150,
  107.                                              CBS_DROPDOWNLIST, 0);
  108.    if (Operator)
  109.       Operator->Attr.Style &= ~CBS_SORT;
  110.    Operand2 = new THistoryBox(this, IDC_OPERAND2, 300, 55, 100, 150,
  111.                                              0, 30);
  112.    Result = new THistoryBox(this, IDC_RESULT, 440, 55, 100, 150,
  113.                                              0, 30);
  114.  
  115.    new TStatic(this, -1, "Error Message", 20, 215, 100, 20);
  116.    ErrMsg = new TEdit(this, IDE_ERRMSG, "", 20, 240, 560, 30);
  117.  
  118.    new TButton(this, IDB_CALC, "Calc", 20, 290, 80, 30);
  119.    new TButton(this, IDB_EXIT, "Exit", 130, 290, 80, 30);
  120. }
  121.  
  122. void TCalcJrWindow::SetupWindow()
  123. {
  124.    TWindow::SetupWindow();    // Initialize the visual element
  125.  
  126.    // Fill up out Operator combo box with a variety
  127.    // of operators for our users compuational pleasure.
  128.    //
  129.    if (Operator)
  130.       {
  131.       static char *p[] =
  132.          { "+", "-", "*", "/", "^", "log", "exp", "sqrt", NULL };
  133.       for (int ix = 0; p[ix]; ++ix)
  134.          Operator->AddString(p[ix]);
  135.       }
  136.  
  137.    // Keep the users out of the error box.
  138.    //
  139.    if (ErrMsg)
  140.       ErrMsg->SetReadOnly(TRUE);
  141. }
  142.  
  143. double get_number(TComboBox *numbox)
  144. {
  145.    double rslt = 0;        // default to 0
  146.    char *str;
  147.    int size;
  148.  
  149.    if (numbox)
  150.       {
  151.       str = new char[size = numbox->GetTextLen() + 1];
  152.       if (str)
  153.          {
  154.          numbox->GetText(str, size);
  155.          rslt = atof(str);
  156.          delete str;
  157.          }
  158.       }
  159.    return rslt;
  160. }
  161.  
  162. void TCalcJrWindow::CmCalc()
  163. {
  164.    double x, y, z = 0;
  165.  
  166.    x = get_number(Operand1);
  167.    y = get_number(Operand2);
  168.  
  169.    if (Operator)
  170.       {
  171.       int   ix = Operator->GetSelIndex();
  172.       if (ix >= 0)
  173.          {
  174.          char *err = NULL;
  175.  
  176.          switch (ix)
  177.             {
  178.             case 0:     // + operator
  179.                z = x + y;
  180.                break;
  181.             case 1:     // - operator
  182.                z = x - y;
  183.                break;
  184.             case 2:     // * operator
  185.                z = x * y;
  186.                break;
  187.             case 3:     // / operator
  188.                if (y)
  189.                   z = x / y;
  190.                else
  191.                   err = "Can't divide by zero.";
  192.                break;
  193.             case 4:     // ^ operator
  194.                if (x > 0)
  195.                   z = exp(y * log(x));
  196.                else
  197.                   err = "Need positive number to raise power.";
  198.                break;
  199.             case 5:     // log function
  200.                if (x > 0)
  201.                   z = log(x);
  202.                else
  203.                   err = "Need positive number for log.";
  204.                break;
  205.             case 6:     // exp function
  206.                if (x < 230)
  207.                   z = exp(x);
  208.                else
  209.                   err = "Need a smaller number for exp.";
  210.                break;
  211.             case 7:     // sqrt function
  212.                if (x >= 0)
  213.                   z = sqrt(x);
  214.                else
  215.                   err = "Can't do sqrt of negative number.";
  216.                break;
  217.             default:
  218.                err = "Unknown operator";
  219.                break;
  220.             }
  221.  
  222.          if (ErrMsg)
  223.             if (!err)
  224.                ErrMsg->Clear();
  225.             else
  226.                ErrMsg->SetWindowText(err);
  227.          if (!err && Result)
  228.             {
  229.             char dest[81];
  230.             sprintf(dest, "%g", z);
  231.             Result->SetWindowText(dest);
  232.             Result->EvKillFocus(NULL);    // Force history addition
  233.             }
  234.          }
  235.       }
  236. }
  237.  
  238. void TCalcJrWindow::CmExit()
  239. {
  240.    SendMessage(WM_CLOSE);
  241. }
  242.  
  243. class TCalcJrApp : public TApplication
  244. {
  245. public:
  246.    TCalcJrApp() : TApplication()
  247.       { nCmdShow = SW_SHOWMAXIMIZED; }
  248.  
  249.    void InitMainWindow()
  250.       {
  251.       SetMainWindow(new TFrameWindow(  0,
  252.                            "Son of Mr. Calulator",
  253.                            new TCalcJrWindow ));
  254.       }
  255. };
  256.  
  257. int OwlMain(int, char *[])
  258. {
  259.    return TCalcJrApp().Run();
  260. }
  261.