- •О.С. Зеленський
- •Розділ 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.2. Додатки без використання архітектури «Документ-вид»
Створимо додаток без використання архітектури «Документ-Вид» з назвою example. Для цього потрібно виконати такі дії:
Запустити меню File → New.
Обрати на вкладці Projects пункт MFC AppWizard (exe), ввести ім’я проекту (рис. 9.1).
Рис. 9.1. Вибір типу створюваного проекту
На 1-му кроці треба зняти виділення Document/View architecture support? (Чи потрібна підтримка архітектури «Документ-Вид»?). На рис. 9.2 наведено основні параметри проекту, які треба ввести користувачу.
Інші кроки можна пропустити, так створюється простий додаток без використання архітектури «Документ-Вид».
В результаті отримуємо наступні класи (табл. 9.1):
Таблиця 9.1
Перелік класів додатку без використання архітектури «Документ-вид»
Назва класу |
Базовий клас |
Опис |
CExampleApp |
CWinApp |
Головний клас додатку |
CMainFrame |
CFrameWnd |
Клас головного вікна додатку |
CChildView |
CWnd |
Клас вікна, дочірнього відносно головного вікна |
CAboutDlg |
CDialog |
Клас вікна діалогу |
Рис. 9.2. Введення основних параметрів проекту
9.2.1. Приклад додатку реєстрації wnd-класу вікна
Приклад додатку реєстрації WND-класу вікна знаходиться у папці DISK\Structure\Dchild_no_tem_0.
Як було зазначено в п. 9.1 всі вікна базуються на структурі WNDCLASS. Розглянемо роботу зі структурами типу WNDCLASS та функціями: AfxRegisterClass, AfxRegisterWndClass, SetClassLong та іншими. Створимо додаток з назвою Dchild_no_tem_0, на рисунку 9.3 зображено його основні класи.
Рис. 9.3. Схема підключення класів вікон у додатку Dchild_no_tem_0
При створенні дочірніх вікон використаємо 3 різних підходи. Щоб вікна з різними параметрами класів було легко відрізнити одне від одного ми у кожному з них задамо свій колір фону. Перше вікно буде створено на основі стандартного класу вікна (цей клас має назву «AfxFrameOrView42d»), фон вікна буде замінений функцією SetClassLong. Друге вікно створюватиметься на основі власного класу, фон вікна буде встановлено при реєстрації класу. Третє вікно також буде створено на основі свого класу, але зміна фону буде зроблена у функції PreCreateWindow.
Функція створення першого дочірнього вікна має вид:
void CMainFrame::OnChild1()
{
if(m_child2) { delete m_child2; m_child2 = 0;}
if(m_child3) { delete m_child3; m_child3 = 0;}
if(m_child1) return;
SetWindowText("Child 1");
m_child1 = new CChild1;
if (!m_child1->CreateEx(0, NULL, "",
AFX_WS_DEFAULT_VIEW, CRect(0, 0, 0, 0),
this, AFX_IDW_PANE_FIRST))
return;
CBrush * br = new CBrush(RGB(255,0,0));
SetClassLong(m_child1->m_hWnd, GCL_HBRBACKGROUND,
(long)(HBRUSH)GetStockObject(*br));
RecalcLayout();
}
На початку функції видаляємо всі інші дочірні вікна. Якщо дане вікно відкрито виходимо з функції. Встановлюємо напис заголовка вікна. Створюємо об’єкт класу CChild1. Функцією CreateEx створюється саме дочірнє вікно. У 2-му параметрі задаємо NULL, отже при створенні вікна буде задано клас звичайного стандартного вікна. Параметр AFX_IDW_PANE_FIRST потрібен для вкладених дочірніх вікон. Вікна з іншими параметрами відображатись не будуть, оскільки будуть працювати у фоновому режимі. Функцією SetClassLong можна встановити нові параметри для класу вікна, у даному випадку змінюємо колір фону на червоний.
Для роботи з другим вікном створимо функцію RegisterMyWndClass для реєстрації власного WND-класу. Через параметр name будемо давати ім’я цього класу:
bool CMainFrame::RegisterMyWndClass(CString name)
{
WNDCLASS wc={0};
HINSTANCE hInst=AfxGetInstanceHandle();
wc.lpszClassName=name;
wc.hInstance=hInst;
wc.lpfnWndProc=::DefWindowProc;
wc.hCursor=::LoadCursor(NULL,IDC_ARROW);
CBrush *br = new CBrush;
br->CreateSolidBrush(RGB(0,255,0));
wc.hbrBackground=(HBRUSH)(*br);
wc.style = CS_GLOBALCLASS|CS_DBLCLKS;
if (!AfxRegisterClass(&wc))
{
AfxThrowResourceException();
return false;
}
return true;
}
В даній функції відбувається створення вікна з зеленим фоном. Спочатку готуємо структуру wc типу WNDCLASS. Через функцію AfxGetInstanceHandle отримуємо дескриптор нашого додатку. Зв’язування структур WNDCLASS та CREATESTRUCT відбувається через параметри структур WNDCLASS.lpszClassName і CREATESTRUCT.lpszClass, які вміщують ім’я зареєстрованого WND-класу. Потім задаємо кожен параметр структури самостійно. Створюємо об'єкт класу CBrush функцією CreateSolidBrush з зеленим кольором. Завдяки функції AfxRegisterClass зареєструємо клас вікна, давши йому структуру wc. Тепер всі вікна створені на основі Windows класу з ім’ям вказаним у name будуть з зеленим фоном. У разі невдалої реєстрації класу викликаємо функцію AfxThrowResourceException, котра використовується при виникненні проблем з ресурсами.
Функція створення другого дочірнього вікна має вид:
void CMainFrame::OnChild2()
{
if(m_child1) { delete m_child1; m_child1 = 0;}
if(m_child3) { delete m_child3; m_child3 = 0;}
if(m_child2) return;
SetWindowText("Child 2");
m_child2 = new CChild2;
// AFX_WS_DEFAULT_VIEW -> WS_CHILD|WS_VISIBLE|WS_BORDER
if (!m_child2->CreateEx(0,str, "Child 2",
WS_CHILD|WS_VISIBLE|WS_BORDER,CRect(0, 0, 0, 0),
this, AFX_IDW_PANE_FIRST))
return;
RecalcLayout();
}
У цьому прикладі робимо аналогічні дії, але при створенні вікна даємо ім’я класу із змінної str, яка отримала значення "MyWndClass" у конструкторі класу CMainFrame. Там ми зареєстрували новий клас з цим ім’ям створеною нами функцією RegisterMyWndClass.
Приведемо функцію створення третього дочірнього вікна:
void CMainFrame::OnChild3()
{
if(m_child1) { delete m_child1; m_child1 = 0;}
if(m_child2) { delete m_child2; m_child2 = 0;}
if(m_child3) return;
CRect rect;
GetWindowRect(&rect);
rect.OffsetRect(20,80);
SetWindowText("Child 3");
m_child3 = new CChild3;
if (!m_child3->CreateEx(0,NULL, "Child 3",
WS_CHILD|WS_VISIBLE|WS_BORDER,CRect(0, 0, 0, 0),
this, AFX_IDW_PANE_FIRST))
return;
RecalcLayout();
}
У функції PreCreateWindow створюємо вікно на основі власного WND-класу:
BOOL CChild3::PreCreateWindow(CREATESTRUCT& cs)
{
if( !CFrameWnd::PreCreateWindow(cs))
return FALSE;
CBrush *br = new CBrush;
br->CreateSolidBrush(RGB(0,0,255));
cs.dwExStyle |= WS_EX_CLIENTEDGE;
cs.style &= ~WS_BORDER;
cs.lpszClass = AfxRegisterWndClass(
CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS,
::LoadCursor(NULL, IDC_ARROW), HBRUSH(*br), NULL);
return TRUE;
}
У PreCreateWindow продемонстровано реєстрацію WND-класу за допомогою функції AfxRegisterWndClass. У якості параметрів цієї функції передаються основні параметри структури WNDCLASS – стилі класу вікна (CS_...), дескриптор курсору, дескриптор пензля, дескриптор іконки, всі інші параметри передаються по умовчанню. Головною відмінністю функції реєстрації класу вікна AfxRegisterWndClass від функції AfxRegisterClass є те, що функція AfxRegisterWndClass сама формує ім’я зареєстрованого класу та повертає його у вигляді 16-го рядку. Рядок коду програми
cs.lpszClass = AfxRegisterWndClass(
CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS,
::LoadCursor(NULL, IDC_ARROW), HBRUSH(*br), NULL);
забезпечує зв’язок структури ініціалізації вікна CREATESTRUCT та структури основних властивостей вікна WNDCLASS.
Таким чином, у результаті виконання функції отримаємо вікно синього кольору.
На рис. 9.4 показано результат роботи додатку.
Рис. 9.4. Приклад роботи додатку Dchild_no_tem_0, із вікнами Child1, Child2 та Child3