- •1. Створення проекту додатку
- •2. Розроблення системи меню
- •2.1. Налаштування головного меню додатку
- •2.2. Створення контекстного меню
- •2.3. Визначення функцій-обробників повідомлень системи меню
- •2.4.Перевірка працездатності меню«Data»
- •2.4.Перевірка працездатності контекстного меню
- •3. Створення класу dbFacade
- •3.1.Заголовочний файл класу dbFacade
- •3.2.Файл реалізації класу dbFacade
- •3.3.Тестування класу dbFacade
- •4. Розроблення графічного представлення даних звітів
- •4.1. Функція CalcDocSizes( )
- •4.2. Функція OnDraw( )
- •4.3. Функція-обробник зміни шрифту
- •4.4. Функція-обробник зміни кольору фону
- •5. Додаткові елементи керування
- •5.1. Дублювання пунктів меню на панелі інструментів
- •5.2. Додавання назви звіту у рядок стану додатку
- •Висновок
- •Список рекомендованої літератури
3.2.Файл реалізації класу dbFacade
Перед тим, як перейти до реалізації класу, потрібно створити джерело даних, наприклад, «Борей». Звернення до цього джерела у тексті програмного коду подано жирним шрифтом).
Реалізація класу має наступний вигляд (коментарі всередині тексту):
#include "stdafx.h"
#include "Course.h"
#include "DBFacade.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//Конструктор класу
DBFacade::DBFacade()
{
//Визначаємо стан за замовчуванням
state = stEmployee;
//Оголошуємо змінні для запитів
Query qryEmployee,qryClients,qryProviders;
//Ініціалізуємо запити і заносимо їх у масив
qryEmployee.strTitle = "СОТРУДНИКИ";
qryEmployee.strQuery = "SELECT * FROM Сотрудники";
queries.push_back(qryEmployee);
qryClients.strTitle = "КЛИЕНТЫ";
qryClients.strQuery = "SELECT * FROM Клиенты";
queries.push_back(qryClients);
qryProviders.strTitle = "ПОСТАВЩИКИ";
qryProviders.strQuery = "SELECT * FROM Поставщики";
queries.push_back(qryProviders);
//Відкриваємо з’єднання з базою даних
db.OpenEx("DSN=Борей");
rs.m_pDatabase = &db;
//Виконуємо запит
openRSet();
}
//Деструктор
DBFacade::~DBFacade()
{
if(!queries.empty())
//Очищаємо масив запитів
queries.clear();
if(rs.IsOpen())
//Закриваємо набір записів
rs.Close();
if(db.IsOpen())
//Закриваємо з’єднання з базою даних
db.Close();
}
DBFacade::State DBFacade::getState()
{
//Повертаємо поточний стан об’єкта
return state;
}
void DBFacade::setState(DBFacade::State st)
{
if(state == st)
return;
//Встановлюємо поточний стан об’єкта
state = st;
openRSet();
}
CString DBFacade::getTitle()
{
//Повертаємо заголовок поточного звіту
return queries[state].strTitle;
}
void DBFacade::openRSet()
{
try
{
//Якщо набір записів відкрито, закриваємо його
if(rs.IsOpen())
rs.Close();
//виконання поточного запиту
rs.Open(AFX_DB_USE_DEFAULT_TYPE,
queries[state].strQuery);
}
//Перехоплюємо виключні ситуації
catch(CMemoryException* ex)
{
ex->ReportError();
ex->Delete();
}
catch(CDBException* ex)
{
ex->ReportError();
ex->Delete();
}
}
CRecordset& DBFacade::getRSet()
{
//Повертаємо посилання на набір записів
return rs;
}
3.3.Тестування класу dbFacade
Для тестування класу DBFacade у оголошення класу CCourseDoc потрібно внести наступні зміни (подані жирним шрифтом):
#include "DBFacade.h"
class CCourseDoc : public CDocument
{
protected: // create from serialization only
CCourseDoc();
DECLARE_DYNCREATE(CCourseDoc)
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CCourseDoc)
public:
virtual BOOL OnNewDocument();
virtual void Serialize(CArchive& ar);
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CCourseDoc();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected:
// Generated message map functions
protected:
//{{AFX_MSG(CCourseDoc)
afx_msg void OnDataClients();
afx_msg void OnDataEmployee();
afx_msg void OnDataProviders();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
private:
DBFacade dbf;
void setMenuRadio(UINT nItem);
};
Після цього потрібно внести зміни у реалізації функцій-обробників команд меню:
void CCourseDoc::OnDataClients()
{
// TODO: Add your command handler code here
//MessageBox(NULL,"OnDataClients not yet implemented",
"Document", MB_OK);
setMenuRadio(ID_DATA_CLIENTS);
dbf.setState(DBFacade::State::stClients);
MessageBox(NULL,dbf.getTitle(),"Document", MB_OK);
UpdateAllViews(NULL);
}
void CCourseDoc::OnDataEmployee()
{
// TODO: Add your command handler code here
//MessageBox(NULL,"OnDataEmployee not yet implemented",
"Document", MB_OK);
setMenuRadio(ID_DATA_EMPLOYEE);
dbf.setState(DBFacade::State::stEmployee);
MessageBox(NULL,dbf.getTitle(),"Document", MB_OK);
UpdateAllViews(NULL);
}
void CCourseDoc::OnDataProviders()
{
// TODO: Add your command handler code here
//MessageBox(NULL,"OnDataProviders not yet implemented",
"Document", MB_OK);
setMenuRadio(ID_DATA_PROVIDERS);
dbf.setState(DBFacade::State::stProviders);
MessageBox(NULL,dbf.getTitle(),"Document", MB_OK);
UpdateAllViews(NULL);
}
Тепер під час вибору пункту меню можна побачити повідомлення з назвою звіту (рис.3.2):
Рис3.2 - Вікно повідомлення з назвою звіту
Наостанок потрібно додати в клас документу (CCourseDoc) відкриту (public) функцію-член, до якої звертатиметься клас представлення, щоб отримати доступ до даних звіту. Прототип функції виглядає наступним чином:
CRecordset& getRSet();
Реалізація функції пересилає запит до об’єкта класу DBFacade і виглядає так:
CRecordset& CCourseDoc::getRSet()
{
return dbf.getRSet();
}
Таким чином було створено і функціонально реалізовано клас DBFacade, за допомогою якого значно спрощується робота з таблицями бази даних.