C++ Builder XE Простой калькулятор-01

//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
// Глобальная переменная number1 для хронения первой цифры
UnicodeString number1;
// Глобальная переменная number2 для хронения второй цифры
UnicodeString number2;
// Глобальная переменная znak для хронения арефметического действия
UnicodeString znak;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
/*
Конкатенация (склеивание, сложение) строки
находящейся в свойстве Label1->Caption сострокой находящейся в
свойстве Button->Caption той кнопки какая будет нажата
так мы набираем нужную нам строку цифр.
Обратите внимание что для кнопок Button1 - Button9 и Button11 и Label1
в инспекторе объектов на вкладке Events для события OnClick
назначен обработчик (метод) Button1Click.
Button1Click это метод (обработчик) класса TForm1 очём свидетельствует
строка TForm1::Button1Click тоесть обработчик (метод) Button1Click
класса TForm1 можно назначить (связать) с любым компанентом (объектом)
расположенном на (форме) Form1 и имеющем событие OnClick.
Теперь обработчик (метод) Button1Click будет сробатывать при нажати
любой из 10 кнопок а также при щелчке на Label1
Встаёт вопрос как теперь узнать какая кнопка или может быть Label1 вызвали срабатывание
обработчика (метода) Button1Click.
Взглянем на параметры обработчика Button1Click(TObject *Sender)
Sender это указатель на объект класса TObject.
TObject это базовый класс всех компанентов "С++Builder" и TButton тоже наследник TObject
смотрите иерархию классов.
Возьмём объект (экземпляр) Button2 при нажати на неё возникает событие OnClick связонное с
обработчиком Button1Click при этом объект (экземпляр) Button2 передаёт свой указатель
Sender в обработчик Button1Click в качестве параметра.
Почему Sender объявлен как указатель на базовый класс TObject.
Да потомучто указатель Sender присутствует в любом компаненте "С++Builder" так как все
компаненты "С++Builder" произведены от класса TObject.
а зделано всё это для того чтоб привязать один обраюотчик к событиям разных компанентов
и не только одного вида Button1->OnClick, Button2->OnClick, но и допустим Label->OnDbClick,
Button3->OnEnter все эти события передают в обработчик только один параметр указатель Sender
типа TObject поэтому их можно связать с обработчиком Button1Click тоже имеющим один параметр
Sender типа TObject
Существуют события которые передают кроме параметра TObject *Sender и другие параметры
например (TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y)
это параметры события OnMouseDown компанента Label или Button и других
такие события связываются с обработчиком имеющим точно такиеже параметры.
Вернёмся к Sender. Попробуйте в обработчике TForm1::Button1Click
сделать Sender-> откроется окно подсказчика кода взгляните на те функции которые там перечислены
все они объявлены в классе TObject здесь вы не найдёте свойство Caption или Width что делать?
Нужно указатель Sender привести к типу TButton и тогда все свойства и методы класса TButton
будут доступны.
Приведение типов в стиле языка "С" ((TButton*) Sender)->Caption; (скобочное приведение)
является статическим приведением выполняется в момент компиляции программы.
static_cast<TControl*>(Sender); новый стиль статического приведения типов тоже
самое что и предыдущее применяется в замен него, только более понятно и читабельно
dynamic_cast<TButton*>(Sender); динамическое приведение типов выполняется в
момент вылолнения программы использует RTTI работает медленее чем статическое приведение
если приведение не возможно возращает ноль.
В нашем случае нужно применить static_cast<TButton*>(Sender);
Потому что обработчик Button1Click срабатывает только от кнопок но так как я намеренно
связал обработчик Button1Click с событием Label->OnClick то применил динамическое приведение
dynamic_cast<TButton*>(Sender);
как видно из кода сначало Sender приводится к типу TControl.
чтобы узнать имя компанента (объекта) далее делается попытка динамического приведения
к типу TButton если возможно то ShowMessage("Кнопка-" + str); узнаём имя кнопки
инициатора срабатывания обработчика.
если был щелчек по Label1 то идёт if(ptButton == NULL) { ShowMessage("Не кнопка а-" + str); return; }
*/
void __fastcall TForm1::Button1Click(TObject *Sender)
{
//Sender->
//Label1->Caption = Label1->Caption + ((TButton*) Sender)->Caption;
TControl* ptContr;
ptContr = static_cast<TControl*>(Sender);
UnicodeString str = ptContr -> Name;
TButton* ptButton;
ptButton=dynamic_cast<TButton*>(Sender);
if(ptButton == NULL) { ShowMessage("Не кнопка а-" + str); return; }
ShowMessage("Кнопка-" + str);
Label1->Caption = Label1->Caption + ptButton->Caption;
}
//---------------------------------------------------------------------------
//--Если была сделана ошибка при наборе цифры
//--очищяем её тоесть свойству Label1->Caption присваиваем пустую строку
void __fastcall TForm1::Button10Click(TObject *Sender)
{
Label1->Caption = "";
}
//----------------------------------------------------------------------------
/*
Вводим знак операции над цифрами
Присваиваем (копируем) строку в свойстве Label1->Caption в переменную
number1 первая строка цифр сформирована и готова к использованию
очищяем свойство Label1->Caption подготавливая его к вводу вторй строки цифр
*/
void __fastcall TForm1::Button13Click(TObject *Sender)
{
znak = "+";
number1 = Label1->Caption;
Label1->Caption = "";
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button14Click(TObject *Sender)
{
znak = "-";
number1 = Label1->Caption;
Label1->Caption = "";
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button15Click(TObject *Sender)
{
znak = "*";
number1 = Label1->Caption;
Label1->Caption = "";
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button16Click(TObject *Sender)
{
znak = "/";
number1 = Label1->Caption;
Label1->Caption = "";
}
//---------------------------------------------------------------------------
/*
Подсчитываем результат и выводим в метку----------------------------
Присваиваем (копируем) строку в свойстве Label1->Caption в переменную
number2 вторая строка цифр сформирована и готова к использованию
Если переменные number1, number2, znak не пустые строки (!= "") то
в них содержатся первая,вторая строка цифр и орефметический знак и
значит можно переходить к вычислениям
если переменная znak равна (==) литеральной константе "+" то будем складывать
//--Сначяло строка цифр number2 преобразуется в целое число с помощью функции
StrToInt(number2); далее идёт преобразование StrToInt(number1);
после этого идёт сложение целых чисел и наконец результат присваиваеися
свойству Label1->Caption мы видим результат
здесь есть один нюанс Label1->Caption имеет тип UnicodeString а мы иму
присваиваем целое число типа int здесь моглабы быть ошибка но кимпилятор
сам способен сделать преобразование типов по этому ошибки не возникает (пример не явного преобразования
типов)
обратное преобразование int в UnicodeString кимпилятор неделает
*/
void __fastcall TForm1::Button12Click(TObject *Sender)
{
number2 = Label1->Caption;
if(number1 != "" & number2 != "" & znak != ""){
if(znak == "+"){Label1->Caption = StrToInt(number1) + StrToInt(number2); }
if(znak == "-"){Label1->Caption = StrToInt(number1) - StrToInt(number2); }
if(znak == "*"){Label1->Caption = StrToInt(number1) * StrToInt(number2); }
if(znak == "/"){Label1->Caption = StrToInt(number1) / StrToInt(number2); }
number2 = "";
znak = "";
number1 = Label1->Caption;
return;
}
number2 = "";
znak = "";
number1 = "";
Label1->Caption = "";
ShowMessage("Не достаточно данных повторите ввод сначала");
}
//---------------------------------------------------------------------------
=================================================
|