Интерфейс и реализация классов




class TObject

{

protected:

CString _name; //В связи с использованием MFC, тип поля _name переведён из char* в CString

public:

TObject();

TObject(CString name);

virtual ~TObject();

 

CString GetName();

void SetName(CString name);

 

virtual CString Show() = 0; //Переделан вызов метода "отобразить свойства", который теперь возвращает строку

};

 

TObject::TObject()

{

}

 

TObject::~TObject()

{

}

 

TObject::TObject(CString name)

{

_name = name;

}

 

CString TObject::GetName()

{

return _name;

}

 

void TObject::SetName(CString name)

{

_name = name;

}

 

Реализация остальных классов осталась такой же за исключением изменения возвращаемого значения методом Show() и заменой сигнатуры конструктора с параметрами, например, с Worker(char* name, int age, int workExp) на Worker(CString name, int age, int workExp).

При реализации интерфейса пришлось добавить следующую структуру:

struct ObjWithOwner

{

CString _owner; //Поле, которое обозначает, кому "подчиняется" данный объект

TObject* _obj; //Указатель на объект базового класса

int _id; //Используется для нахождения элемента в массиве через ListView

};

 

Реализация интерфейса программы относится к двум основным окнам:

Главное окно программы (которое создаётся и вызывается первым):

 

Для начала изменяется код метода OnInitDialog:

BOOL Clab51Dlg::OnInitDialog()

{

CDialogEx::OnInitDialog();

 

……………………………………………

 

lst.InsertColumn(0, L"Описание", LVCFMT_LEFT, 400); // Добавление заголовков в объект ListView

 

lst.InsertColumn(1, L"Подчиняется", LVCFMT_LEFT, 150);

 

……………………………………………………………

}

 

void Clab51Dlg::AddObj(ObjWithOwner obj) //Метод добавления объекта в список

{

ObjWithOwner* temp = new ObjWithOwner[_itemsCount + 1]; //Создаём новый массив размером на 1 больше, чем был

for (int i = 0; i < _itemsCount; ++i) //Переписываем в него элементы из предыдущего массива

{

temp[i] = _arr[i];

temp[i]._id = i;

}

if (_arr!= NULL) delete [] _arr;

_arr = temp; //Заменяем предыдущий массив новым

++_itemsCount;

_arr[_itemsCount - 1] = obj; //И добавляем новый элемент в массив

_arr[_itemsCount - 1]._id = _itemsCount - 1;

}

 

void Clab51Dlg::FillList() //Метод заполнение объекта lst типа ListView

{

lst.DeleteAllItems(); //Удаляем все элементы

int pos;

CString str;

for(int i = _itemsCount - 1; i >= 0; --i)

{

pos = lst.InsertItem(0, _arr[i]._obj->Show()); //Заполняем список

lst.SetItemText(pos, 1, _arr[i]._owner);

lst.SetItemData(pos, (DWORD_PTR) _arr[i]._id); //Устанавливаем это значение чтобы найти элемент в массиве по номеру

}

}

 

void Clab51Dlg::OnBnClickedBtnDel() //Реакция на нажатие кнопки "Удалить"

{

POSITION pos = lst.GetFirstSelectedItemPosition(); //Находим выделенный элемент

if (pos!= NULL)

{

if(MessageBox(L"Вы действительно хотите удалить выбранную запись?", L"Информация", MB_YESNO | MB_ICONINFORMATION)!= IDYES)

{

return;

}

int i = lst.GetItemData(lst.GetNextSelectedItem(pos)); //Находим его номер в массиве

DeleteObj(i); //Удаляем

FillList(); //Заполняем список заново

}

else MessageBox(L"Сначала выберите элемент для удаления.");

}

 

void Clab51Dlg::DeleteObj(int idx) //Метод для удаление элемента из массива

{

ObjWithOwner* temp = new ObjWithOwner[_itemsCount - 1];

for (int i = 0; i < idx; ++i)

{

temp[i] = _arr[i];

temp[i]._id = i;

}

for (int i = idx + 1; i < _itemsCount; ++i)

{

temp[i - 1] = _arr[i];

temp[i - 1]._id = i - 1;

}

delete [] _arr;

_arr = temp;

--_itemsCount;

}

 

void Clab51Dlg::OnBnClickedBtnAdd() //Реакция на нажатие кнопки "Добавить"

{

CEditDlg dlg; //Создаём экземпляр объекта окна редактирования

if (dlg.DoModal() == IDOK) //Если пользователь в окне нажал кнопку "OK"

{

ObjWithOwner obj;

obj._owner = dlg._ownedByStr; //Заполняем поле "в подчинении у"

 

//Далее, определяя тип, выбранный в ListBox'ах создаём новый элемент

if (dlg._boxTypePersDepartString == L"Рабочий")

{

obj._obj = new Worker(dlg._name, _ttoi(dlg._age), _ttoi(dlg._workExp));

}

else if (dlg._boxTypePersDepartString == L"Служащий")

{

obj._obj = new Employee(dlg._name, _ttoi(dlg._age), _ttoi(dlg._workExp));

}

else if (dlg._boxTypePersDepartString == L"Инженер")

{

obj._obj = new Engineer(dlg._name, _ttoi(dlg._age), _ttoi(dlg._workExp));

}

 

if (dlg._boxTypeObjString == L"Группа") //Если был выбран тип "Группа"

{

CEditDlg* addHeadDlg = new CEditDlg(); //Вызываем окно для добавления руководителя

addHeadDlg->_staticAddHeaderStr = L"Добавление руководителя";

addHeadDlg->_ownedByStr = dlg._name;

if (addHeadDlg->DoModal()!= IDOK) return; //Если руководитель не добавлен, то и группа не создаётся

 

TPerson* header;

 

if (addHeadDlg->_boxTypePersDepartString == L"Рабочий")

{

header = new Worker(addHeadDlg->_name, _ttoi(addHeadDlg->_age), _ttoi(addHeadDlg->_workExp));

}

else if (addHeadDlg->_boxTypePersDepartString == L"Служащий")

{

header = new Employee(addHeadDlg->_name, _ttoi(addHeadDlg->_age), _ttoi(addHeadDlg->_workExp));

}

else if (addHeadDlg->_boxTypePersDepartString == L"Инженер")

{

header = new Engineer(addHeadDlg->_name, _ttoi(addHeadDlg->_age), _ttoi(addHeadDlg->_workExp));

}

 

if (dlg._boxTypePersDepartString == L"Цех")

{

obj._obj = new WorkShop(dlg._name, header);

}

else if (dlg._boxTypePersDepartString == L"Завод")

{

obj._obj = new Factory(dlg._name, header);

}

else if (dlg._boxTypePersDepartString == L"Филиал")

{

obj._obj = new Branch(dlg._name, header);

}

}

AddObj(obj); //Добавляем этот объект в список

FillList(); //Перезаполняем список

}

}

 

void Clab51Dlg::OnBnClickedBtnEdit() //Реакция на нажатие кнопки "Изменить"

{

POSITION pos = lst.GetFirstSelectedItemPosition(); //Находим позицию элемента в списке

if (pos!= NULL) //Если выделен элемент

{

int i = lst.GetItemData(lst.GetNextSelectedItem(pos)); //Находим номер элемента в массиве

 

CEditDlg dlg; //Создаём экземпляр объекта редактирования

dlg._name = _arr[i]._obj->GetName(); //У всех объектов есть поле _name, сразу заполняем его

dlg._ownedByStr = _arr[i]._owner; //А также поле "подчиняется"

//В зависимости от типа объекта заполняем другие данные

if (typeid(*_arr[i]._obj) == typeid(WorkShop) || typeid(*_arr[i]._obj) == typeid(Factory) || typeid(*_arr[i]._obj) == typeid(Branch))

{

if (dlg.DoModal() == IDOK) _arr[i]._obj->SetName(dlg._name);

}

else

{

if (typeid(*_arr[i]._obj) == typeid(Worker))

{

Worker* cur = (Worker*)_arr[i]._obj;

dlg._age.Format(L"%d", cur->GetAge());

dlg._workExp.Format(L"%d", cur->GetWorkExp());

 

if (dlg.DoModal() == IDOK)

{

cur->SetName(dlg._name);

cur->SetAge(_ttoi(dlg._age));

cur->SetWorkExp(_ttoi(dlg._workExp));

}

}

else if (typeid(*_arr[i]._obj) == typeid(Engineer))

{

Engineer* cur = (Engineer*)_arr[i]._obj;

dlg._age.Format(L"%d", cur->GetAge());

dlg._workExp.Format(L"%d", cur->GetWorkExp());

 

if (dlg.DoModal() == IDOK)

{

cur->SetName(dlg._name);

cur->SetAge(_ttoi(dlg._age));

cur->SetWorkExp(_ttoi(dlg._workExp));

}

}

else if (typeid(*_arr[i]._obj) == typeid(Employee))

{

Employee* cur = (Employee*)_arr[i]._obj;

dlg._age.Format(L"%d", ((Employee*)_arr[i]._obj)->GetAge());

dlg._workExp.Format(L"%d", ((Employee*)_arr[i]._obj)->GetWorkExp());

 

if (dlg.DoModal() == IDOK)

{

cur->SetName(dlg._name);

cur->SetAge(_ttoi(dlg._age));

cur->SetWorkExp(_ttoi(dlg._workExp));

}

}

}

FillList();

}

else MessageBox(L"Сначала выберите элемент для редактирования");

}

 

Интерфейс окна редактирования основывается на следующем коде:

Добавляется следующий код в метод DoDataExchange:

void CEditDlg::DoDataExchange(CDataExchange* pDX)

 

{

CDialogEx::DoDataExchange(pDX);

 

……………………………………………

if(_boxTypeObj.GetCount() == 0) //Если в выпадающем списке нет объектов, добавляем их

{

_boxTypeObj.AddString(L"Человек");

_boxTypeObj.AddString(L"Группа");

}

 

if (_staticAddHeaderStr!= L"") //Если создаётся руководитель для группы

{

_boxTypeObj.SetCurSel(1); //Выделяем поле "Человек"

_boxTypeObj.EnableWindow(FALSE); //И блокируем его

 

_boxTypePersDepart.AddString(L"Рабочий");

_boxTypePersDepart.AddString(L"Служащий");

_boxTypePersDepart.AddString(L"Инженер");

_boxTypePersDepart.SetCurSel(0);

 

_ageEditControl.EnableWindow(TRUE); //Активируем поля "возраст" и "трудовой стаж"

_workExpEditControl.EnableWindow(TRUE);

 

_staticName = L"Имя:";

}

 

if (_ownedByStr!= L"") _ownedBy.EnableWindow(FALSE); //Если поле "подчиняется" уже заполнено, блокируем его

 

}

 

void CEditDlg::SelchangeComboObjtype() //Реакция на изменение выбранного элемента в выпадающем списке "Тип"

{

UpdateData(TRUE); //Заносим информацию в переменные

for (int i = 0; i <= 3; ++i) //Очищаем список подтипов

_boxTypePersDepart.DeleteString(0);

 

//В зависимости от выбранного типа, заполняем выпадающий список "подтип", делаем активными поля "возраст" и "трудовой стаж" и изменяем описание у поля "Имя"

if (_boxTypeObjString == L"Человек")

{

_boxTypePersDepart.AddString(L"Рабочий");

_boxTypePersDepart.AddString(L"Служащий");

_boxTypePersDepart.AddString(L"Инженер");

_boxTypePersDepart.SetCurSel(0);

 

_ageEditControl.EnableWindow(TRUE);

_workExpEditControl.EnableWindow(TRUE);

 

_staticName = L"Имя:";

UpdateData(FALSE); //Перерисовываем обновлённые данные

}

else

{

_boxTypePersDepart.AddString(L"Цех");

_boxTypePersDepart.AddString(L"Завод");

_boxTypePersDepart.AddString(L"Филиал");

_boxTypePersDepart.SetCurSel(0);

 

_ageEditControl.EnableWindow(FALSE);

_workExpEditControl.EnableWindow(FALSE);

 

_staticName = L"Название:";

UpdateData(FALSE);

}

}

 

void CEditDlg::OnBnClickedOk() //Реакция на нажатие кнопки "Ок"

{

//Если ничего не введено в одно из полей

if (_name == L"" || _ownedByStr == L"" || (_age == L"" && _boxTypeObjString == L"Человек") || (_workExp == L"" && _boxTypeObjString == L"Человек"))

{ //Выводим сообщение об ошибке

MessageBox(L"Введены не все данные");

return;

}

CDialogEx::OnOK();

}

 




Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2016-04-27 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: