- •О.С. Зеленський
- •Розділ 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. Перевірка значень змінних під час виконання програми
- •Контрольні питання
- •Список літератури
- •Додатки
Invalidate();
COleControl::OnLButtonDown(nFlags, point);
}
Після установки прапорця для прямокутника, на якому клацнув користувач, ми викликаємо перемальовування виду методом Invalidate(). Це призводить до виклику OnDraw(), в якому перевіряються всі чотири прапорці і необхідний прямокутник зафарбовується методом FillSolidRect() класу CDC:
void CBoxerCtrl::OnDraw(
CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
{
pdc->FillRect(rcBounds,
CBrush::FromHandle((HBRUSH)
GetStockObject(WHITE_BRUSH)));
box1 = CRect(rcBounds.left, rcBounds.top,
rcBounds.right/2, rcBounds.bottom/2);
box2 = CRect(rcBounds.left, rcBounds.bottom/2,
rcBounds.right/2, rcBounds.bottom);
box3 = CRect(rcBounds.right/2, rcBounds.top,
rcBounds.right, rcBounds.bottom/2);
box4 = CRect(rcBounds.right/2, rcBounds.bottom/2,
rcBounds.right, rcBounds.bottom);
pdc->Rectangle(&box1);
pdc->Rectangle(&box2);
pdc->Rectangle(&box3);
pdc->Rectangle(&box4);
if(fill1) pdc->FillSolidRect(&box1, RGB(0, 0, 0));
if(fill2) pdc->FillSolidRect(&box2, RGB(0, 0, 0));
if(fill3) pdc->FillSolidRect(&box3, RGB(0, 0, 0));
if(fill4) pdc->FillSolidRect(&box4, RGB(0, 0, 0));
}
Програма завершена, можна приступати до її тестування.
12.2. Тестування елемента ActiveX
Щоб перевірити роботу елемента Boxer, виконайте команду Build → Build Boxer.ocx (керуючі елементи ActiveX отримують розширення .ocx) – елемент створюється і реєструється в Windows. Потім виконайте команду Tools → ActiveX Control Test Container. Запускається надзвичайно корисна програма «тестовий контейнер» (рис. 12.3).
Виконайте в тестовому контейнері команду Edit → Insert OLE Control і двічі клацніть на рядку Boxer control у вікні Insert OLE Control. У результаті наш елемент ActiveX з'явиться в контейнері (рис. 12.3).
Клацніть у будь-якому прямокутнику – він зафарбовується чорним кольором, як показано на рис. 12.3. Якщо клацнути в іншому прямокутнику, чорним стане він. Елемент працює так, як ми хотіли, а зараз ми спробуємо вставити його в програму.
Рис. 12.3. Тестування елемента ActiveX
12.3. Вставка елементів ActiveX в програми на Visual C++
Давайте подивимося, як створений елемент буде працювати в програмі, написаній на Visual C++. За допомогою AppWizard створіть програму на базі діалогового вікна і назвіть її Boxerapp. У неї можна вставити елемент типу Boxer – виконайте команду Project → Add To Project → Components and Controls, і відкриється вікно Components and Controls Gallery . Двічі клацніть на рядку Registered ActiveX Controls, щоб вивести список всіх доступних елементів ActiveX (рис. 12.4).
Рис. 12.4. Вікно Components and Controls Gallery
Виділіть рядок Boxer Control (див. рис. 12.4) і натисніть кнопку Insert. З'являється діалогове вікно з питанням, чи бажаєте ви вставити елемент в свою програму; натисніть кнопку OK. Потім відкриється вікно Confirm Class, що повідомляє про створення нового класу CBoxer. Знову натисніть кнопку OK і закрийте вікно Components and Controls Gallery. Елемент Boxer з'явиться в палітрі редактора діалогових вікон (рис. 12.5). Він представлений кнопкою з літерами OCX.
Підказка. Щоб змінити зовнішній вигляд елемента ActiveX у палітрі, двічі клацніть у Visual C++ на ідентифікаторі растрового ресурсу IDB_BOXER – значок відкриється в редакторі растрових зображень, і ви зможете відредагувати його на свій розсуд.
Рис. 12.5. Елемент ActiveX у палітрі
Елемент Boxer, як і будь-який інший керуючий елемент, можна розмістити в головному діалоговому вікні програми (див. рис. 12.5). Запустіть програму (рис. 12.6).
Рис. 12.6. Елемент ActiveX у програмі
Як бачите, елемент ActiveX присутній у програмі і працює так, як йому належить. Ви можете як завгодно клацати на прямокутниках, і кожен раз обраний вами прямокутник буде зафарбовуватись (рис. 12.6).
Оригінальний текст програми міститься у файлах BoxerCtl.h/BoxerCtl.cpp.
BoxerCtl.h і BoxerCtl.cpp
#if !defined(AFX_BOXERCTL_H__00B2C1F4_95A2_11D0_8860_444553540000__INCLUDED_)
#define AFX_BOXERCTL_H__00B2C1F4_95A2_11D0_8860_444553540000__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
// BoxerCtl.h : Заголовок класа елемента ActiveX CBoxerCtrl.
/////////////////////////////////////////////////////////////////////////
// CBoxerCtrl : реалізація міститься в BoxerCtl.cpp.
class CBoxerCtrl : public COleControl
{
DECLARE_DYNCREATE(CBoxerCtrl)
// Конструктор
public:
CBoxerCtrl();
// Перевантаження
// Перевантажені віртуальні функції,
// сформовані ClassWizard-ом.
//{{AFX_VIRTUAL(CBoxerCtrl)
public:
virtual void OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid);
virtual void DoPropExchange(CPropExchange* pPX);
virtual void OnResetState();
//}}AFX_VIRTUAL
// Реалізація
protected:
~CBoxerCtrl();
CRect box1;
CRect box2;
CRect box3;
CRect box4;
boolean fill1;
boolean fill2;
boolean fill3;
boolean fill4;
DECLARE_OLECREATE_EX(CBoxerCtrl) // Фабрика класа і guid
DECLARE_OLETYPELIB(CBoxerCtrl) // GetTypeInfo
DECLARE_PROPPAGEIDS(CBoxerCtrl) // Ідентифікатори сторінок властивостей
DECLARE_OLECTLTYPE(CBoxerCtrl) // Імя типа і
// вспомогательная інформація
// Карта повідомлень
//{{AFX_MSG(CBoxerCtrl)
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
// Диспетчерські схеми
//{{AFX_DISPATCH(CBoxerCtrl)
// УВАГА!! Тут ClassWizard буде додавати і
// видаляти функції-члени.
// не редагуйте текст у цих блоках!
//}}AFX_DISPATCH
DECLARE_DISPATCH_MAP()
afx_msg void AboutBox();
// Карта подій
//{{AFX_EVENT(CBoxerCtrl)
// УВАГА!! Тут ClassWizard буде додавати і
// видаляти функції-члени.
// не редагуйте текст у цих блоках!
//}}AFX_EVENT
DECLARE_EVENT_MAP()
// Диспетчерскі ідентифікатори та ідентифікатори повідомлень
public:
enum {
//{{AFX_DISP_ID(CBoxerCtrl)
// УВАГА!! Тут ClassWizard буде додавати і
// видаляти елементи.
// не редагуйте текст у цих блоках!
//}}AFX_DISP_ID
};
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ буде вставляти додаткові
// оголошення перед попереднім рядком.
#endif // !defined(AFX_BOXERCTL_H__00B2C1F4_95A2_11D0_8860_444553540000__INCLUDED)
// BoxerCtl.cpp : реалізація елемента ActiveX CBoxerCtrl.
#include "stdafx.h"
#include "boxer.h"
#include "BoxerCtl.h"
#include "BoxerPpg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
IMPLEMENT_DYNCREATE(CBoxerCtrl, COleControl)
/////////////////////////////////////////////////////////////////////////
// Карта повідомлень
BEGIN_MESSAGE_MAP(CBoxerCtrl, COleControl)
//{{AFX_MSG_MAP(CBoxerCtrl)
ON_WM_LBUTTONDOWN()
//}}AFX_MSG_MAP
ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////
// Диспетчерська схема
BEGIN_DISPATCH_MAP(CBoxerCtrl, COleControl)
//{{AFX_DISPATCH_MAP(CBoxerCtrl)
// УВАГА!! Тут ClassWizard буде додавати і
// видаляти функції-члени.
// не редагуйте текст у цих блоках!
//}}AFX_DISPATCH_MAP
DISP_FUNCTION_ID(CBoxerCtrl, "AboutBox",
DISPID_ABOUTBOX, AboutBox, VT_EMPTY, VTS_NONE)
END_DISPATCH_MAP()
/////////////////////////////////////////////////////////////////////////
// Карта повідомлень
BEGIN_EVENT_MAP(CBoxerCtrl, COleControl)
//{{AFX_EVENT_MAP(CBoxerCtrl)
// УВАГА!! Тут ClassWizard буде додавати і
// видаляти функції-члени.
// не редагуйте текст у цих блоках!
//}}AFX_EVENT_MAP
END_EVENT_MAP()
/////////////////////////////////////////////////////////////////////////
// Сторінки властивостей
// ЗРОБИТИ: При необхідності додайте нові
// сторінки властивостей.
// Не забудьте збільшити значення лічильника!
BEGIN_PROPPAGEIDS(CBoxerCtrl, 1)
PROPPAGEID(CBoxerPropPage::guid)
END_PROPPAGEIDS(CBoxerCtrl)
/////////////////////////////////////////////////////////////////////////
// Ініціалізація фабрики класа і guid
IMPLEMENT_OLECREATE_EX(CBoxerCtrl, "BOXER.BoxerCtrl.1",
0xb2c1e6, 0х95а2, Ox11dO, 0x88, 0x60, 0x44, 0x45, 0x53, 0x54, 0, 0)
/////////////////////////////////////////////////////////////////////////
// Ідентифікатор бібліотеки типа і версія
IMPLEMENT_OLETYPELIB(CBoxerCtrl, _tlid, _wVerMajor,
_wVerMinor)
/////////////////////////////////////////////////////////////////////////
// Ідентифікатори інтерфейсів
const IID BASED_CODE IID_DBoxer =
{ 0xb2c1e4, 0x95a2, 0x11d0, { 0x88, 0x60, 0x44, 0x45,
0x53, 0x54, 0, 0 } };
const IID BASED_CODE IID_DBoxerEvents =
{ 0xb2c1e5, 0x95a2, 0x11d0, { 0x88, 0x60, 0x44, 0x45,
0x53, 0x54, 0, 0 } };
/////////////////////////////////////////////////////////////////////////
// Інформація типа для елемента
static const DWORD BASED_CODE _dwBoxerOleMisc =
OLEMISC_ACTIVATEWHENVISIBLE |
OLEMISC_SETCLIENTSITEFIRST |
OLEMISC_INSIDEOUT |
OLEMISC_CANTLINKINSIDE |
OLEMISC_RECOMPOSEONRESIZE;
IMPLEMENT_OLECTLTYPE(CBoxerCtrl, IDS_BOXER, _dwBoxerOleMisc)
/////////////////////////////////////////////////////////////////////////
// CBoxerCtrl::CBoxerCtrlFactory::UpdateRegistry -
// додає або видаляє записи системного реєстру для CBoxerCtrl
BOOL CBoxerCtrl::CBoxerCtrlFactory::UpdateRegistry(
BOOL bRegister)
{
// Переконайтеся, що ваш елемент відповідає вимогам
// спільної потокової моделі. Подробиці наведені
// у документі MFC TechNote 64.
// Якщо елемент порушує вимоги спільної моделі,
// необхідно модифікувати наступний фрагмент
// програми і замінити другу параметр з
// afxRegApartmentThreading на 0.
if (bRegister)
return AfxOleRegisterControlClass(
AfxGetInstanceHandle(),
m_clsid,
m_lpszProgID,
IDS_BOXER,
IDB_BOXER,
afxRegApartmentThreading,
_dwBoxerOleMisc,
_tlid,
_wVerMajor,
_wVerMinor);
else
return AfxOleUnregisterClass(m_clsid,
m_lpszProgID);
}
/////////////////////////////////////////////////////////////////////////
// CBoxerCtrl::CBoxerCtrl - конструктор
CBoxerCtrl::CBoxerCtrl()
{
InitializeIIDs(&IID_DBoxer, &IID_DBoxerEvents);
// ЗРОБИТИ: ініциалізуйте дані екземпляра
// вашого елемента.
fill1 = fill2 = fill3 = fill4 = false;
}
/////////////////////////////////////////////////////////////////////////
// CBoxerCtrl::"CBoxerCtrl - деструктор
CBoxerCtrl::~CBoxerCtrl()
{
// ЗРОБИТИ: знищіть дані екземпляра вашого елемента.
}
/////////////////////////////////////////////////////////////////////////
// CBoxerCtrl::OnDraw - функція малювання
void CBoxerCtrl::OnDraw(
CDC* pdc, const CRect& rcBounds,
const CRect& rcInvalid)
{
pdc->FillRect(rcBounds,
CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH)));
box1 = CRect(rcBounds.left, rcBounds.top,
rcBounds.right/2, rcBounds.bottom/2);
box2 = CRect(rcBounds.left, rcBounds.bottom/2,
rcBounds.right/2, rcBounds.bottom);
box3 = CRect(rcBounds.right/2, rcBounds.top,
rcBounds.right, rcBounds.bottom/2);
box4 = CRect(rcBounds.right/2, rcBounds.bottom/2,
rcBounds.right, rcBounds.bottom);
pdc->Rectangle(&box1);
pdc->Rectangle(&box2);
pdc->Rectangle(&box3);
pdc->Rectangle(&box4);
if(fill1) pdc->FillSolidRect(&box1, RGB(0, 0, 0));
if(fill2) pdc->FillSolidRect(&box2, RGB(0, 0, 0));
if(fill3) pdc->FillSolidRect(&box3, RGB(0, 0, 0));
if(fill4) pdc->FillSolidRect(&box4, RGB(0, 0, 0));
}
/////////////////////////////////////////////////////////////////////////
// CBoxerCtrl::DoPropExchange – підтримка стійкості
void CBoxerCtrl::DoPropExchange(CPropExchange* pPX)
{
ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
COleControl::DoPropExchange(pPX);
// ЗРОБИТИ: Викличте функції РХ_ для кожної стійкої
// властивості.
}
/////////////////////////////////////////////////////////////////////////
// CBoxerCtrl::OnResetState - сброс елемента у стан по
// замовчуванню
void CBoxerCtrl::OnResetState()
{
COleControl::OnResetState(); // Присвоює значення
// по замовчанню із DoPropExchange
// Скиньте будь-які інші параметри стану елемента
}
/////////////////////////////////////////////////////////////////////////
// CBoxerCtrl::AboutBox - відображення діалогового вікна About
void CBoxerCtrl::AboutBox()
{
CDialog dlgAbout(IDD_ABOUTBOX_BOXER);
dlgAbout.DoModal();
}
/////////////////////////////////////////////////////////////////////////
// Обробники повідомлень CBoxerCtrl
void CBoxerCtrl::OnLButtonDown(UINT nFlags, CPoint point)
{
// ЗРОБИТИ: додайте код обробки повідомлення
// і/або викличте обробник по замовчуванню
fill1 = box1.PtInRect(point);
fill2 = box2.PtInRect(point);
fill3 = box3.PtInRect(point);
fill4 = box4.PtInRect(point);
Invalidate();
COleControl::OnLButtonDown(nFlags, point);
}
Ми подивилися, як створити елемент керування ActiveX і організувати його малювання. Однак на цьому можливості ActiveX не вичерпуються – керуючі елементи можуть також мати події, методи та властивості. Зараз ми познайомимося з цією темою докладніше.