home *** CD-ROM | disk | FTP | other *** search
- #include <ctype.h>
- #include <math.h>
- #include <stdio.h>
- #include <owl\applicat.h>
- #include <owl\button.h>
- #include <owl\combobox.h>
- #include <owl\edit.h>
- #include <owl\framewin.h>
- #include <owl\static.h>
- #include <owl\window.h>
- #include <owl\window.rh>
-
- #include "calcjr.h"
-
- class THistoryBox : public TComboBox
- {
- public:
- THistoryBox(TWindow *parent,
- int id,
- int x, int y, int w, int h,
- UINT textLen,
- int historyLen,
- TModule *module = 0);
-
- void EvKillFocus(HWND);
-
- private:
- int history;
-
- DECLARE_RESPONSE_TABLE(THistoryBox);
- };
- DEFINE_RESPONSE_TABLE1(THistoryBox, TComboBox)
- EV_WM_KILLFOCUS,
- END_RESPONSE_TABLE;
-
- THistoryBox::THistoryBox( TWindow *parent,
- int id,
- int x, int y, int w, int h,
- UINT textLen,
- int historyLen,
- TModule *module )
- : TComboBox(parent, id, x, y, w, h, CBS_DROPDOWN, textLen, module)
- {
- Attr.Style &= ~CBS_SORT; // We don't want to sort
- history = historyLen;
- }
-
- void THistoryBox::EvKillFocus(HWND)
- {
- int len = GetTextLen() + 1;
- char *str = new char[len];
- if (str)
- {
- GetText(str, len);
- int ix = FindExactString(str, -1);
- if (ix < 0)
- {
- InsertString(str, 0);
- while (GetCount() >= history)
- DeleteString(GetCount() - 1);
- }
- else if (ix > 0)
- {
- DeleteString(ix);
- InsertString(str, 0);
- SetSelIndex(0);
- }
- delete str;
- }
- }
-
- class TCalcJrWindow : public TWindow
- {
- public:
- TCalcJrWindow(TWindow *parent = 0);
-
- protected:
- virtual void SetupWindow();
-
- void CmCalc();
- void CmExit();
-
- private:
- TComboBox *Operator;
- THistoryBox *Operand1, *Operand2, *Result;
- TEdit *ErrMsg;
-
- DECLARE_RESPONSE_TABLE(TCalcJrWindow);
- };
- DEFINE_RESPONSE_TABLE1(TCalcJrWindow, TWindow)
- EV_BN_CLICKED(IDB_CALC, CmCalc),
- EV_BN_CLICKED(IDB_EXIT, CmExit),
- END_RESPONSE_TABLE;
-
- TCalcJrWindow::TCalcJrWindow(TWindow *parent)
- {
- Init(parent, 0, 0);
-
- new TStatic(this, -1, "Operand1", 20, 30, 100, 20);
- new TStatic(this, -1, "Operator", 160, 30, 100, 20);
- new TStatic(this, -1, "Operand2", 300, 30, 100, 20);
- new TStatic(this, -1, "Result", 440, 30, 100, 20);
-
- Operand1 = new THistoryBox(this, IDC_OPERAND1, 20, 55, 100, 150,
- 0, 30);
- Operator = new TComboBox(this, IDC_OPERATOR, 160, 55, 100, 150,
- CBS_DROPDOWNLIST, 0);
- if (Operator)
- Operator->Attr.Style &= ~CBS_SORT;
- Operand2 = new THistoryBox(this, IDC_OPERAND2, 300, 55, 100, 150,
- 0, 30);
- Result = new THistoryBox(this, IDC_RESULT, 440, 55, 100, 150,
- 0, 30);
-
- new TStatic(this, -1, "Error Message", 20, 215, 100, 20);
- ErrMsg = new TEdit(this, IDE_ERRMSG, "", 20, 240, 560, 30);
-
- new TButton(this, IDB_CALC, "Calc", 20, 290, 80, 30);
- new TButton(this, IDB_EXIT, "Exit", 130, 290, 80, 30);
- }
-
- void TCalcJrWindow::SetupWindow()
- {
- TWindow::SetupWindow(); // Initialize the visual element
-
- // Fill up out Operator combo box with a variety
- // of operators for our users compuational pleasure.
- //
- if (Operator)
- {
- static char *p[] =
- { "+", "-", "*", "/", "^", "log", "exp", "sqrt", NULL };
- for (int ix = 0; p[ix]; ++ix)
- Operator->AddString(p[ix]);
- }
-
- // Keep the users out of the error box.
- //
- if (ErrMsg)
- ErrMsg->SetReadOnly(TRUE);
- }
-
- double get_number(TComboBox *numbox)
- {
- double rslt = 0; // default to 0
- char *str;
- int size;
-
- if (numbox)
- {
- str = new char[size = numbox->GetTextLen() + 1];
- if (str)
- {
- numbox->GetText(str, size);
- rslt = atof(str);
- delete str;
- }
- }
- return rslt;
- }
-
- void TCalcJrWindow::CmCalc()
- {
- double x, y, z = 0;
-
- x = get_number(Operand1);
- y = get_number(Operand2);
-
- if (Operator)
- {
- int ix = Operator->GetSelIndex();
- if (ix >= 0)
- {
- char *err = NULL;
-
- switch (ix)
- {
- case 0: // + operator
- z = x + y;
- break;
- case 1: // - operator
- z = x - y;
- break;
- case 2: // * operator
- z = x * y;
- break;
- case 3: // / operator
- if (y)
- z = x / y;
- else
- err = "Can't divide by zero.";
- break;
- case 4: // ^ operator
- if (x > 0)
- z = exp(y * log(x));
- else
- err = "Need positive number to raise power.";
- break;
- case 5: // log function
- if (x > 0)
- z = log(x);
- else
- err = "Need positive number for log.";
- break;
- case 6: // exp function
- if (x < 230)
- z = exp(x);
- else
- err = "Need a smaller number for exp.";
- break;
- case 7: // sqrt function
- if (x >= 0)
- z = sqrt(x);
- else
- err = "Can't do sqrt of negative number.";
- break;
- default:
- err = "Unknown operator";
- break;
- }
-
- if (ErrMsg)
- if (!err)
- ErrMsg->Clear();
- else
- ErrMsg->SetWindowText(err);
- if (!err && Result)
- {
- char dest[81];
- sprintf(dest, "%g", z);
- Result->SetWindowText(dest);
- Result->EvKillFocus(NULL); // Force history addition
- }
- }
- }
- }
-
- void TCalcJrWindow::CmExit()
- {
- SendMessage(WM_CLOSE);
- }
-
- class TCalcJrApp : public TApplication
- {
- public:
- TCalcJrApp() : TApplication()
- { nCmdShow = SW_SHOWMAXIMIZED; }
-
- void InitMainWindow()
- {
- SetMainWindow(new TFrameWindow( 0,
- "Son of Mr. Calulator",
- new TCalcJrWindow ));
- }
- };
-
- int OwlMain(int, char *[])
- {
- return TCalcJrApp().Run();
- }
-