利用mfc编写activex控件

介绍:
      
利用 vc 中的向导来创建 activex 控件很方便。这篇文章不准备告诉你 activex控件 的原理,它将一步步的告诉你如何建立一个简单的 activex 控件,其中主要介绍事件和属性页的编程,如果想知道其中的道理,我想你还需要读一些相关的书籍。本文是讲述 mfc 创建 activex 控件,如果想学习 ATL 创建 activex控件 ,请不要看此文。

创建控件

  1. 使用向导建立activex control工程
  2. 选择file中的new,然后选择MFC ActiveX Control Wizard
  3. 输入工程的名称
  4. 选中所有的默认设置点击next
  5. 如果想子类话的话可以从combobox中选择相应的类
  6. 点击结束按钮完成。此时产生如下代码
    • C**App - 派生自 COleControlModule.  这个类提供了控件类的初始化initialization (InitInstance销毁代码(ExitInstance).
    • C**Ctrl - 派生自COleControl 提供控件的大部分功能,这个类是你需要编写大部分代码的地方
    • 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.      点击classwiardactivex events属性页

2.      点击add event…按钮

3.      我们如果从extanal name中选取已有的就是stock事件(当然我们需要在下面选择stock,不能选择custom)也就是系统定义好的。我们在这里选择Dblstock

4.      结束

    这时我们就创建了一个stock的事件,也就是双击事件。我们来测试一下。选择tool->activex control test container,然后在控件上双击就会发现下面会打印出双击消息,也就是控件响应了我们的双击



事件之custom:


下面我们介绍如何定义用户自定义事件

我们想完成以下功能,如果用户鼠标在圆或者椭圆内做点击操作则触发一个事件。

1.classwiardactivex events属性页

2.点击add event…按钮

3.exteranl name里面填写ClickIn

4.结束


现在我们就定义好了这个事件。关键是我们要考虑如何触发这个事件。也就是当我们在圆或者椭圆内单击鼠标左键的时候要触发这个事件。这里我们可以想到在CSampleCtrl中添加一个
WM_LBUTTONDOWN消息。

1.Classwizrd中确定选择CSampleCtrl

2.添加消息WM_LBUTTONDOWN

3.结束


在类
CsampleCtrl添加一个成员函数BOOL CSampleCtrl::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)
    {
         if (InCircle(point))
         {
              FireClickIn();     //触发事件
          }
         COleControl::OnLButtonDblClk(nFlags, point);
    }
    

    到这里我们就完成
ClickIn事件的编写和响应过程,让我们来测试一下。



我们可以添加一些画图操作来使得事件表现得更明显,更改代码如下:
    static int i = 0;
    if (InCircle(point))
    {
          FireClickIn();
          i++;
          CString num;
          CBrush brush;
          CDC* pDC = GetDC();
          CRect rt;
          GetClientRect(rt);
          CRgn rgn;
          rgn.CreateEllipticRgnIndirect(rt);
          num.Format("%d", i);
          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中选择BackColorForeColor

2.CSampleCtrl.CPP文件中更改代码

BEGIN_PROPPAGEIDS(CSampleCtrl, 1)
            PROPPAGEID(CLSID_CColorPropPage)
END_PROPPAGEIDS(CSampleCtrl)
更改CSampleCtrl中的OnDraw函数添加代码
CBrush bkBrush(TranslateColor(GetBackColor()));
pdc->FillRect(rcBounds, &bkBrush);
把其放置到绘制椭圆之后测试如下



属性页之custom

1.创建一个对话框资源(size 250x62 or 250x110 dialog units)或者在建立对话框中选择insert然后选择对话框中的IDD_OLE_PROPPAGE_SMALL就可以了。

2.然后双击该对话框创建新的类,取名CMyProperty,基类选择ColePropertyPate

3.然后在该对话框上放置一个checkbox控件,取名Erase

4.classwiard中的automaition中选择add propertyCSampleCtrlexternal name erase,类型选择BOOL其它默认,implement选择member variable

5.classwizard中选择类CMyProperty,然后为checkbox添加成员变量。变量名为m_bErase,类型BOOLoptinal property name填写刚才新添加的用户自定义的属性名Erase

6.在资源的string table中添加两个string一个是新建属性页的标题,一个是新建属性页的名字,在这里我们设置的值是IDS_PPG_MYPROPERTYoptions)和IDS_PPG_MYPROPERTY_CAPTIONcaption)当然这个用户可以自行修改。

7.更改CMyPropertycpp文件如下:
BOOL CMyProperty::CMyPropertyFactory::UpdateRegistry(BOOL bRegister)
{
   if (bRegister)
        return AfxOleRegisterPropertyPageClass(AfxGetInstanceHandle(),m_clsid, IDS_PPG_MYPROPERTY);
   else
         return AfxOleUnregisterClass(m_clsid, NULL);
}

    CMyProperty::CMyProperty() :COlePropertyPage(IDD, IDS_PPG_MYPROPERTY_CAPTION)
{
   //{{AFX_DATA_INIT(CMyProperty)
   m_bErase = FALSE;
   //}}AFX_DATA_INIT
}

    

8.最后在CSampleCtrlcpp文件中修改如下代码:

    BEGIN_PROPPAGEIDS(CSampleCtrl, 2)
       PROPPAGEID(CLSID_CColorPropPage)
       PROPPAGEID(CMyProperty::guid)
    END_PROPPAGEIDS(CSampleCtrl)

    记住一定要把计数从
1改为2,同时添加#include "myproperty.h"

9.CSampleCtrl中修改如下代码


 
  
 
  
    到这里基本完成了我们的控件,也展示了activex控件事件和属性页的编程。Enjoy it.

    










author:simahao time:05.1.10



你可能感兴趣的:(VC/C/C++)