Пример простого калькулятора на
MFC.
Зачем было
сделано
Посмотрел я как-то текст простого
калькулятора на Visual Basic и подумал, а как проще
сделать калькулятор без программирования каждой
клавиши отдельно. Естественно, используя классы.
Данная программа является скорее каркасом для
дальнейшей работы, чем полнофункциональным
калькулятором. Такой есть в Windows и писать нечто
подобное не имеет смысла. Но она может служить
примером использования класса для вывода в
диалоговое окно массива однотипных элементов, в
частности кнопок.
Что это такое
Калькулятор выполняет простые
арифметические действия и только. Однако,
добавить новые действия ничего не стоит. Нужно
лишь определить местоположение кнопки на экране
и обработчик данного действия в самом
калькуляторе. Как это сделать написано дальше.
Как это сделано.
За прорисовку и обработку нажатий
кнопок отвечает класс CButt, который наследуется из
библиотечного класса CButton. (Class
Wizard->AddClass->New->BaseClass->CButton)
В него добавляем структруру RECT для
задания местоположения кнопки.
// Generated message map functions
protected:
RECT rect;
И ссылку на родительское окно, для
последующей обработки
CCalcDlg * w_Parent;
//{{AFX_MSG(CButt)
afx_msg void OnClicked();
//}}AFX_MSG
Определяем метод OnClicked, ...
(ClassWizard->ClassName->CButt->Messages->=BN_CLICKED->AddFunction)
который занимается тем, что передает
в специальный обработчик вызывающего окна
заголовок кнопки...
void CButt::OnClicked()
{
CString Header;
GetWindowText(Header);
w_Parent->ObrNum(Header);
}
и переопределяем метод OnCreate(), который при
создании кнопки принимает заголовок кнопки,
ссылку на родительское окно и координату левого
верхнего угла. Сами кнопки квадратные, 40 пиксел
BOOL CButt::Create(LPCTSTR lpszWindowName,CWnd * wnd,UINT nID,UINT
top,UINT left)
{
rect.left=left;
rect.top=top;
rect.right=left+40;
rect.bottom=top+40;
w_Parent=(CCalcDlg *)wnd;
return CButton::Create(lpszWindowName, WS_CHILD |WS_VISIBLE, rect, wnd,
nID);
}
Изменим класс родительского окна
CalcDlg
class CCalcDlg : public CDialog
{
// Construction
public:
double Operation(); // обработка действий
void ObrNum(CString Num); // обработка нажатий
клавиш
CCalcDlg(CWnd* pParent = NULL); // standard
constructor
CButt m_btn[17]; // всего кнопок
..............
В код CCalcDlg::OnInitDialog() добавим
инициализацию кнопок
char buff[2];
buff[1]=0;
// создание и прорисовка числовых
кнопок
for (int i=0;i<10;i++){
m_btn[i].Create(itoa(i,buff,10),this,10000+i,i>4?90:45,15+(45*(i<5?i:i-5)));
}
// равно
m_btn[10].Create("=",this,10010,45*3,15+45*5);
// точка и другие действия
m_btn[11].Create(".",this,10011,45*3,15+45*0);
m_btn[12].Create("/",this,10012,45*3,15+45*1);
m_btn[13].Create("*",this,10013,45*3,15+45*2);
m_btn[14].Create("+",this,10014,45*3,15+45*3);
m_btn[15].Create("-",this,10015,45*3,15+45*4);
m_btn[16].Create("C",this,10016,45,15+45*5);
Определим обработку нажатия кнопки
void CCalcDlg::ObrNum(CString Num)
{
if (Num=="." && m_Num.Find('.')>=0){ // если
точка уже нажата, то не вводить
return;
}
if (Num=="C"){ // сброс
m_Num="";
m_Operation="";
UpdateData(FALSE);
UpdateWindow();
return;
}
CString PossibleOperation("/+-*"); // если
действие, то число и действие запоминаем и
сбрасываем табло
if (PossibleOperation.Find(Num)>=0){
m_BuffNum=atof(m_Num);
m_Num="";
m_Operation=Num;
UpdateData(FALSE);
UpdateWindow();
return;
}
double Buff=0;
if (Num=="="){ // равно -
обрабатываем, что получилось
Buff=Operation();
m_Num.Format("%f",Buff);
m_Operation="";
UpdateData(FALSE);
UpdateWindow();
return;
}
m_Num+=Num; // все остальное выводим на
табло
UpdateData(FALSE);
UpdateWindow();
}
Собственно действия
double CCalcDlg::Operation()
{
double Buff=0;
if (m_Operation=="+"){
Buff=m_BuffNum+atof(m_Num);
} else if (m_Operation=="-"){
Buff=m_BuffNum-atof(m_Num);
} else if (m_Operation=="/"
&& atof(m_Num)!=0){
Buff=m_BuffNum/atof(m_Num);
} else if (m_Operation=="*"){
Buff=m_BuffNum*atof(m_Num);
}
return Buff;
}
Запускаем и наслаждаемся нажатием
кнопочек. Однако, если действия вводятся с
клавиатуры, то они вместо выполнения
отображаются на табло. Но как этого избежать, как
нибудь в другой раз.
Теперь для того, чтобы добавить
новую кнопку, нужно:
- увеличить массив кнопок
m_btn[17]; до 18.
- добавить создание этой кнопки в OnInitDialog()
- добавить действие в CString
PossibleOperation("/+-*");
- добавить его обработку в CCalcDlg::Operation()
И будет работать.
Возможно это не самый лучший пример, но
главное - работающий
Программа
и полный исходный текст
Скачать: calc.zip
(105 Kb) программа.
Скачать: calc_src.zip
(38.5 Kb) исходные тексты к ней.
|