简单介绍 VC2003 使用 ATL 开发 ActiveX 控件

使用MFC开发ActiveX控件,简单明了直接。缺点是需要附带MFC的动态链接库,于是决定选用ATL进行开发。

搜索了一把,只有英文MSDN上面有开发例程,于是照葫芦画瓢,做了一遍,将其中的部分内容翻译摘录一下:

MSDN 链接:http://msdn2.microsoft.com/en-us/library/1byykx68(VS.80).aspx

第一步:创建ATL项目
  使用新建项目->VC++项目->ATL,选择 ATL 项目,输入项目名字,进入创建项目向导,选择好对应的属性(动态链接库),VC2003将自动生成一个框架,内含:
  项目代码(.c, .cpp),模块定义文件(.def),接口定义语言文件(.idl),注册脚本(.rgs),以及其他的资源文件等

第二步:添加一个 ATL 对象(Class)
  在类视图中,在项目上点击右键,选择“添加->添加类”,在类选择框中,选择 VC++ ->ATL 中的“ATL 控件”,出现 ATL 控件向导对话框,在向导的“名称”选项卡,“简称”(Short name)中,填写你的 ActiveX 控件的名字,如PolyCtl,这个名字就是控件注册后使用的名字。其他选项基本选择默认。如果想使用,可以用鼠标悬停在相应项上查看简单说明。

  在“选项”里面,选择支持“连接点”,可以让生成的控件调用外部实现接口,即执行特定页面函数的实现。

  VC6 中,需要手工选择支持 IError 等接口。
第三步:设置控件的属性和实现
  例程的控件是实现绘出一个正多边形,多边形的边数可以调整。并能够响应鼠标左键点击事件,点击事件将判断鼠标点击的位置,并根据情况调用两个外部实现函数。
  在类视图的 IPolyCtl 上点击右键,选择“添加->添加属性”,添加一个 short 类型的属性,名字为 Sides,其他属性选默认,点击完成,向导将自动添加 get_Sides 和 put_Sides 的实现函数,这两个函数是外界取得 ActiveX 控件属性的时候被隐式调用的。

  为控件类添加一个成员变量 short m_nSides 来存储多边形的边数。在类构造函数中将其初始化为 3。
  在 get_Sides 和 put_Sides 中分别实现存取:

STDMETHODIMP CPolyCtl::get_Sides( short   * pVal)
{
   
* pVal  =  m_nSides;
   
return  S_OK;
}
STDMETHODIMP CPolyCtl::put_Sides(
short  newVal)
{
   
if  (newVal  >   2   &&  newVal  <   101 )
   {
      m_nSides 
=  newVal;
      FireViewChange(); 
//  立即更新窗口
       return  S_OK;
   }
   
else
     
return  Error(_T( " Shape must have between 3 and 100 sides " ));
}

第四步:实现绘图
  为了实现绘出多边形,这里用到了 sin 和 cos 函数,这两个函数包含在 C 头文件 math.h 中,所以需要添加引用 #include <math.h>
  由于使用 Polygon 函数进行绘图,需要在类中添加一个点数组 POINT m_arrPoint[100];
  在类中添加一个函数,用来计算指定矩形区域中多边形每个顶点的位置:

void  CalcPoints( const  RECT &  rc);
void  CPolyCtl::CalcPoints( const  RECT &  rc)
{
   
const   double  pi  =   3.14159265358979 ;
   POINT   ptCenter;
   
double   dblRadiusx  =  (rc.right  -  rc.left)  /   2 ;
   
double   dblRadiusy  =  (rc.bottom  -  rc.top)  /   2 ;
   
double   dblAngle  =   3   *  pi  /   2 ;           //  Start at the top
    double   dblDiff   =   2   *  pi  /  m_nSides;    //  Angle each side will make
   ptCenter.x  =  (rc.left  +  rc.right)  /   2 ;
   ptCenter.y 
=  (rc.top  +  rc.bottom)  /   2 ;

   
//  Calculate the points for each side
    for  ( int  i  =   0 ; i  <  m_nSides; i ++ )
   {
      m_arrPoint[i].x 
=  ( long )(dblRadiusx  *  cos(dblAngle)  +  ptCenter.x  +   0.5 );
      m_arrPoint[i].y 
=  ( long )(dblRadiusy  *  sin(dblAngle)  +  ptCenter.y  +   0.5 );
      dblAngle 
+=  dblDiff;
   }
}

  修改控件类的 OnDraw 函数,实现绘出多边形的效果:

HRESULT CPolyCtl::OnDraw(ATL_DRAWINFO &  di)
{
   RECT
&  rc  =   * (RECT * )di.prcBounds;
   HDC hdc  
=  di.hdcDraw;

   COLORREF    colFore;
   HBRUSH      hOldBrush, hBrush;
   HPEN        hOldPen, hPen;

   
//  Translate m_colFore into a COLORREF type
   OleTranslateColor(m_clrFillColor, NULL,  & colFore);

   
//  Create and select the colors to draw the circle
   hPen  =  (HPEN)GetStockObject(BLACK_PEN);
   hOldPen 
=  (HPEN)SelectObject(hdc, hPen);
   hBrush 
=  (HBRUSH)GetStockObject(WHITE_BRUSH);
   hOldBrush 
=  (HBRUSH)SelectObject(hdc, hBrush);

   Ellipse(hdc, rc.left, rc.top, rc.right, rc.bottom);

   
//  Create and select the brush that will be used to fill the polygon
   hBrush     =  CreateSolidBrush(colFore);
   SelectObject(hdc, hBrush);

   CalcPoints(rc);
   Polygon(hdc, 
& m_arrPoint[ 0 ], m_nSides);

   
//  Select back the old pen and brush and delete the brush we created
   SelectObject(hdc, hOldPen);
   SelectObject(hdc, hOldBrush);
   DeleteObject(hBrush);

   
return  S_OK;
}

  此时,编译运行,使用 ActiveX控件测试容器 (工具 菜单中可以直接打开)对 ActiveX 控件进行测试。
  注意:由于一般情况下,项目属性的“生成后”将自动注册控件,在 Vista 下,如果想要注册 ActiveX,需要以管理员身份启动编译环境,以管理员身份进行注册。

第五步:添加事件处理
  使控件响应鼠标点击并调用外部实现方法。
  在第二步里面,选择了“选项->支持 连接点”的话,类视图将有一个 _IPolyCtlEvent 接口,在上面点击右键,选择“添加->添加方法”,在添加方法向导中,将返回类型设置为 void,函数名设置为 ClickIn,参数设置为 [in]long x 和 [in]long y。用同样操作添加 ClickOut 方法。
  此时代码中的接口部分将类似如下代码:

__interface _IPolyCtlEvents
{
   properties:
   methods:
   [id(
1 ), helpstring( " 方法 ClickIn " )]  void  ClickIn([ in ]LONG x, [ in ] LONG y);
   [id(
2 ), helpstring( " 方法 ClickOut " )]  void  ClickOut([ in ] LONG x, [ in ] LONG y);
};

  在 VC6 中,此时需要重新编译 idl 文件,然后对类 CPolyCtl 进行右键菜单中的添加连接点(Implement Connection Points),VC2003 中,在此类创建时就已经自动绑定,不需要再次手工操作。

  在类 CPolyCtl 的属性对话框中,选择消息标签,重载 WM_LBUTTONDOWN 事件,添加如下代码:

LRESULT CPolyCtl::OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &  bHandled)
{
   HRGN hRgn;
   WORD xPos 
=  LOWORD(lParam);   //  horizontal position of cursor
   WORD yPos  =  HIWORD(lParam);   //  vertical position of cursor

   CalcPoints(m_rcPos);

   
//  Create a region from our list of points
   hRgn  =  CreatePolygonRgn( & m_arrPoint[ 0 ], m_nSides, WINDING);

   
//  If the clicked point is in our polygon then fire the ClickIn
   
//   event otherwise we fire the ClickOut event
    if  (PtInRegion(hRgn, xPos, yPos))
      Fire_ClickIn(xPos, yPos);
   
else
      Fire_ClickOut(xPos, yPos);

   
//  Delete the region that we created
   DeleteObject(hRgn);
   
return   0 ;
}

  编译,再测试,可一看到 ActiveX控件测试容器中,鼠标点击时产生的 ClickIn 和 ClickOut 调用。
第六步:添加属性页(懒,没做,略)
第七步:在网页中的引用
  项目编译的时候,会自动产生一个文件,名字叫 PolyCtl.htm,编辑它:

< HTML >
< HEAD >
< TITLE > 对象 PolyCtl 的 ATL 7.0 测试页 </ TITLE >
</ HEAD >
< BODY >
< OBJECT  ID ="PolyCtl"  CLASSID ="CLSID:4CBBC676-507F-11D0-B98B-000000000000" ></ OBJECT >
< SCRIPT  LANGUAGE ="VBScript" >
< ! --
Sub  PolyCtl_ClickIn(x, y)
   PolyCtl.Sides 
=  PolyCtl.Sides  +   1
End Sub
Sub  PolyCtl_ClickOut(x, y)
   PolyCtl.Sides 
=  PolyCtl.Sides  -   1
End Sub
-->
</ SCRIPT >
</ BODY >
</ HTML >

使用浏览器打开网页,点击其中的 ActiveX 控件,试试结果吧。 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值