Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Visual2.doc
Скачиваний:
5
Добавлен:
07.03.2016
Размер:
3.31 Mб
Скачать

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).

Виконайте в тестовому контейнері команду EditInsert 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 не вичерпуються – керуючі елементи можуть також мати події, методи та властивості. Зараз ми познайомимося з цією темою докладніше.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]