Шаг 74.
Библиотека OWL.
Создание простейшего калькулятора

    На этом шаге мы рассмотрим простейший калькулятор.

    Юлия Мяготина, студентка 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.




Предыдущий шаг Содержание Следующий шаг