用VC创建ActiveX控件

1,ActiveX控件理解:

ActiveX控件是一个极小的服务器应用程序,他不能独立运行,必须嵌入到某个容器程序中,与容器一起运行,如VB,VC,也有点象插件,组件的形式,在VC中,可以把ActiveX控件认为是资源里的,可以拖动到对话框上的小控件,这里就是说明怎么样制作这样一个VC的小控件。(参考孙鑫VC++深入详解)。

2,生成一个小时钟控件:可以显示当前时间 :Clock.ocx

用VC6,通过MFC ActiveXContolWizad可以创建一个工程,一个工程可以包含多个控件,这里选默认1个。

通过向导可以不写任何代码生成三个类:CClockApp(相当于应用程序类),CClockCtrl(相当于视类),CClockProPage(控件的属性页类)。还生成两个接口:_DCLOCK,   _DCLOCKEVENTS.(说明一下:控件主要包括属性,方法和事件机制)。通过_DCLOCK得到属性和方法,通过_DCLOCKEVENTS得到控件的事件,主要是控件发出事件通知容器程序,容器可以对事件作出反应,也可以不作出反应)。

VC编译成功时会出现两行:Registering ActiveX Control…

                          RegSvr32:DllRegisterServerin.\Debug\Clock.ocx succeeded.

表示编译成功,且已经注册成功。这时这个控件就可以再别的程序如VB里调用了,若要取消注册,可以:开始菜单->运行里输入:regsvr/u  控件的绝对路径。

 

2.1:时钟控件的实现:

上面生成的控件没有时钟的功能,只是一个椭圆,因为在CClockCtrl里的OnDraw()里有这样几行代码://       pdc->FillRect(rcBounds,   CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH)));

//     pdc->Ellipse(rcBounds);

注释起来:加入自己的代码:

CBrushbrush(TranslateColor(GetBackColor()));//…………1

       pdc->FillRect(rcBounds,&brush);

       pdc->SetBkMode(TRANSPARENT);

       pdc->SetTextColor(TranslateColor(GetForeColor()));

 

       CTimetime=CTime::GetCurrentTime();

       if(0==time.GetSecond())

       {

              FireNewMinute();

       }

       CStringstr=time.Format("%H:%M:%S");

       pdc->TextOut(0,0,str);

意思是:用控件的背景颜色填充矩形,然后得到当前时间,用控件的前景颜色填充文字,注意使用pdc->SetBkMode(TRANSPARENT);使的文字的背景透明,至于FireNewMinute();

是后面设置的一个事件驱动:当秒=0时,控件会像他的容器发出一个事件,容器是否处理他就要看的具体要求了。得到背景色和前景色是后面对控件添加的属性。不然也不会有这两项。

这样的控件的时间还是静止的,要让他动起来,需要每个1秒钟调用一个OnDraw()函数,自然后想到设置一个定时器。在那里设置呢?

要在程序一运行起来就要动起来,自然可以再OnCreate()里定义,恰好CClockCtrl这个跟视类相当的类里有一个OnCreate(),在里面添加:

SetTimer(1,m_interval,NULL);  // m_interval为定时器时间,我们完全可以不让他1种走一次,自己设定他。

当然这样就要在OnTimer()里来调用刷新了:

if(AmbientUserMode()) ///这句可以不要,加上他只是说明控件在什么模式下才刷新///OnDraw().这里是在控件属性运行状态时才刷新。

              InvalidateControl();//也可以直接调用另一个函数Invalidate()

这样一个可以动的时钟控件就出来了。设定好m_interval=1000,就是时钟了。

 

2.2 时钟控件的完善:

在VB里控件面板里总会有前景色和背景色的选项,我们希望这个时钟控件也可以达到那种效果。

在VC通过Class Wizard来完成,选择Automation->Add Property可以选择常规属性BackColor    ForeColor等。选好后,可以再_DCClock里多了:

       [id(DISPID_BACKCOLOR), bindable,requestedit] OLE_COLOR BackColor;

       [id(DISPID_FORECOLOR), bindable, requestedit]OLE_COLOR ForeColor;

 

这就是我们可以再上面的1处添加那两句代码的原因了。

然后可以为这个控件添加属性页,

在CClockCtr的源文件里,可以看到下面,意思说这个控件有一个属性页,且标示符为guid.要添加另外一个属性页,就要改1为2,相应加入颜色属性页的标识符。

BEGIN_PROPPAGEIDS(CClockCtrl,1)

       PROPPAGEID(CClockPropPage::guid)

END_PROPPAGEIDS(CClockCtrl)

改为:

BEGIN_PROPPAGEIDS(CClockCtrl,2)

       PROPPAGEID(CClockPropPage::guid)

                            PROPPAGEID(CLSID_CColorPropPage)//颜色属性页的guid为//CLSID_CColorPropPage

END_PROPPAGEIDS(CClockCtrl)

这样控件就有了个颜色属性页。

2.3:自定义属性 时间间隔m_interval

要时钟控件多久更新一次,我们通过属性页给定一个值来设定。

同样通过向导,增加属性,选择Member variable 增加一个变量,这时程序自动增加一个函数:OnIntervalChanged(),在控件外部修改这个m_interval时,此函数被调用。

在此函数里添加:

if(m_interval<0|| m_interval>6000)

       {

              m_interval=1000;

       }

       else

       {

              m_interval=m_interval/1000*1000;

              KillTimer(1);

              SetTimer(1,m_interval,NULL);

              BoundPropertyChanged(0x1);

       }

       SetModifiedFlag();

 

意思:首先对输入的值进行判断,过大过小都设置为1000,其他的按取整计算。

 

问题:m_interval初值怎么办?第一次启动他的间隔是多少了?

在CClockProPage类对应的属性也上上添加一个文本框,并且关联一个变量:m_updateInterval,这么做得同时,向导会提示我们是否为这个变量关联一个属性,这里选择关联上面的时间间隔属性,Interval;这样就为这个属性添加了一个属性页了。在CClockPropPage的DoDataExchange(CDataExchange* pDX)函数里就会自动多加几行:

       DDP_Text(pDX, IDC_EDIT_INTERVAL,m_updateInterval, _T("Interval") );

       DDX_Text(pDX, IDC_EDIT_INTERVAL,m_updateInterval);

文本框初始值为0,当然就解决了上面的问题。你在运行程序时可以设定为别的值,比如说1000。

我们希望这个设置的值一直都能保存下去,下次启动时不要重新设置怎么办?

2.4属性的持久性:

只需在CClockCtrl的DoPropExchange(CPropExchange* pPX)里加入

       PX_Short(pPX,"Interval",m_interval,1000);

m_interval就有了持久性了,后面那个1000是缺省值。也就是当没有为文本框制定值时,他默认为1000而不是0了。

还有一个问题,在VB里调试这个时钟程序时发现,他自身的属性页与Vb的属性面板对应不起来,比如吧时间间隔调到2000,但是Vb的属性框里没有变化。解决:

在CClockCtrl的OnIntervalChanged() 加上BoundPropertyChanged(0x1);通知容器作出反应。

2.4 方法:

跟添加属性差不多可以添加方法。添加方法跟VC里添加成员函数相对应,添加属性跟天剑成员变量相对应。

2.5:事件:

标准事件:

通过向导添加事件,在接口-DCCLOCKEVENT中会多了点击事件,在Vb里可以调用窗口过程对改事件作出反应或者不反应。

自定义事件:

 当秒钟=0时,我们增加一个事件,FireNewMinute();同理在vb中可以对该事件作出或者不作出反应。

 

以上控件就生成好了,如要把它放到VC里,就像普通的加入Vc组件一样加入。然后调用它的函数,变量。添加事件可以鼠标又击这个控件选择Events.添加。该栏就会显示该控件所有的事件。

 


 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值