Microsoft Visual C++ и MFC. Программирование для Windows 95 и Windows NT. Часть 2 - Александр Фролов
Шрифт:
Интервал:
Закладка:
Кроме этого элемента в классе CDaterDoc определены конструктор, деструктор, метод OnNewDocument, а также методы AssertValid и Dump:
class CDaterDoc : public CDocument {
protected:
CDaterDoc();
DECLARE_DYNCREATE(CDaterDoc)
// Attributes
public:
CDaterSet m_daterSet;
// Operations
public:
// Overrides
//{{AFX_VIRTUAL(CDaterDoc)
public:
virtual BOOL OnNewDocument();
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CDaterDoc();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected:
//{{AFX_MSG(CDaterDoc)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
Конструктор и деструктор класса CDaterDocКонструктор и деструктор класса CMainFrame не содержжат программного кода.
Метод PreCreateWindow класса CDaterDocМетод OnNewDocument вызывается, когда надо создать новый документ для приложения. Метод OnNewDocument приложения Dater вызывает метод OnNewDocument базового класса CDocument:
BOOL CDaterDoc::OnNewDocument() {
if (!CDocument::OnNewDocument()) return FALSE;
// TODO:
return TRUE;
}
Методы AssertValid и Dump класса CDaterDocМетоды AssertValid и Dump класса CMainFrame могут использоваться при отладке приложения.
Класс окна просмотра приложения – CDaterViewБольшой интерес представляет класс окна просмотра приложения CDaterView. В нем содержится указатель m_pSet на объект класса CDaterSet, который представляет запись базы данных. Обратите внимание, что определение указателя находится внутри комментариев вида //{{AFX_DATA. Эти комментарии используются MFC ClassWizard:
class CDaterView : public CRecordView {
protected:
CDaterView();
DECLARE_DYNCREATE(CDaterView)
public:
//{{AFX_DATA(CDaterView)
enum { IDD = IDD_DATER_FORM };
CDaterSet* m_pSet;
//}}AFX_DATA
// Attributes
public:
CDaterDoc* GetDocument();
// Operations
public:
// Overrides
//{{AFX_VIRTUAL(CDaterView)
public:
virtual CRecordset* OnGetRecordset();
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
virtual void DoDataExchange(CDataExchange* pDX);
virtual void OnInitialUpdate();
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CDaterView();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected:
//{{AFX_MSG(CDaterView)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
Помимо конструктора и деструктора в классе CDaterView определен целый ряд методов – PreCreateWindow, GetDocument, OnGetRecordset, DoDataExchange, OnInitialUpdate, а также AssertValid и Dump. Опишем наиболее важные из этих методов более подробно.
Конструктор и деструктор класса CDaterViewКонструктор класса CMainFrame вызывает конструктор базового класса CRecordView и передает ему в качестве параметра символ IDD, определенный как идентификатор шаблона диалоговой панели IDD_DATER_FORM, используемого окном просмотра.
Конструктор CMainFrame также приваивает указателю m_pSet значение NULL:
CDaterView::CDaterView() : CRecordView(CDaterView::IDD) {
//{{AFX_DATA_INIT(CDaterView)
m_pSet = NULL;
//}}AFX_DATA_INIT
// TODO:
}
Деструктор класса CMainFrame не содержит программного кода:
CDaterView::~CDaterView() {}
Метод PreCreateWindow класса CDaterViewМетод PreCreateWindow вызывает метод PreCreateWindow базового класса CRecordView и выполняет обработку по умолчанию:
BOOL CDaterView::PreCreateWindow(CREATESTRUCT& cs) {
// TODO:
return CRecordView::PreCreateWindow(cs);
}
Метод GetDocument класса CDaterViewМетод GetDocument возвращает указатель на документ, связанный с данным окном просмотра. Если окно просмотра не связано ни с каким документом, метод возвращает значение NULL.
Метод GetDocument имеет две реализации. Одна используется для отладочной версии приложения, а другая для окончательной.
Окончательная версия GetDocument определена непосредственно после самого класса окна просмотра CDaterView как встраиваемый (inline) метод. Когда вы используете страницу ClassView окна Project Workspace, чтобы просмотреть определение метода GetDocument, вы увидите именно этот код:
// Окончательная версия приложения
#ifndef _DEBUG
inline CDaterDoc* CDaterView::GetDocument() {
return (CDaterDoc*)m_pDocument;
}
#endif
Отладочная версия GetDocument расположена в файле реализации класса окна просмотра DaterView.cpp. Откройте этот файл вручную, выбрав его название из страницы FileView окна Project Workspace:
// Отладочная версия приложения
#ifdef _DEBUG
CDaterDoc* CDaterView::GetDocument() {
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDaterDoc)));
return (CDaterDoc*)m_pDocument;
}
#endif //_DEBUG
Макрокоманда RUNTIME_CLASS возвращает указатель на структуру CRuntimeClass, содержащую информацию о классе CDaterDoc. Метод IsKindOf, определенный в классе CObject, проверяет, принадлежит ли объект, на который указывает m_pDocument, к классу CDaterDoc или классу наследованному от CDaterDoc. Если в приложении есть ошибка и m_pDocument не указывает на документ приложения, макрокоманда ASSERT отображает соответствующее сообщение и прерывает работу приложения.
Метод OnGetRecordset класса CDaterViewМетод OnGetRecordset класса CDaterView возвращает указатель m_pSet на запись базы данных:
//////////////////////////////////////////////////////////////
// Метод OnGetRecordset класса CDaterView
CRecordset* CDaterView::OnGetRecordset() {
return m_pSet;
}
Метод OnInitialUpdate класса CDaterViewМетод OnInitialUpdate класса окна просмотра CDaterView первоначально определен в базовом классе CView. Этот метод вызывается MFC перед отображением окна просмотра на экране:
//////////////////////////////////////////////////////////////
// Метод OnInitialUpdate класса CDaterView
void CDaterView::OnInitialUpdate() {
m_pSet = &GetDocument()->m_daterSet;
CRecordView::OnInitialUpdate();
}
В момент вызова метода OnInitialUpdate окно просмотра уже связано с объектом документа приложения, поэтому можно использовать метод GetDocument.
В нашем случае метод GetDocument используется, чтобы записать в переменную m_pSet (входящую в класс CDaterView) укзатель на объект m_daterSet класса CDaterSet, представляющий записи базы данных и входящий в класс документа приложения — класс CDaterDoc.
Затем вызывается метод OnInitialUpdate базового класса CRecordView.
Метод DoDataExchange класса CDaterViewВиртуальный метод DoDataExchange класса CDaterView, первоначально определен в классе CWnd. Он служит для реализации механизмов автоматического обмена данными – Dialog Data Exchange (DDX) и автоматической проверки данных – Dialog Data Validation (DDV). Мы рассматривали этот механизм в 24 томе серии “Библиотека системного программиста”:
//////////////////////////////////////////////////////////////
// Метод DoDataExchange класса CDaterView
void CDaterView::DoDataExchange(CDataExchange* pDX) {
CRecordView::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CDaterView)
DDX_FieldText(pDX,IDC_ADDRESS, m_pSet->m_ADDRESS, m_pSet);
DDX_FieldText(pDX,IDC_NAME, m_pSet->m_NAME, m_pSet);
DDX_FieldText(pDX,IDC_PHONE, m_pSet->m_PHONE, m_pSet);
DDX_FieldText(pDX,IDC_PRIORITY, m_pSet->m_PRIORITY,m_pSet);
//}}AFX_DATA_MAP
}
Механизм автоматического обмена данными привязывает к органам управления диалоговой панели переменные или элементы данных класса диалоговой панели. Так как окно просмотра построено на основе диалоговой панели, механизм автоматического обмена данными позволяет нам выполнять обмен данными между органами управления, размещенными в окне просмотра, и элементами класса окна просмотра. Обмен данными работает в обоих направлениях.
Обмен выполняется при помощи функций DDX_FieldText. Могут также использоваться и другие функции, например, DDX_FieldRadio, DDX_FieldCheck, DDX_FieldScroll. Практически каждый тип органов управления диалоговой панели имеет собственную функцию для выполнения процедуры обмена данными.
Всем функциям DDX_FieldText, вызываевым в методе DoDataExchange класса CDaterView передаются четыре параметра.
Первый параметр содержит указатель на объект класса CDataExchange. Этот объект определяет параметры обмена, в том числе направление, в котором надо выполнить обмен данными.
Второй параметр определяет идентификатор органа управления окна просмотра, с которым выполняется обмен данными (окно просмотра доолжно быть представлено классом CRecordView). В нашем случае это идентификаторы полей IDC_ADDRESS, IDC_NAME, IDC_PHONE и IDC_PRIORITY, котоорые принадлежат шаблону диалоговой панели используемому окном просмотра.
Третий параметр содержит ссылку на элемент данных класса CDaterSet, представляющий соответствующее поле базы данных. В нашем методе в качестве этого парамтера фигурируют m_pSet->m_ADDRESS, m_pSet->m_NAME, m_pSet->m_PHONE и m_pSet->m_PRIORITY.