На этом шаге мы рассмотрим простейший калькулятор.
Юлия Мяготина, студентка 4 курса факультета математики и информационных технологий Курганского государственного университета (декабрь 2005 г.) разработала простейший калькулятор, который должен выполнять 4 арифметических действия, которые выбираются из группы радиокнопок. Калькулятор имеет кнопку "Очистить", нажатие на которую осуществляет очистку 3 полей редактирования, содержащих соответственно 2 числа и результат операции. При выполнении деления на ноль должно появляться диалоговое окно с соответствующим сообщением.
Для реализации этого проекта было создано главное окно со следующими управляющими элементами: 3 строки редактирования, 4 радиокнопки и кнопка "Очистить".
Первые два поля редактирования предназначены для ввода чисел, выбор необходимых арифметических действий осуществляется с помощью группы радиокнопок. При выборе соответствующего действия результат помещается в 3-ю строку. Щелчок по кнопке "Очистить" приводит к очистке 3-х полей редактирования и установке курсора в первую строку. Также в окне возможно переключение между строками при помощи клавиши TAB (конструкция EnableKBHandler()).
В программе предусмотрены следующие ограничения:
Эти возможности реализованы с помощью функции MessageBox().
Также в программе осуществлен контроль вводимых пользователем данных. Для этого в конструкторе главного окна создается управляющий объект OWL для каждого управляющего элемента главного окна. Данную проверку можно осуществить так:
str1 = new TEdit(this, ID_STR1,"",10,26,60,25,10); valid = new TFilterValidator("-0-9."); str1->SetValidator(valid); str2 = new TEdit(this, ID_STR2,"",110,26,60,25,10); str2->SetValidator(valid);
Используемый класс TFilterValidator позволяет пользователю вводить только цифры, знак "-" и "." - это относится к первым двум полям редактирования, для третьей строки предусмотрена защита от ввода любых символов:
str3 = new TEdit(this, ID_STR3,"",195,26,60,25,10); valid = new TFilterValidator(""); str3->SetValidator(valid);
Рассмотрим принципы работы программы. Остановимся подробнее на функции, в которой реализовано умножение 2-х чисел (функция CmMul()).
Для правильной работы данной программы необходимо первоначально очистить 3-ю строку редактирования, иначе результат будет добавляться к уже имеющемуся там:
str3->Clear();
Далее в переменные s1 и s2 помещается содержимое 1-го и 2-го полей редактирования, затем значения строк s1 и s2 переводятся в числа и выполняется соответствующее арифметическое действие. Следующим шагом является перевод полученного числа в строку и помещение его в третье поле.
Конструкция:
str3->Insert(s3);
помещает строку s3 в поле результата.
Аналогичные конструкции осуществляются в 3-х остальных функциях CmDiv(), CmPlus(), CmVich(), разница заключается в арифметических операциях, производимых над числами. Только в функции CmDiv() добавлена проверка на ноль во второй строке редактирования.
Особенностью данной задачи является задание цвета фона окна при помощи функции SetBkgndColor().
Текст приложения:
#include <owl\applicat.h> #include <owl\framewin.h> #include <owl\edit.h> #include <owl\dc.h> #include <owl\groupbox.h> #include <owl\radiobut.h> #include <stdlib.h> #include <owl\validate.h> #include <math.h> #include "pr74_1.rc" class TApp : public TApplication { public : TApp() : TApplication() {}; void InitMainWindow(); }; class TWndw : public TFrameWindow { public : TWndw(TWindow *parent, const char far *title); protected : TEdit *str1,*str2,*str3; TRadioButton *r1,*r2,*r3,*r4; BOOL CanClose(); DECLARE_RESPONSE_TABLE(TWndw); void SetupWindow(); void CmMul(); void CmDiv(); void CmPlus(); void CmVich(); void CmClear(); }; DEFINE_RESPONSE_TABLE1(TWndw,TFrameWindow) EV_COMMAND(CM_CLEAR,CmClear), EV_COMMAND(ID_MUL,CmMul), EV_COMMAND(ID_DIV,CmDiv), EV_COMMAND(ID_PLUS,CmPlus), EV_COMMAND(ID_VICH,CmVich), END_RESPONSE_TABLE; TWndw::TWndw(TWindow *parent, const char far *title): TFrameWindow(parent, title) { TValidator *valid; Attr.X=50; Attr.Y=50; Attr.W=270; Attr.H=150; EnableKBHandler(); str1=new TEdit(this, ID_STR1,"",10,26,60,25,10); valid=new TFilterValidator("-0-9."); str1->SetValidator(valid); str2=new TEdit(this, ID_STR2,"",110,26,60,25,10); str2->SetValidator(valid); str3=new TEdit(this, ID_STR3,"",195,26,60,25,10); valid=new TFilterValidator(""); str3->SetValidator(valid); new TButton(this,CM_CLEAR,"Очистить",80,75,71,25); r1 = new TRadioButton(this,ID_MUL,"х",79,10,23,10,0); r2 = new TRadioButton(this,ID_DIV,"/",79,24,23,10); r3 = new TRadioButton(this,ID_PLUS,"+",79,38,23,10); r4 = new TRadioButton(this,ID_VICH,"-",79,52,23,10); new TStatic(this,-1," =",175,28,15,15,1); } void TWndw::SetupWindow() { TFrameWindow::SetupWindow(); } BOOL TWndw::CanClose() { int result=MessageBox("Закрыть?","Сообщение",MB_YESNO|MB_ICONQUESTION); if (result==IDYES) return TRUE; else return FALSE; } void TWndw::CmMul() { char *s1,*s2,*s3; double k; str3->Clear(); s1=new char[10]; s2=new char[10]; s3=new char[10]; str1->GetLine(s1,10,1); str2->GetLine(s2,10,1); if (strlen(s1) && strlen(s2)) { k = atof(s1)*atof(s2); gcvt(k,9,s3); str3->Insert(s3); } else { MessageBox("Данные введены не все!","Предупреждение", MB_ICONEXCLAMATION); } delete [] s1; delete [] s2; delete [] s3; } void TWndw::CmDiv() { char *s1,*s2,*s3; double k; str3->Clear(); s1=new char[10]; s2=new char[10]; s3=new char[10]; str1->GetLine(s1,10,2); str2->GetLine(s2,10,2); if (strlen(s1) && strlen(s2)) { if (atof(s2)!=0) { k = atof(s1)/atof(s2); gcvt(k,9,s3); str3->Insert(s3); } else { MessageBox("Делить на ноль нельзя!","Предупреждение", MB_ICONEXCLAMATION); //str2->Clear(); } } else { MessageBox("Данные введены не все!","Предупреждение", MB_ICONEXCLAMATION); } delete [] s1; delete [] s2; delete [] s3; } void TWndw::CmPlus() { char *s1,*s2,*s3; double k; str3->Clear(); s1=new char[10]; s2=new char[10]; s3=new char[10]; str1->GetLine(s1,10,1); str2->GetLine(s2,10,1); if (strlen(s1) && strlen(s2)) { k = atof(s1)+atof(s2); gcvt(k,9,s3); str3->Insert(s3); } else { MessageBox("Данные введены не все!","Предупреждение", MB_ICONEXCLAMATION); } delete [] s1; delete [] s2; delete [] s3; } void TWndw::CmVich() { char *s1,*s2,*s3; double k; str3->Clear(); s1=new char[10]; s2=new char[10]; s3=new char[10]; str1->GetLine(s1,10,1); str2->GetLine(s2,10,1); if (strlen(s1) && strlen(s2)) { k = atof(s1)-atof(s2); gcvt(k,9,s3); str3->Insert(s3); } else { MessageBox("Данные введены не все!","Предупреждение", MB_ICONEXCLAMATION); } delete [] s1; delete [] s2; delete [] s3; } void TWndw::CmClear() { str1->Clear(); str2->Clear(); str3->Clear(); str1->SetFocus(); } void TApp::InitMainWindow() //TWindow { TWndw *wndw=new TWndw(0," Калькулятор"); wndw->SetBkgndColor(13409000); SetMainWindow(wndw); } int OwlMain(int, char* []) { return TApp().Run(); }
Файл ресурсов:
#ifndef WORKSHOP_INVOKED #include "windows.h" #endif #include <owl\window.rh> #define CM_CLEAR 101 #define ID_MUL 102 #define ID_DIV 103 #define ID_PLUS 104 #define ID_VICH 105 #define ID_STR1 106 #define ID_STR2 107 #define ID_STR3 108
Результат работы приложения изображен на рисунке 1:
Рис.1. Результат работы приложения
На следующем шаге мы рассмотрим еще одно приложение, разработанное с использованием OWL.