介紹:
利用vc中的嚮導來建立activex控件很方便。這篇文章不許備告訴activex的原理,它將一步步的告訴你如何創建一個簡單的activex控件,其中主要介紹事件和屬性頁的編程,若是想知道其中的道理,我想你還須要讀一些相關的書籍。本文是講述mfc建立activex控件,若是想學習atl建立activex,請不要看此文。
編程
建立控件函數
使用嚮導創建activex control工程工具
選擇file中的new,而後選擇MFC ActiveX Control Wizard學習
輸入工程的名稱測試
選中全部的默認設置點擊next字體
若是想子類話的話能夠從combobox中選擇相應的類ui
點擊結束按鈕完成。此時產生以下代碼spa
C**App - 派生自 COleControlModule. 這個類提供了控件類的初始化initialization (InitInstance) 和 銷燬代碼(ExitInstance).code
C**Ctrl - 派生自COleControl 提供控件的大部分功能,這個類是你須要編寫大部分代碼的部orm
C**PropPage - C**PropPage, (派生自 COlePropertyPage)。這個類主要操縱控件的屬性頁
編譯控件,將生成.ocx的文件。這是vc自帶的測試控件的容器將幫助咱們來測試控件。點擊tool->activex control test container。在container中的工具欄中點擊new control 咱們選取咱們剛纔創建的工程好比smaple,咱們會發現其中畫了一個橢圓。以下圖。
事件:
咱們在使用mfc的控件會發現控件會提供一些事件,最簡單的例子是按鈕這種控件提供click事件,也就是當用戶點擊按鈕的時候會進行一些用戶自定義的處理過程,這就是最簡單的控件事件。Activex既然是一種控件,那麼要想使其功能豐富天然少不了事件的支持。
Activex控件中有兩種事件,一種是stock即系統定義的事件,一種是custom也就是用戶自定義的事件。讓咱們首先來看看stock事件如何處理。
Stock:
1. 點擊classwiard中activex events屬性頁
2. 點擊add event…按鈕
3. 咱們若是從extanal name中選取已有的就是stock事件,也就是系統定義好的,固然咱們須要在下面選擇stock,不能選擇custom。咱們在這裏選擇Dblstock
4. 結束
這時咱們就建立了一個stock的事件,也就是雙擊事件。咱們來測試一下。
選擇tool->activex control test container,而後在控件上雙擊就會發現下面會打印處雙擊消息,也就是控件響應了咱們的雙擊
custom:
下面咱們介紹如何定義用戶自定義事件
咱們想完成如下功能,若是用戶鼠標在圓或者橢圓內作的點擊操做則觸發一個事件。
1.擊classwiard中activex events屬性頁
2.點擊add event…按鈕
3.在exteranl name裏面填寫ClickIn
4.結束
如今咱們就定義好了這個事件。關鍵是咱們要考慮如何觸發這個事件。也就是當咱們在圓或者橢圓內單擊鼠標左鍵的時候要觸發這個事件。這裏咱們能夠想到要添加一個lbuttondown消息。
1.Classwizrd中肯定選擇CSampleCtrl類
2.添加消息WM_LBUTTONDOWN
3.結束
在類CsampleCtrl添加一個成員函數BOOL CSample3Ctrl::InCircle(CPoint& point)
函數內容以下:
CRect rc;
GetClientRect(rc);
// Determine radii
double a = (rc.right - rc.left) / 2;
double b = (rc.bottom - rc.top) / 2;
// Determine x, y
double x = point.x - (rc.left + rc.right) / 2;
double y = point.y - (rc.top + rc.bottom) / 2;
// Apply ellipse formula
return ((x * x) / (a * a) + (y * y) / (b * b) <= 1);
而後編譯LBUTTONDOWN的響應函數
void CCirc3Ctrl::OnLButtonDblClk(UINT nFlags, CPoint point)
{
// Flash the color of the control if within the ellipse.
if (InCircle(point))
{
FireClickIn();
}
COleControl::OnLButtonDblClk(nFlags, point);
}
到這裏咱們就完成ClickIn事件的編寫和響應過程,讓咱們來測試一下。
咱們能夠添加一些畫圖操做來使得事件表現得更明顯,更改代碼以下:
static int i = 0;
if (InCircle(point))
{
FireClickIn();
CString num;
CBrush brush;
CDC* pDC = GetDC();
CRect rt;
GetClientRect(rt);
CRgn rgn;
rgn.CreateEllipticRgnIndirect(rt);
num.Format("%d", j);
brush.CreateSolidBrush(RGB(0, 0, 255));
pDC->FillRgn(&rgn, &brush);
pDC->SetBkMode(TRANSPARENT);
pDC->TextOut((rt.left + rt.right) / 2, (rt.top + rt.bottom) / 2, num);
}
這樣每一次點擊都會在圓或者橢圓中間輸出點擊的累計次數。到這裏咱們已經簡單的介紹了在利用mfc編寫activex控件的事件的處理,下面咱們看看activex控件的屬性頁編程。
屬性頁:
在咱們利用mfc提供的控件中咱們能夠設置一些屬性來改變控件的表現形式,仍是拿按鈕舉例,按鈕屬性當中有visible這個選項,咱們能夠經過設置這個屬性來改變按鈕是否可見。下面咱們就看看activex控件的屬性頁編程。
屬性頁分爲兩種,一種是系統內建的屬性頁,好比說背景色,字體等;一種是用戶自定義的屬性頁。咱們首先來看系統內建的屬性頁,在這裏咱們來設置背景色
stock屬性頁
1.在classwizard中的automation中點擊add property,而後從external name中選擇BackColor和ForeColor
2.在CSampleCtrl的.CPP文件中更改代碼
BEGIN_PROPPAGEIDS(CSampleCtrl, 1)
PROPPAGEID(CLSID_CColorPropPage)
END_PROPPAGEIDS(CSampleCtrl)
而後測試以下
custom屬性頁:
1.建立一個對話框資源(size 250x62 or 250x110 dialog units)或者在創建對話框中選擇insert而後選擇對話框中的IDD_OLE_PROPPAGE_SMALL就能夠了。
2.而後雙擊該對話框建立新的類,取名CmyProperty,基類選擇ColePropertyPate。
3.而後在該對話框上放置一個checkbox控件,取名Erase。
4.在classwiard中的automaition中選擇add property(CSampleCtrl)external name 填erase,類型選擇BOOL其它默認,implement選擇member variable。
5.在classwizard中選擇類CmyProperty,而後爲checkbox添加成員變量。變量名爲m_bErase,類型BOOL,optinal property name填寫剛纔新添加的用戶自定義的屬性名Erase。
6.在資源的string table中添加兩個string一個是新建屬性頁的標題一個是新建屬性頁的名字,在這裏咱們咱們設置的值是IDS_PPG_OPTIONS(options)和IDS_PPG_OPTIONS_CAPTION(caption)固然這個用戶能夠自行修改。
7.更改CmyProperty的cpp文件以下:
BOOL CMyProperty::CMyPropertyFactory::UpdateRegistry(BOOL bRegister)
{
if (bRegister)
return AfxOleRegisterPropertyPageClass(AfxGetInstanceHandle(),m_clsid,IDS_PPG_OPTIONS);
else
return AfxOleUnregisterClass(m_clsid, NULL);
}
CMyProperty::CMyProperty() :
COlePropertyPage(IDD, IDS_PPG_OPTIONS_CAPTION)
{
//{{AFX_DATA_INIT(CMyProperty)
m_bErase = FALSE;
//}}AFX_DATA_INIT
}
8.最後在CSampleCtrl的cpp文件中修改以下代碼:
BEGIN_PROPPAGEIDS(CSampleCtrl, 2)
PROPPAGEID(CLSID_CColorPropPage)
PROPPAGEID(CMyProperty::guid)
END_PROPPAGEIDS(CSampleCtrl)
記住必定要把計數從1改成2,同時添加#include "myproperty.h"
9.在CSampleCtrl中修改以下代碼
void CSampleCtrl::DoPropExchange(CPropExchange* pPX)
{
ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
COleControl::DoPropExchange(pPX);
PX_Bool(pPX, _T("Erase"), FALSE);
}
void CSampleCtrl::OnEraseChanged()
{
InvalidateControl();
SetModifiedFlag();
}
void CSampleCtrl::OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
{
pdc->FillRect(rcBounds, CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH)));
CBrush bkBrush(TranslateColor(GetBackColor()));
pdc->FillRect(rcBounds, &bkBrush);
if (m_erase)
{
pdc->MoveTo(rcBounds.left, (rcBounds.top + rcBounds.bottom) / 2);
pdc->LineTo(rcBounds.right, (rcBounds.top + rcBounds.bottom) / 2);
}
pdc->Ellipse(rcBounds);
}
到這裏基本完成了咱們的控件,也展現了activex控件事件和屬性頁的編程。Enjoy it.