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

12.5. Відображення елементів ActiveX

За допомогою АррWizard створіть нову програму на базі діалогового вікна і надайте їй ім'я Buttonerapp. Увімкніть елемент Buttoner у палітру редактора діалогових вікон. Для цього слід викликати вікно Components and Controls Gallery, про що розповідалося в попередньому прикладі. Коли Visual C++ запропонує вказати ім'я класу елемента, підтвердіть запропоноване за замовчуванням ім'я CButtoner.

Тепер ми додамо елемент Buttoner у нову програму за допомогою редактора діалогових вікон (рис. 12.12). Він привласнює елементу ідентифікатор ID_BUTTONERCTRL1.

Рис. 12.12. Елемент Buttoner у новій програмі

Розмістіть над елементом Buttoner напис Клацніть елемент Buttoner, а під ним – текстове поле для виведення відомостей про кількість клацань. Вміст поля буде визначатись методом GetData(), що повертає значення властивості data.

За допомогою ClassWizard зв'яжіть з елементом Buttoner змінну m_buttoner (рис. 12.13). Зверніть увагу: вона належить створеному класу CButtoner. Крім того, зв'яжіть вміст текстового поля зі змінною m_text (див. рис. 12.13).

Елемент Buttoner впроваджений у додаток Buttonerapp, і для виклику його методів (наприклад, Beep()) можна користуватися записом виду m_buttoner.Beep().

Зв'язування елемента ActiveX з кодом програми

У ClassWizard ми створимо обробник для події Click елемента Buttoner. Знайдіть подію у вікні ClassWizard (рис. 12.14) і створіть новий обробник, якому ClassWizard привласнює ім'я OnClickButtonerctrl1():

Рис. 12.13. Створення змінної для елемента ActiveX

void CButtonerappDlg::OnClickButtonerctrl1()

{

// ЗРОБИТИ: додайте код обробки події

// і/або викличте обробник за замовчуванням

}

Цей метод буде викликатися при кожному клацанні мишею на елементі. Щоб дізнатися, скільки разів користувач клацнув на елементі, слід визначити значення властивості data, а для цього потрібно викликати метод GetData():

Рис. 12.14. Створення обробника для події від елемента ActiveX

void CButtonerappDlg::OnClickButtonerctrl1()

{

m_text.Format("свойство data = %ld",

m_buttoner.GetData());

UpdateData(false);

}

Тепер при кожному натисканні на елементі програма Buttonerapp буде виводити загальну кількість клацань, що зберігається у властивості data (рис. 12.15).

На прикладі елемента Buttoner ми дізналися багато нового: як створити елемент ActiveX на базі існуючого керуючого елемента та як організувати в ньому підтримку подій, методів і властивостей.

Оригінальний текст елемента Buttoner міститься у файлах ButtonerCtl.h/ButtonerCtl.cpp, а вихідний текст програми Buttonerapp – у файлах ButtonerappDlg.h/ButtonerappDlg.cpp.

Рис. 12.15. Використання властивостей і методів елемента ActiveX

ButtonerCtl.h і ButtonerCtl.cpp

#if !defined(AFX_BUTTONERCTL_H__6AE5A16F_9584_11D0_8860_444553540000__INCLUDED_)

#define AFX_BUTTONERCTL_H__6AE5A16F_9584_11D0_8860_444553540000__INCLUDED_

#if _MSC_VER >= 1000

#pragma once

#endif // _MSC_VER >= 1000

// ButtonerCtl.h : заголовок класа елемента ActiveX CButtonerCtrl.

/////////////////////////////////////////////////////////////////////////

// CButtonerCtrl : реалізація міститься в ButtonerCtl.cpp.

class CButtonerCtrl : public COleControl

{

DECLARE_DYNCREATE(CButtonerCtrl)

// Конструктор

public:

CButtonerCtrl();

// Перевантаження

// Перевантажені віртуальні функції,

// сформовані ClassWizard-ом.

//{{AFX_VIRTUAL(CButtonerCtrl)

public:

virtual void OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid);

virtual void DoPropExchange(CPropExchange* pPX);

virtual void OnResetState();

//}}AFX_VIRTUAL

// Реалізація

protected:

~CButtonerCtrl();

DECLARE_OLECREATE_EX(CBoxerCtrl) // Фабрика класа і guid

DECLARE_OLETYPELIB(CBoxerCtrl) // GetTypeInfo

DECLARE_PROPPAGEIDS(CBoxerCtrl) // Ідентификатори сторінок властивостей

DECLARE_OLECTLTYPE(CBoxerCtrl) // Імя типа і

// допоміжна інформація

// Підтримка субкласування

BOOL PreCreateWindow(CREATESTRUCT& cs);

BOOL IsSubclassedControl();

LRESULT OnOcmCommand(WPARAM wParam, LPARAM lParam);

// Карта повідомлень

//{{AFX_MSG(CButtonerCtrl)

afx_msg void OnLButtonDown(UINT nFlags, CPoint point);

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

// Диспетчерські схеми

//{{AFX_DISPATCH(CButtonerCtrl)

short m_data;

afx_msg void OnDataChanged();

afx_msg void Beep();

//}}AFX_DISPATCH

DECLARE_DISPATCH_MAP()

afx_msg void AboutBox();

// Схеми событий

//{{AFX_EVENT(CButtonerCtrl)

//}}AFX_EVENT

DECLARE_EVENT_MAP()

// Диспетчерські ідентифікатори та ідентифікатори подій

public:

enum {

//{{AFX_DISP_ID(CButtonerCtrl)

dispidData = 1L,

dispidBeep = 2L,

//}}AFX_DISP_ID

};

};

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ буде вставляти в додаток

// оголошення перед попереднім рядком.

#endif // !defined(AFX_BUTTONERCTL_H__6AE5A16F_9584_11D0_8860_444553540000__INCLUDED_)

// ButtonerCtl.cpp : реалізація класа елемента ActiveX CButtonerCtrl.

#include "stdafx.h"

#include "Buttoner.h"

#include "ButtonerCtl.h"

#include "ButtonerPpg.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

IMPLEMENT_DYNCREATE(CButtonerCtrl, COleControl)

/////////////////////////////////////////////////////////////////////////

// Карта повідомлень

BEGIN_MESSAGE_MAP(CButtonerCtrl, COleControl)

//{{AFX_MSG_MAP(CButtonerCtrl)

ON_WM_LBUTTONDOWN()

//}}AFX_MSG_MAP

ON_MESSAGE(OCM_COMMAND, OnOcmCommand)

ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties)

END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////

// Диспетчерська схема

BEGIN_DISPATCH_MAP(CButtonerCtrl, COleControl)

//{{AFX_DISPATCH_MAP(CButtonerCtrl)

DISP_PROPERTY_NOTIFY(CButtonerCtrl, "data", m_data, OnDataChanged, VT_I2)

DISP_FUNCTION(CButtonerCtrl, "Beep", Beep, VT_EMPTY, VTS_NONE)

//}}AFX_DISPATCH_MAP

DISP_FUNCTION_ID(CButtonerCtrl, "AboutBox", DISPID_ABOUTBOX, AboutBox, VT_EMPTY, VTS_NONE)

END_DISPATCH_MAP()

/////////////////////////////////////////////////////////////////////////

// Карта повідомлень

BEGIN_EVENT_MAP(CButtonerCtrl, COleControl)

//{{AFX_EVENT_MAP(CButtonerCtrl)

EVENT_STOCK_CLICK()

//}}AFX_EVENT_MAP

END_EVENT_MAP()

/////////////////////////////////////////////////////////////////////////

// Сторінки властивостей

// ЗРОБИТИ: При необхідності додайте нові

// сторінки властивостей.

// Не забудьте збільшити значення лічильника!

BEGIN_PROPPAGEIDS(CButtonerCtrl, 1)

PROPPAGEID(CButtonerPropPage::guid)

END_PROPPAGEIDS(CButtonerCtrl)

/////////////////////////////////////////////////////////////////////////

// Ініциалізація фабрики класа і guid

IMPLEMENT_OLECREATE_EX(CButtonerCtrl, "BUTTONER.ButtonerCtrl.1",

0x6ae5a161, 0x9584, 0x11d0, 0x88,

0x60, 0x44, 0x45, 0x53, 0x54, 0, 0)

/////////////////////////////////////////////////////////////////////////

// Ідентифікатор бібліотеки типа і версія

IMPLEMENT_OLETYPELIB(CButtonerCtrl, _tlid, _wVerMajor, _wVerMinor)

/////////////////////////////////////////////////////////////////////////

// Ідентифікатори інтерфейсів

const IID BASED_CODE IID_DButtoner =

{ 0x6ae5a15f, 0x9584, 0x11d0, { 0x88, 0x60, 0x44, 0x45,

0x53, 0x54, 0, 0 } };

const IID BASED_CODE IID.DButtonerEvents =

{ 0x6ae5a160, 0x9584, 0x11d0, { 0x88, 0x60, 0x44, 0x45,

0x53, 0x54, 0, 0 } };

/////////////////////////////////////////////////////////////////////////

// Інформація типа для елемента

static const DWORD BASED_CODE _dwButtonerOleMisc =

OLEMISC_ACTIVATEWHENVISIBLE |

OLEMISC_SETCLIENTSITEFIRST |

OLEMISC_INSIDEOUT |

OLEMISC_CANTLINKINSIDE |

OLEMISC_RECOMPOSEONRESIZE;

IMPLEMENT_OLECTLTYPE(CButtonerCtrl,

IDS_BUTTONER, _dwButtonerOleMisc)

/////////////////////////////////////////////////////////////////////////

// CButtonerCtrl::CButtonerCtrlFactory::UpdateRegistry -

// додає або видаляє записи системного реєстра для CBoxerCtrl

BOOL CButtonerCtrl::CButtonerCtrlFactory::UpdateRegistry(

BOOL bRegister)

{

// Переконайтеся, що ваш елемент відповідає вимогам

// спільної потокової моделі. Подробиці наведені

// у документі MFC TechNote 64.

// Якщо елемент порушує вимоги спільної моделі,

// необхідно модифікувати наступний фрагмент

// програми і замінити другу параметр з

// afxRegApartmentThreading на 0.

if (bRegister)

return AfxOleRegisterControlClass(

AfxGetInstanceHandle(),

m_clsid,

m_lpszProgID,

IDS_BUTTONER,

IDB_BUTTONER,

afxRegApartmentThreading,

_dwButtonerOleMisc,

_tlid,

_wVerMajor,

_wVerMinor);

else

return AfxOleUnregisterClass(m_clsid,

m_lpszProgID);

}

/////////////////////////////////////////////////////////////////////////

// CButtonerCtrl::CButtonerCtrl - Конструктор

CButtonerCtrl::CButtonerCtrl()

{

InitializeIIDs(&IID_DButtoner, &IID_DButtonerEvents);

SetText("Нажми меня!");

// ЗРОБИТИ: ініциалізуйте дані екземпляра

// вашого елемента.

m_data =0;

}

/////////////////////////////////////////////////////////////////////////

// CButtonerCtrl::""CButtonerCtrl - деструктор

CButtonerCtrl::~CButtonerCtrl()

{

// ЗРОБИТИ: знищіть дані екземпляра вашого елемента.

}

/////////////////////////////////////////////////////////////////////////

// CButtonerCtrl::OnDraw - функція малювання

void CButtonerCtrl::OnDraw(CDC* pdc, const CRect& rcBounds,

const CRect& rcInvalid)

{

DoSuperclassPaint(pdc, rcBounds);

}

/////////////////////////////////////////////////////////////////////////

// CButtonerCtrl::DoPropExchange – підтримка стійкості

void CButtonerCtrl::DoPropExchange(CPropExchange* pPX)

{

ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));

COleControl::DoPropExchange(pPX);

// ЗРОБИТИ: Викличте функції РХ_ для кажної стійкої

// властивості.

}

/////////////////////////////////////////////////////////////////////////

// CButtonerCtrl::OnResetState - сброс елемента у стан по

// замовчанню

void CButtonerCtrl::OnResetState()

{

COleControl::OnResetState();// Присвоює значення

// по замовчанню із DoPropExchange

// Скиньте будь-які інші параметри стану елемента

}

/////////////////////////////////////////////////////////////////////////

// CButtonerCtrl::AboutBox - відображення діалогового

// вікна About

void CButtonerCtrl::AboutBox()

{

CDialog dlgAbout(IDD_ABOUTBOX_BUTTONER);

dlgAbout.DbModal();

}

/////////////////////////////////////////////////////////////////////////

// CButtonerCtrl::PreCreateWindow – Зміна параметрів

// для CreateWindowEx

BOOL CButtonerCtrl::PreCreateWindow(CREATESTRUCT& cs)

{

cs.lpszClass = _T("BUTTON");

return COleControl::PreCreateWindow(cs);

}

/////////////////////////////////////////////////////////////////////////

// CButtonerCtrl::IsSubclassedControl – субкласований елемент

BOOL CButtonerCtrl::IsSubclassedControl()

{

return TRUE;

}

/////////////////////////////////////////////////////////////////////////

// CButtonerCtrl::OnOcmCommand – обробка командних повідомлень

LRESULT CButtonerCtrl::OnOcmCommand(WPARAM wParam,

LPARAM lParam)

{

#ifdef _WIN32

WORD wNotifyCode = HIWORD(wParam);

#else

WORD wNotifyCode = HIWORD(lParam);

#endif

// ЗРОБИТИ: Переключитись на wNotifyCode.

return 0;

}

/////////////////////////////////////////////////////////////////////////

// Обробники повідомлень CButtonerCtrl

void CButtonerCtrl::OnLButtonDown(UINT nFlags, CPoint point)

{

// ЗРОБИТИ: додайте код обробки повідомлення

// і/або викличте обробник по замовчуванню

FireClick();

m_data++;

COleControl::OnLButtonDown(nFlags, point);

}

void CButtonerCtrl::OnDataChanged()

{

// ЗРОБИТИ: додайте код для обробки повідомлень

// від елемента

SetModifiedFlag();

}

void CButtonerCtrl::Beep()

{

// ЗРОБИТИ: додайте код диспетчерської обробки

MessageBeep(MB_OK);

}

ButtonerappDlg.h і ButtonerappDlg.cpp

// ButtonerappDlg.h : заголовочний файл

//

//{{AFX_INCLUDES()

#include "buttoner.h"

//}}AFX_INCLUDES

#if !defined(AFX_BUTTONERAPPDLG_H__9F6EEC67_988A_11D0_8860_444553540000__INCLUDED_)

#define AFX_BUTTONERAPPDLG_H__9F6EEC67_988A_11D0_8860_444553540000__INCLUDED_

#if _MSC_VER >= 1000

#pragma once

#endif // _MSC_VER >= 1000

/////////////////////////////////////////////////////////////////////////

// Діалогове вікно CButtonerappDlg

class CButtonerappDlg : public CDialog

{

// Construction

public:

CButtonerappDlg(CWnd* pParent = NULL);

// Стандартный конструктор

// Данні діалогового вікна

//{{AFX_DATA(CButtonerappDlg)

enum { IDD = IDD_BUTTONERAPP_DIALOG };

CString m_text;

CButtoner m_buttoner;

//}}AFX_DATA

// Перевантаження

// Перевантажені віртуальні функції,

// сформовані ClassWizard-ом.

//{{AFX_VIRTUAL(CButtonerappDlg)

protected:

virtual void DoDataExchange(CDataExchange* pDX);

// Поддержка DDX/DDV

//}}AFX_VIRTUAL

// Реалізація

protected:

HICON m_hIcon;

// Сформовані функції карти повідомлень

//{{AFX_MSG(CButtonerappDlg)

virtual BOOL OnInitDialog();

afx_msg void OnSysCommand(UINT nID, LPARAM lParam);

afx_msg void OnPaint();

afx_msg HCURSOR OnQueryDragIcon();

afx_msg void OnClickButtonerctrl1();

DECLARE_EVENTSINK_MAP()

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

};

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ буде вставляти додаткові

// оголошення перед попереднім рядком.

#endif // !defined(AFX_BUTTONERAPPDLG_H__9F6EEC67_988A_11D0_8860_444553540000__INCLUDED_)

// ButtonerappDlg.cpp : файл реалізації

//

#include "stdafx.h"

#include "Buttonerapp.h"

#include "ButtonerappDlg.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

/////////////////////////////////////////////////////////////////////////

// Діалогове вікно CAboutDlg, що виводиться по команді About

class CAboutDlg : public CDialog

{

public:

CAboutDlg();

// Данні діалогового вікна

//{{AFX_DATA(CAboutDlg)

enum { IDD = IDD_ABOUTBOX };

//}}AFX_DATA

// Перевантаження

// Перевантажені віртуальні функції,

// сформовані ClassWizard-ом.

//{{AFX_VIRTUAL(CAboutDlg)

protected:

virtual void DoDataExchange(CDataExchange* pDX);

// Підтримка DDX/DDV

//}}AFX_VIRTUAL

// Реалізація

protected:

//{{AFX_MSG(CAboutDlg)

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)

{

//{{AFX_DATA_INIT(CAboutDlg)

//}}AFX_DATA_INIT

}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)

{

CDialog::DoDataExchange(pDX);

//{{AFX_DATA_MAP(CAboutDlg)

//}}AFX_DATA_MAP

}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)

//{{AFX__MSG_MAP(CAboutDlg)

// No message handlers

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////

// Діалогове вікно CButtonerappDlg

CButtonerappDlg::CButtonerappDlg(CWnd* pParent /*=NULL*/)

: CDialog(CButtonerappDlg::IDD, pParent)

{

//{{AFX_DATA_INIT(CButtonerappDlg)

m_text = _T(M");

//}}AFX_DATA_INIT

// Зверніть увагу на те, що в Win32 LoadIcon

// не вимагає подальшого виклику DestroyIcon

m_hIcon = AfxGetApp()->Loadrcon(IDR_MAINFRAME);

}

void CButtonerappDlg::DoDataExchange(CDataExchange* pDX)

{

CDialog::DoDataExchange(pDX);

//{{AFX_DATA_MAP(CButtonerappDlg)

DDX_Text(pDX, IDC_EDIT1, m_text);

DDX_Control(pDX, IDC_BUTTONERCTRL1, m_buttoner);

//}}AFX_DATA_MAP

}

BEGIN_MESSAGE_MAP(CButtonerappDlg, CDialog)

//{{AFX_MSG_MAP(CButtonerappDlg)

ON_WM_SYSCOMMAND()

ON_WM_PAINT()

ON_WM_QUERYDRAGICON()

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////

// Обробники повідомлень CButtonerappDlg

BOOL CButtonerappDlg::OnInitDialog()

{

CDialog::OnInitDialog();

// Додати команду "About..." у системне меню.

// Значення IDM_ABOUTBOX повинно знаходитись у діапазоні

// системних команд.

ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);

ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);

if (pSysMenu != NULL)

{

CString strAboutMenu;

strAboutMenu.LoadString(IDS_ABOUTBOX);

if (!strAboutMenu.IsEmpty())

{

pSysMenu->AppendMenu(MF_SEPARATOR);

pSysMenu->AppendMenu(MF_STRING,

IDM_ABOUTBOX, strAboutMenu);

}

}

// Поставити значок для діалогового вікна. Бібліотека

// робить це автоматично, якщо головне вікно програми

// не є діалоговим.

SetIcon(m_hIcon, TRUE); // Встановити великий значок

SetIcon(m_hIcon, FALSE); // Встановити малий значок

// ЗРОБИТИ: додайте додаткову ініціалізацію

return TRUE; // повернути TRUE, якщо тільки ви

// не передаєте фокус елементу

}

void CButtonerappDlg::OnSysCommand(UINT nID, LPARAM lParam)

{

if ((nID & 0xFFF0) == IDM_ABOUTBOX)

{

CAboutDlg dlgAbout;

dlgAbout.DoModal();

}

else

{

CDialog::OnSysCommand(nID, lParam);

}

}

// Поставити значок для діалогового вікна. Бібліотека

// робить це автоматично, якщо головне вікно програми

// не є діалоговим.

void CButtonerappDlg::OnPaint()

{

if (IsIconic())

{

CPaintDC dc(this); // контекст пристрою для

// малювання

SendMessage(WM_ICONERASEBKGND,

(WPARAM) dc.GetSafeHdc(), 0);

// Вивести значок в центрі

// клієнтського прямокутника

int cxIcon = GetSystemMetrics(SM_CXICON);

int cyIcon = GetSystemMetrics(SM_CYICON);

CRect rect;

GetClientRect(&rect);

int x = (rect.Width() - cxIcon + 1) / 2;

int y = (rect.Height() - cyIcon + 1) / 2;

// Намалювати значок

dc.DrawIcon(x, y, m_hIcon);

}

else

{

CDialog::OnPaint();

}

}

// Викликається системою для отримання вказівки,

// відображаємого при перетаскуванні згорнутого вікна.

HCURSOR CButtonerappDlg::OnQueryDragIcon()

{

return (HCURSOR) m_hIcon;

}

BEGIN_EVENTSINK_MAP(CButtonerappDlg, CDialog)

//{{AFX_EVENTSINK_MAP(CButtonerappDlg)

ON_EVENT(CButtonerappDlg, IDC_BUTTONERCTRL1,

-600 /* Click */, OnClickButtonerctrl1, VTS_NONE)

//}}AFX_EVENTSINK_MAP

END_EVENTSINK_MAP()

void CButtonerappDlg::OnClickButtonerctrl1()

{

// ЗРОБИТИ: додайте код для оброби повідомлень

// від елемента

m_buttoner.Beep();

m_text.Format("свойство data = %ld",

m_buttoner.GetData());

UpdateData(false);

}

У цьому розділі ми дізналися багато нового і отримали уявлення про те, як створювати елементи ActiveX і малювати їх, як створювати їх на базі інших керуючих елементів Windows, як підтримувати події, методи і властивості ActiveX. Користуючись цими прийомами, ви зможете створювати власні елементи ActiveX і використовувати їх у своїх програмах. Наступний розділ присвячений налагодженню, і ця тема цілком логічно завершує матеріал посібника.

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