- •О.С. Зеленський
- •Розділ 9. Структура створення додатків
- •9.1. Загальна структура додатків
- •9.2. Додатки без використання архітектури «Документ-вид»
- •9.2.1. Приклад додатку реєстрації wnd-класу вікна
- •9.2.2. Створення та видалення дочірніх вікон без використання архітектури «Документ-Вид»
- •9.2.3. Створення дочірніх вікон без використання архітектури «Документ-Вид» (переключення вікон з використанням функції ShowWindow)
- •9.3. Архітектура «Документ-Вид»
- •Idr_mainframe формат строкового ресурсу.
- •9.3.1. Приклад додатку з використанням архітектури «Документ-Вид»
- •9.3.2. Види у архітектурі «Документ-Вид»
- •9.3.3. Створення видів у архітектурі «Документ-Вид» (переключення видів з використанням функції ShowWindow)
- •9.3.4. Робота з документами та видами на прикладі додатку SingleTemplate
- •9.4. Додатки mdi, робота з шаблонами
- •9.4.1. Приклад додатку mdi з одним шаблоном
- •9.4.2. Приклад додатку mdi з декількома шаблонами
- •Контрольні питання
- •Розділ 10. Робота з базами даних з використанням об'єктів ado
- •10.1.1. Ініціалізація об'єктів com з використанням директиви #import
- •10.1.2. Підтримка класів сом
- •10.2. Об'єкт Connection
- •10.3. Об'єкт Command
- •10.4. Об'єкт Recordset
- •10.5. Об'єкт Field і колекція Fields
- •10.6. Об'єкт Error і колекція Errors
- •10.8. Коротка характеристика структури мови sql
- •10.9. Синтаксис оператора вибору Select
- •10.10. Приклад програмування об'єктів ado
- •10.11. Опис розробленого навчального пакету ado6 для роботи з базами даних access та MySql
- •Int tip_bd; // тип бд 1- ms access, 2- MySql, 3 - xml
- •Void Connect_Baza(cString str);
- •Void ErrMessage(_com_error &ce);
- •If(pConn.CreateInstance("adodb.Connection"))
- •If(pRecordset.CreateInstance("adodb.RecordSet"))
- •Void cAdo6Doc::ErrMessage(_com_error &ce)
- •Void cAdo6Doc::OnMsaccess()
- •Void cAdo6Doc::OnMysql()
- •Void cAdo6Doc::OnXmlRead()
- •Void cAdo6Doc::Connect_Baza(cString str)
- •Virtual void DoDataExchange(cDataExchange* pDx);
- •Void cAdo6Dlg::DoDataExchange(cDataExchange* pDx)
- •Void cAdo6Dlg::Struct_MySql()
- •Void cAdo6Dlg::OnSelchangeListBaza()
- •Void cAdo6Dlg::OnVibor_bd()
- •Void cAdo6Dlg::AccessOpen()
- •Void cAdo6Dlg::xmlOpen()
- •Void cAdo6Dlg::Structura_bd()
- •Void cAdo6Dlg::OnSelchangeListTab()
- •Void cAdo6Dlg::show(int kod, int kod_bd)
- •Void cAdo6Dlg::Recordset_Baza(cString str)
- •Void cAdo6Dlg::OnClose()
- •10.11.2. Формування списку бд (MySql), відкриття бази даних (ms access), відкриття xml-файлу, формування списку таблиць (MySql і ms access) та полів (MySql, ms access, xml)
- •Void cAdo6Dlg::OnSelchangeListTab()
- •1. Обрану таблицю необхідно брати в зворотні лапки "`", щоб виключити помилку в тому випадку, якщо в імені таблиці будуть зустрічатися пробіли.
- •10.11.3. Робота з sql-запитами
- •Void cAdo6Dlg::OnZapros_Select()
- •If (str_query.Mid(0,6).Compare("select"))
- •If(!baza.Left(3).Compare("otl") &&
- •Void cAdo6Dlg::Recordset_Baza(cString str)
- •Void cado6Dlg::OnZapros_Make()
- •Vr_zap.Format(" Запрос выполнен за %f сек ",conec - nach);
- •10.11.4. Видалення, сортування, пошук, фільтрація, оновлення набору записів
- •Void cado6Dlg::OnZapis_Delete()
- •Void cado6Dlg::OnCheck_Sort()
- •Void cado6Dlg::OnFind()
- •0L,adSearchForward,bb);
- •Void cado6Dlg::OnFilter()
- •Void cado6Dlg::OnVozvrat()
- •10.11.5. Переходи по записах
- •Void cado6Dlg::OnButtonFirst()
- •Void cado6Dlg::OnButtonLast()
- •Void cado6Dlg::OnButtonLeft()
- •Void cado6Dlg::OnButtonRight()
- •Void cado6Dlg::OnButtonRecno()
- •Void cado6Dlg::OnButtonPgup()
- •Void cado6Dlg::OnButtonPgdn()
- •Void cado6Dlg::OnButtonBookmark()
- •10.11.6. Запис даних до xml-файлу
- •Void cAdo6Dlg::OnButtonSave()
- •10.11.7. Кнопки, призначені тільки для роботи з otl_tab
- •Void cado6Dlg::OnZapis_Add1()
- •Void cado6Dlg::OnZapis_Add2()
- •Void cado6Dlg::OnZapis_Update1()
- •Void cado6Dlg::OnZapis_Update2()
- •Void cado6Dlg::OnFormir_bd()
- •Void cAdo6Dlg::OnValues_Fields()
- •10.12. Використання у якості джерела даних електронної таблиці Excel
- •Контрольні питання
- •Завдання
- •Розділ 11. Програмування для інтернет
- •11.1. Створення броузера
- •11.3. Використання протоколу http
- •If ((pInternetSession)
- •11.4. Використання протоколу ftp
- •Контрольні питання
- •Розділ 12. Створення елементів activex
- •12.1. Створення елементів ActiveX
- •Invalidate();
- •12.2. Тестування елемента ActiveX
- •12.4. Створення елемента ActiveX на базі стандартних елементів
- •12.5. Відображення елементів ActiveX
- •Контрольні питання
- •Розділ 13. Налагодження програм
- •Int data[5];
- •Invalidate();
- •13.3. Установка точки переривання
- •13.2. Покрокове виконання програми
- •13.4. Перевірка значень змінних під час виконання програми
- •Контрольні питання
- •Список літератури
- •Додатки
9.3.4. Робота з документами та видами на прикладі додатку SingleTemplate
Приклад знаходиться у папці DISK\Structure\SingleTemplate.
Створимо приклад під назвою SingleTemplate, у якому буде 2 класи документів, 3 класи виду і один клас виду зі скролінгом. На рис. 9.12 наведено схему підключення класів вікон у додатку SingleTemplate.
Рис. 9.12. Схема підключення класів вікон додатку SingleTemplate
Програмний код класів можна знайти у комп’ютерній мережі інституту на inf-srv.
Створимо клас CScroll:
class CScroll : public CScrollView
{
.............................................................
};
Вікно класу CScroll похідне від класу CScrollView може виступати як дочірнє вікно при підключенні до окремого клієнтського вікна. У якості клієнтського вікна виберемо клас CFrameWnd. Додамо функцію OnClient в клас CMainFrame, для створення вікна зі скролінгом:
void CMainFrame::OnClient()
{
CRect rect;
GetWindowRect(&rect);
rect.OffsetRect(20,80);
CFrameWnd*fw = new CFrameWnd;
fw->CreateEx(NULL,NULL, "Скроллинг",
WS_VISIBLE|WS_OVERLAPPEDWINDOW,rect, this, 0);
CScroll*scr = new CScroll;
scr->Create(NULL,
NULL,
AFX_WS_DEFAULT_VIEW,
rectDefault,
fw,
AFX_IDW_PANE_FIRST,
NULL);
scr->OnInitialUpdate();
fw->RecalcLayout();
}
Функцію OnInitialUpdate необхідно визвати після створення вікна скролінгу, так як у ній обчислюються настройки, потрібні для правильного відображення скролінгу. Без виклику цієї функції програма не буде працювати. Якщо вікно скролінга створюється майстром, то ця функція знаходиться у секції protected, в такому випадку її необхідно самостійно перенести у public. Код самої функції необхідно також редагувати, так як створена майстром функція не обчислює розміри вікна. Обчислення розмірів вікна можна побачити нижче:
void CScroll::OnInitialUpdate()
{
CScrollView::OnInitialUpdate();
CSize sizeTotal;
// TODO: calculate the total size of this view
CRect rect;
int chir_s, dlina;
chir_s = GetDC()->GetTextExtent("1",1).cx;
dlina = GetDC()->GetTextExtent(str).cx + 10;
// Організація скролінгу
GetClientRect(&rect);
CSize clientSize(rect.right,rect.bottom);
CSize docSize(dlina,20*100);
CSize unitSize(chir_s,20);
SetScrollSizes(MM_TEXT,docSize,clientSize,unitSize);
}
Позначимо ширину символу змінною chir_s, а ширину вікна змінною dlina. Значення ширини тексту визначимо функцією GetTextExtent, з необхідними параметрами. До значення ширини вікна додаємо значення 10, необхідне для відступів. Потім задаємо класи розмірів CSize, необхідні для функції SetScrollSizes. Змінна docSize визначає розмір всього документа, а unitSize – розміри переміщення вікна при прокрутці скролінгу. Змінна clientSize відповідає за розміри клієнтського вікна, які визначаються через функцію GetClientRect.
Клас документа CDpredDoc перейменуємо на CDpredDoc0, і також створимо ще один клас документа CDpredDoc1. В ці класи додамо змінні str типу CString:
class CDpredDoc0 : public CDocument
{
.............................................................
CString str;
.............................................................
};
class CDpredDoc1 : public CDocument
{
.............................................................
CString str;
.............................................................
};
Присвоєння значень змінних відбувається у конструкторах класів:
CDpredDoc0::CDpredDoc0()
{
str = "Документ 0";
}
CDpredDoc1::CDpredDoc1()
{
str = "Документ 1";
}
Додамо функції OnDoc0 та OnDoc1 для переключення класів документів:
void CMainFrame::OnDoc0()
{
if(per_doc == 0)return;
per_view= 0;
per_doc = 0;
CSingleDocTemplate* pDocTemplate =
((CDpredApp*)AfxGetApp())->pDocTemplate;
CDocument*p_doc_vrem = GetActiveDocument();
CView*p_view_vrem = GetActiveView();
//Спочатку видалення активного документу
pDocTemplate->RemoveDocument(p_doc_vrem);
CDpredDoc0 *p_doc0 = new CDpredDoc0;
CDpredView0*p_view0 = new CDpredView0;
p_view0->Create(NULL,
NULL,
AFX_WS_DEFAULT_VIEW,
rectDefault,
this,
AFX_IDW_PANE_FIRST,
NULL);
p_doc0->AddView(p_view0);
pDocTemplate->AddDocument(p_doc0);
SetActiveView(p_view0);
// Спочатку видалення документу, а потім виду
delete p_doc_vrem;
delete p_view_vrem;
RecalcLayout();
}
void CMainFrame::OnDoc1()
{
if(per_doc)return;
per_doc = 1;
CSingleDocTemplate* pDocTemplate;
pDocTemplate = ((CDpredApp*)AfxGetApp())->pDocTemplate;
CDocument*p_doc_vrem = GetActiveDocument();
CView*p_view_vrem = GetActiveView();
pDocTemplate->RemoveDocument(p_doc_vrem);
CDpredDoc1 *p_doc1 = new CDpredDoc1;
CDpredView2*p_view2 = new CDpredView2;
p_view2->Create (NULL,
NULL,
AFX_WS_DEFAULT_VIEW,
rectDefault,
this,
AFX_IDW_PANE_FIRST,
NULL);
p_doc1->AddView(p_view2);
pDocTemplate->AddDocument(p_doc1);
SetActiveView(p_view2);
// Спочатку видалення документу, а потім виду
delete p_doc_vrem;
delete p_view_vrem;
RecalcLayout();
}
При підключенні класу документа CDpredDoc0, значення змінної per_doc=0, а при іншому документі per_doc=1. Ця змінна вводиться для з’ясування, який документ відкритий, і якщо відкритий документ CDpredDoc0, то можна змінювати підключене до нього вікно виду (CDpredView0 або CDpredView1). Функціями GetActiveDocument та GetActiveView ми отримуємо вказівки на активні класи документу та виду. Функцією класу шаблону RemoveDocument видаляємо клас активного документа з шаблону. Потім створюємо нові класи документа і виду, додаємо документ до шаблону і робимо активним вікно виду. На наступному етапі видаляємо об’єкти старих класів документа і виду (p_doc_vrem та p_view_vrem, які були активними на початку роботи функції). Видаляти потрібно спочатку клас документа, а лише потім клас виду!
У функціях OnView0 та OnView1 буде відбуватися зміна вікна виду, підключеного до активного документа CDpredDoc:
void CMainFrame::OnView0()
{
if(per_view==0)return;
if(per_doc)return;
per_view=0;
CView* p_view_vrem = GetActiveView();
CDpredView0* p0 = new CDpredView0;
p0->Create(NULL,
NULL,
AFX_WS_DEFAULT_VIEW,
rectDefault,
this,
AFX_IDW_PANE_FIRST,
NULL);
GetActiveDocument()->AddView(p0);
GetActiveView()->ShowWindow(SW_HIDE);
GetActiveDocument()->RemoveView(GetActiveView());
SetActiveView(p0);
//Видалення об’єкту View
delete p_view_vrem;
RecalcLayout();
}
void CMainFrame::OnView1()
{
if(per_view==1)return;
if(per_doc)return;
per_view=1;
CView* p_view_vrem = GetActiveView();
CDpredView1* p1 = new CDpredView1;
//Вказівка на документ
p1->pDoc = (CDpredDoc0*)GetActiveDocument();
p1->Create(NULL,
NULL,
AFX_WS_DEFAULT_VIEW,
rectDefault,
this,
AFX_IDW_PANE_FIRST,
NULL);
GetActiveDocument()->AddView(p1);
GetActiveView()->ShowWindow(SW_HIDE);
GetActiveDocument()->RemoveView(GetActiveView());
SetActiveView(p1);
//Видалення об’єкту View
delete p_view_vrem;
RecalcLayout();
}
На екран виводиться змінна str, яка береться із відповідного класу документа, а також номер вікна виду. Наведемо функції OnDraw вікон виду:
void CDpredView0::OnDraw(CDC* pDC)
{
CDpredDoc0* pDoc = GetDocument();
pDC->TextOut (10,10,pDoc->str + " Представление 0");
}
void CDpredView1::OnDraw(CDC* pDC)
{
pDC->TextOut (10,10,pDoc->str + " Представление 1");
}
void CDpredView2::OnDraw(CDC* pDC)
{
CDpredDoc1* pDoc = (CDpredDoc1*)GetDocument();
pDC->TextOut (10,10,pDoc->str + " Представление 2");
}
У даному фрагменті слід звернути головну увагу на отримання доступу до даних документа з кожного окремого виду. У функції OnDraw з 1-го виду CDpredView0 вказівка на документ отримується через функцію GetDocument яка створюється самостійно при розробці проекту:
CDpredDoc0* pDoc = GetDocument();
У функції OnDraw з 2-го виду CDpredView1 вказівка на документ отримується при переключенні на цей вид функцією OnView1 класу:
p1->pDoc = (CDpredDoc0*)GetActiveDocument();
У функції OnDraw з 3-го виду CDpredView2 вказівка на документ отримується за допомогою приведення функції GetDocument класу CDocument до класу документу з якого необхідно отримати дані:
CDpredDoc1* pDoc = (CDpredDoc1*)GetDocument();
Приклад додатку SingleTemplate приведено на рис. 9.13:
Рис. 9.13. Вікно додатку SingleTemplate, з відкритим документом 0-м та клієнтським вікном скролінга