ООПиП (часть 3). Пример лабораторной работы №1
..pdfБГУИР: Дистанционное обучение (неофициальный сайт)
Министерство образования Республики Беларусь Учреждение образования
«Белорусский государственный университет информатики и радиоэлектроники»
Инженерно-экономический факультет Кафедра экономической информатики
Лабораторная работа №1: «Диалоговые окна»
Проверил: Огневая Татьяна Анатольевна
Выполнил: студент группы (дистанционная форма обучения) Wasja
Минск 2009
http://do.ucoz.net
БГУИР: Дистанционное обучение (неофициальный сайт)
1 Краткие теоретические сведения
В операционной среде Windows получить данные от пользователя приложение может через диалоговые окна. Приложение может иметь любое количество диалоговых окон, в которых происходит ввод данных пользователем.
Библиотека классов MFC содержит класс CDialog (наследованный от базового класса CWnd), специально предназначенный для управления диалоговыми панелями.
Диалоговые панели бывают двух типов - модальные и немодальные. Большинство диалоговых окон, которые приходится включать в состав приложения, относятся к так называемым модальным окнам. Модальное окно всегда выведено на экране поверх всех остальных окон приложения. Пользователь должен поработать в этом окне и обязательно закрыть его, прежде чем приступить к работе в любом другом окне этого же приложения. Немодальное диалоговое окно позволяет пользователю, не закончив работы с ним, работать в других окнах приложения, выполнить там необходимые действия, затем снова вернуться в немодальное окно и продолжить работу.
Как правило, для каждого диалогового окна в приложении необходимо разработать две вещи: ресурсы окна и класс окна.
Ресурсы окна используются программой для того, чтобы вывести на экран его изображение и изображения элементов управления, которые входят в него. Ресурсы диалога создаются посредством редактора ресурсов, с помощью которого возможно включать в его состав необходимые элементы управления и размещать их в необходимом порядке. К основным элементам управления Windows, используемым для построения диалога относяться:
−надпись (static text) – используется как поле для вывода надписи;
−текстовое поле (edit box) – может быть однострочным или многострочным; сюда пользователь может ввести текст;
−кнопка (button) – данный элемент предназначен для начала каких-либо действий после нажатия на неё;
−флажок (check box) – используется для установки опций, каждая из которых может быть выбрана независимо от других;
−переключатель-радиокнопка (radio button) – используется для выбора одной из групп связанных опций; если выбрана одна из них, то другие полагаются невыбранными;
−список (list box) – используется для выбора одного элемента из заранее подготовленного набора; набор может быть как жестко установленным на этапе разработки программы, так и меняться программно в процессе выполнения приложения; главное – пользователь по своей воле не может непосредственно менять элементы в наборе, он может только их выбирать;
−поле со списком (Combo box) – это комбинация текстового поля и списка; такой элемент управления позволяет пользователю не только выбирать элементы из ранее подготовленного набора, но и самостоятельно пополнять его, непосредственно внося необходимый текст в текстовое поле.
Поскольку каждое диалоговое окно в приложении является уникальным объектом, разработчику практически всегда нужно присваивать окнам и элемен-
http://do.ucoz.net |
2 |
БГУИР: Дистанционное обучение (неофициальный сайт)
там управления, входящим в их состав, идентификаторы по собственному выбору. Рекомендуется соблюдать соглашение о префиксах: идентификаторы диалоговых окон имеют префикс IDD_, а идентификаторы элементов управления – IDC_.
Как правило, класс диалогового окна в проекте является производным от класса CDialog, входящего в MFC. В класс окна включены переменные и функции, ответственные за работу диалога. Работая с диалоговой панелью, пользователь взаимодействует с органами управления - нажимает кнопки, вводит текст, выбирает элементы списков. В результате генерируются соответствующие сообщения, которые должны быть обработаны классом диалоговой панели. Так как класс диалоговой панели обрабатывает сообщения, то содержит таблицу сообщений и соответствующие методы-обработчики сообщений.
Обычно каждый элемент управления, включенный в состав ресурсов диалога, имеет в классе окна соответствующий член-переменную, ассоциированный с ним. Для того чтобы установить значения по умолчанию для элементов управления перед выводом окна на экран или считать состояние элементов управления после завершения работы пользователя, необходимо обращаться к членампеременным класса. Ассоциированная переменная класса диалогового окна соответствует либо значению - содержимому элемента управления, либо объекту класса соответствующего данному типу элемента управления. Типы переменных, которые могут быть ассоциированы с элементами управления по значению:
−текстовые поля – строковый тип CString, int, fIoat и long;
−кнопки – int;
−флажки – BOOL;
−переключатели – int;
−список – строковый тип;
−поле со списком – строковый тип CString;
−полоса прокрутки – int.
Для загрузки данных в ассоциированные по значению переменные исполь-
зуется метод UpdateData, определенный в классе CWnd. Необязательный параметр этой функции определяет, как будет происходить обмен данными:
−FALSE – выполняется инициализация диалоговой панели, информация из данных класса отображается в органах управления диалоговой панели;
−TRUE – из органов управления диалоговой панели данные копируются в
соответствующие элементы данных класса диалоговой панели.
Метод UpdateData возвращает ненулевое значение, если обмен данными прошел успешно, и нуль в противном случае. Ошибка при обмене данными может произойти, если пользователь ввел неправильные данные, отвергнутые процедурой автоматической проверки данных.
Чтобы создать модальную диалоговую панель, сначала необходимо создать объект определенного в приложении класса диалоговой панели, а затем вызвать метод DoModal, определенный в классе CDialog.
При создании модальной диалоговой панели перед тем, как панель появится на экране, вызывается виртуальный метод OnInitDialog класса CDialog. По умолчанию OnInitDialog вызывает метод UpdateData и выполняет инициализацию органов управления.
http://do.ucoz.net |
3 |
БГУИР: Дистанционное обучение (неофициальный сайт)
2 Задание
Разработать приложение (с использованием диалоговых окон), реализующее калькулятор. Приложение должно иметь строку редактирования, набор кнопок 0…9, кнопки арифметических действий – суммирование, вычитание, деление, умножение. Результат отображать в статическом поле. Предусмотреть возможность управления калькулятором с помощью клавиш клавиатуры.
3 Выполнение работы
3.1 Разработка алгоритма программы
Исходя из задания, работу приложения можно охарактеризовать с помощью 5 внутренних состояний:
−состояние 0 – в строке ввода находиться неизменное число, операция не определена;
−состояние 1 – в строке ввода находиться изменяемое число, операция не определена;
−состояние 2 – в строке ввода находиться неизменное число, в памяти храниться число, операция определена;
−состояние 3 – в строке ввода находиться изменяемое число, в памяти храниться число, операция определена;
−состояние 4 – в строке ввода неизменяемое число, в памяти храниться чис-
ло и предыдущее введенное число, операция определена.
Взаимосвязь состояний между собой можно представить в виде графсхемы и условия перехода:
=, CE, C
=,C
0
|
число, <-, CE |
операция, CE число, <-, CE |
||||||||||
|
|
|
|
|
1 |
|
операция |
2 |
число |
3 |
||
|
|
|
|
|
|
|
|
|
||||
сло |
|
|
|
а |
|
я |
|
|
|
операция |
|
|
|
|
|
|
|
|
|
|
|
||||
|
|
|
|
|
|
и |
|
|
|
|
|
|
чи |
о |
|
р |
ц |
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
||||
|
|
е |
|
|
|
|
|
|
|
|
|
|
|
п |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
C |
|
|
|
|
|
C4
=, CE
C
Рисунок 3.1 – Граф-схема алгоритма
Как можно видеть из приведенной граф-схемы, условием изменения состояния является нажатие соответствующей кнопки, которые по функциональным особенностям можно подразделить на следующие группы:
− «число» – сюда относятся цифровые кнопки «0»…«9», кнопка изменения знака «+/-» и кнопка ввода разделителя разрядов «.»;
http://do.ucoz.net |
4 |
БГУИР: Дистанционное обучение (неофициальный сайт)
−«операция» - сюда относиться кнопки арифметических действий: суммирование «+», вычитание «-», деление «/», умножение «*»;
−«равно» - сюда относиться кнопка выполнения вычислений «=».
Кроме того, для удобства работы необходимо ввести поддержку служебных кнопок, а именно:
−кнопка отмены последней введенной цифры «<-»;
−кнопка сброса введенного числа «СЕ»;
−кнопка сброса «С».
Дополнительно необходимо предусмотреть контроль возникновения ошибок при выполнении арифметических операций.
Используя вышеприведенную граф-схему можно разработать более детальные блок-схемы алгоритмов работы отдельных функций программы:
Рисунок 3.2 – Блок-схемы алгоритмов: а) функции удаления последней введенной цифры; б) функции сброса; в) функции сброса введенного числа
http://do.ucoz.net |
5 |
БГУИР: Дистанционное обучение (неофициальный сайт) |
||||
а) |
Начало |
|
|
|
|
Была ошибка? |
да |
|
|
|
|
|
||
|
нет |
|
|
|
2 |
1, 3 |
да |
Присвоить полю |
|
state = 3 |
Состояние (state) |
Введено "0"? |
ввода значение |
|
|
|
|
введенной цифры |
|
|
0, 4 |
нет |
|
|
Присвоить полю |
|
нет |
Дописать в поле |
|
state = 1 |
Кол-во цифр |
ввода введенную |
||
ввода значение "0" |
максимально? |
|||
|
цифру |
|||
|
|
|
||
|
|
да |
|
|
|
|
Сброс выделения |
|
|
|
|
в поле ввода |
|
|
|
Конец |
|
|
б) |
Начало |
|
|
|
|
Была ошибка? |
да |
|
|
|
|
|
||
|
нет |
|
|
|
|
2 |
1, 3 |
да |
|
state = 3 |
Состояние (state) |
Введено "0"? |
||
|
||||
|
0, 4 |
нет |
|
|
|
|
|
нет |
|
Присвоить полю |
state = 1 |
Знак числа "-"? |
Добавить знак в |
|
ввода значение "0" |
поле ввода |
|||
|
|
|||
|
|
да |
|
|
|
Сброс выделения |
|
Убрать знак в поле |
|
|
в поле ввода |
|
ввода |
|
|
Конец |
|
|
|
в) |
Начало |
|
|
|
|
Была ошибка? |
да |
|
|
|
|
|
||
|
нет |
|
|
|
|
2 |
1, 3 |
да |
|
state = 3 |
Состояние (state) |
Точка уже |
||
введена? |
|
|||
|
|
|
||
|
0, 4 |
нет |
|
|
Присвоить полю |
|
Кол-во цифр |
нет |
|
ввода значение |
state = 1 |
Дописать в поле |
||
максимально? |
ввода "." |
|||
"0." |
|
|||
|
|
|
||
|
|
да |
|
|
|
|
Сброс выделения |
|
|
|
|
в поле ввода |
|
Конец
Рисунок 3.3 – Блок-схемы алгоритмов: а) функции ввода цифры; б) функции изменения знака; в) функции добавления точки
http://do.ucoz.net |
6 |
|
|
БГУИР: Дистанционное обучение (неофициальный сайт) |
|
||
|
а) |
Начало |
|
|
|
|
|
Была ошибка? |
да |
|
|
|
|
|
|
|
|
|
|
нет |
|
|
|
|
|
3 |
2 |
|
нет |
ДописатьПрвоитьчислополюиз |
|
Состояние (state) |
Заменить |
Ошибка? |
state = 2 |
ввподаля вводазначениев лог"0" |
|
операцию в логе |
|||
|
|
|
|
||
|
|
0,1,4 |
|
да |
|
|
|
ДопиПрсвоитьатьчислополюиз |
Запомнить число |
|
|
|
|
ДопПрисвоитьатьчислополюиз |
state = 0 |
Вывод лога |
|
ввподаля вводазначениев лог"0" |
|
ввподаля вводазначениев лог"0" |
из поля ввода в |
||
|
ввподаля вводазначениев лог"0" |
|
|
||
|
|
|
numb |
|
|
Записать |
|
Вывод результата |
|
|
Сброс выделения |
Присвоить полю |
|
|
|
||
результат |
|
вычислений |
|
|
в поле ввода |
ввода значение "0" |
|
|
|
||
операции в numb |
|
|
|
|
|
|
б) |
Начало |
|
|
Конец |
|
|
Была ошибка? |
да |
|
|
|
|
|
|
|
|
|
|
нет |
|
|
|
Запомнить число |
2, 3 |
4 |
Вывод результата |
|
|
из поля ввода в |
|
Состояние (state) |
ДопПрисвоитьДопатьсатьчислополюиз |
|
|
|
ввпоперациюдаля вводазначениеввлог"0" |
вычислений |
|
||
numb_d |
|
|
|
||
|
|
|
|
|
|
|
|
0,1 |
|
|
|
Выполнить |
|
Запомнить число |
ДописаатьПрисвоитьnumbчислополюdизв |
|
|
Присвоить полю |
|
Присвоить полю |
Вывод лога |
|
|
операцию над |
|
из поля ввода в |
ввподаля вводазначениелогв лог"0" |
|
|
ввода значение "0" |
|
ввода значение "0" |
|
|
|
numb и numb_d |
|
numb |
|
|
|
Записать |
|
ДопиПрисвоитьатьчислополюиз |
Выполнить |
|
нет |
Присвоить полю |
|
Присвоить полю |
Ошибка? |
|
|
результат |
|
ввподаля вводазначениев лог"0" |
операцию над |
|
|
ввода значение "0" |
|
ввода значение "0" |
|
|
|
операции в numb |
|
|
numb и numb_d |
|
|
|
|
|
|
да |
|
ДописатьПрвоитьчислополюиз |
|
|
Записать |
|
|
|
state = 0 |
Присвоить полю |
state = 0 |
|
|
ввподаля вводазначениев лог"0" |
|
результат |
|
||
|
|
ввода значение "0" |
|
|
|
|
|
|
операции в numb |
|
|
state = 4 |
|
|
|
Сброс выделения |
|
|
|
|
в поле ввода |
|
|
|
|
|
|
|
Конец
Рисунок 3.4 – Блок-схемы алгоритмов: а) функции обработки нажатия кнопок операций; б) функции обработки нажатия кнопки «равно»
3.2 Исходные тексты программы
3.2.1Заголовок класса Lab3_1Dlg (Lab3_1Dlg.h)
//Заголовок класса Lab3_1Dlg
#pragma once #include "afxwin.h" #include "Winuser.h" #include <vector>
enum SM { state_0 = 0, state_1 = 1, state_2 = 2, state_3 = 3, state_4 = 4 }; // Состояния работы калькулятора
const char PointChar = '.';
http://do.ucoz.net |
7 |
БГУИР: Дистанционное обучение (неофициальный сайт)
// Разделитель целой и дробной части числа
class CLab3_1Dlg : public CDialog
// Класс диалогового окна CLab3_1Dlg
{
public:
CLab3_1Dlg(CWnd* pParent = NULL);
//Стандартный конструктор
protected:
enum { IDD = IDD_LAB3_1_DIALOG };
//Данные диалога
HICON m_hIcon;
//Иконка диалога
CEdit m_edit;
//Поле ввода
CStatic m_static;
//Статическое поле
virtual |
void |
DoDataExchange( CDataExchange* pDX ); |
// Поддержка |
DDX/DDV |
|
virtual |
BOOL |
OnInitDialog(); |
//Обработчик инициализации диалога
BOOL PreTranslateMessage( MSG* pMsg );
//Обработчик сообщений
DECLARE_MESSAGE_MAP()
// Функция генерации карты сообщений
/* ========================== */ /* Обработчики нажатия кнопок */ afx_msg void OnBnClickedButton0(); afx_msg void OnBnClickedButton1(); afx_msg void OnBnClickedButton2(); afx_msg void OnBnClickedButton3(); afx_msg void OnBnClickedButton4(); afx_msg void OnBnClickedButton5(); afx_msg void OnBnClickedButton6(); afx_msg void OnBnClickedButton7(); afx_msg void OnBnClickedButton8(); afx_msg void OnBnClickedButton9();
afx_msg void OnBnClickedButtonSign(); afx_msg void OnBnClickedButtonPoint(); afx_msg void OnBnClickedButtonBack(); afx_msg void OnBnClickedButtonClear(); afx_msg void OnBnClickedButtonClearEnd(); afx_msg void OnBnClickedButtonDiv(); afx_msg void OnBnClickedButtonMul(); afx_msg void OnBnClickedButtonSub(); afx_msg void OnBnClickedButtonAdd(); afx_msg void OnBnClickedButtonReturn(); /* ========================== */
void AddChar( const char );
//Функция добавления цифры void AddCommand( const char );
//Функция добавления операции void PrintList();
//Вывод лога выполнения операций void PrintResult( const double );
//Вывод результата вычислений void FocusEdit();
//Сброс выделения в поле ввода, установка фокуса double exec( const char, const double, const double );
//Функция выполнения операции
static const int max_text = 22;
//Длина вводимого числа: 20 - цифры, 1 - знак, 1 - точка std::vector<CString> n_c_list;
//Лог выполнения операций
http://do.ucoz.net |
8 |
БГУИР: Дистанционное обучение (неофициальный сайт)
double numb;
//Данные double numb_d;
//Предыдущие данные char comm;
//Операция
SM state;
//Автомат состояний
BOOLEAN EndError;
//Флаг ошибки при выполнении последней операции
};
3.2.2Реализация класса Lab3_1Dlg (Lab3_1Dlg.cpp)
//Реализация класса Lab3_1Dlg
#include "stdafx.h" #include "Lab3_1.h" #include "Lab3_1Dlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW #endif
CLab3_1Dlg::CLab3_1Dlg( CWnd* pParent )
:CDialog( CLab3_1Dlg::IDD, pParent )
//Стандартный конструктор
{
m_hIcon = AfxGetApp()->LoadIcon( IDR_MAINFRAME );
}
void CLab3_1Dlg::DoDataExchange( CDataExchange* pDX ) // Поддержка DDX/DDV
{
CDialog::DoDataExchange( pDX ); DDX_Control( pDX, IDC_EDIT, m_edit ); // Связь поля ввода с переменной m_edit
DDX_Control( pDX, IDC_STATIC_TEXT, m_static ); // Связь статического поля с переменной m_static
}
// CLab3_1Dlg message handlers
BOOL CLab3_1Dlg::OnInitDialog()
// Обработчик инициализации диалога
{
CDialog::OnInitDialog();
//Вызов стандартного обработчика родительского класса
SetIcon( m_hIcon, TRUE );
//Задание "большой" иконки программы
SetIcon( m_hIcon, FALSE );
//Задание "малой" иконки программы m_edit.SetWindowText( "0" );
//Задание первоначального значения поля ввода
FocusEdit();
//Сброс выделения в поле ввода, установка фокуса
EndError = FALSE;
//Сброс флага ошибки
state = state_0;
//Установка начального состояния return FALSE;
//Установлен фокус
}
BEGIN_MESSAGE_MAP(CLab3_1Dlg, CDialog)
http://do.ucoz.net |
9 |
БГУИР: Дистанционное обучение (неофициальный сайт)
// Функция генерации карты сообщений
ON_BN_CLICKED( IDC_BUTTON_0, OnBnClickedButton0 )
ON_BN_CLICKED( IDC_BUTTON_1, OnBnClickedButton1 )
ON_BN_CLICKED( IDC_BUTTON_2, OnBnClickedButton2 )
ON_BN_CLICKED( IDC_BUTTON_3, OnBnClickedButton3 )
ON_BN_CLICKED( IDC_BUTTON_4, OnBnClickedButton4 )
ON_BN_CLICKED( IDC_BUTTON_5, OnBnClickedButton5 )
ON_BN_CLICKED( IDC_BUTTON_6, OnBnClickedButton6 )
ON_BN_CLICKED( IDC_BUTTON_7, OnBnClickedButton7 )
ON_BN_CLICKED( IDC_BUTTON_8, OnBnClickedButton8 )
ON_BN_CLICKED( IDC_BUTTON_9, OnBnClickedButton9 ) ON_BN_CLICKED( IDC_BUTTON_Sign, OnBnClickedButtonSign ) ON_BN_CLICKED( IDC_BUTTON_Point, OnBnClickedButtonPoint ) ON_BN_CLICKED( IDC_BUTTON_Back, OnBnClickedButtonBack ) ON_BN_CLICKED( IDC_BUTTON_Clear, OnBnClickedButtonClear ) ON_BN_CLICKED( IDC_BUTTON_ClearEnd, OnBnClickedButtonClearEnd ) ON_BN_CLICKED( IDC_BUTTON_Div, OnBnClickedButtonDiv ) ON_BN_CLICKED( IDC_BUTTON_Mul, OnBnClickedButtonMul ) ON_BN_CLICKED( IDC_BUTTON_Sub, OnBnClickedButtonSub ) ON_BN_CLICKED( IDC_BUTTON_Add, OnBnClickedButtonAdd ) ON_BN_CLICKED( IDC_BUTTON_Return, OnBnClickedButtonReturn )
END_MESSAGE_MAP()
/* =================================== */ /* Обработчики нажатия цифровых кнопок */
void CLab3_1Dlg::OnBnClickedButton0() { AddChar( '0' ); } void CLab3_1Dlg::OnBnClickedButton1() { AddChar( '1' ); } void CLab3_1Dlg::OnBnClickedButton2() { AddChar( '2' ); } void CLab3_1Dlg::OnBnClickedButton3() { AddChar( '3' ); } void CLab3_1Dlg::OnBnClickedButton4() { AddChar( '4' ); } void CLab3_1Dlg::OnBnClickedButton5() { AddChar( '5' ); } void CLab3_1Dlg::OnBnClickedButton6() { AddChar( '6' ); } void CLab3_1Dlg::OnBnClickedButton7() { AddChar( '7' ); } void CLab3_1Dlg::OnBnClickedButton8() { AddChar( '8' ); } void CLab3_1Dlg::OnBnClickedButton9() { AddChar( '9' ); } /* =================================== */
void CLab3_1Dlg::AddChar( const char C ) // Функция добавления цифры
{
if (EndError) { FocusEdit(); return; } // Пока ошибка - нет изменений
char txt [ max_text+1 ];
if ((state == state_0) || (state == state_2) || (state == state_4))
//Если состояние 0, 2 или 4 - присвоить значение цифры
{
txt[ 0 ] = C; txt[ 1 ] = '\0';
m_edit.SetWindowText( txt );
if ((state == state_0) || (state == state_4)) state = state_1; else state = state_3;
}
else
//Если состояние 1 или 3
{
m_edit.GetWindowText( txt, max_text+1 ); size_t serv = 0;
if (txt[0] != '-') serv += 1;
if (strchr( txt, PointChar ) == NULL) serv += 1; if (strcmp( txt, "0" ) == 0)
// Если введен "0" - присвоить значение цифры
{
txt[ |
0 |
] |
= |
C; |
|
txt[ |
1 |
] |
= |
'\0'; |
|
m_edit.SetWindowText( txt ); |
|
||||
|
|
|
http://do.ucoz.net |
10 |