孙鑫18课Active控件.docx

上传人:b****6 文档编号:8541410 上传时间:2023-01-31 格式:DOCX 页数:14 大小:237.52KB
下载 相关 举报
孙鑫18课Active控件.docx_第1页
第1页 / 共14页
孙鑫18课Active控件.docx_第2页
第2页 / 共14页
孙鑫18课Active控件.docx_第3页
第3页 / 共14页
孙鑫18课Active控件.docx_第4页
第4页 / 共14页
孙鑫18课Active控件.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

孙鑫18课Active控件.docx

《孙鑫18课Active控件.docx》由会员分享,可在线阅读,更多相关《孙鑫18课Active控件.docx(14页珍藏版)》请在冰豆网上搜索。

孙鑫18课Active控件.docx

孙鑫18课Active控件

容器和服务器程序

⏹容器应用程序是可以嵌入或链接对象的应用程序。

Word就是容器应用程序。

⏹服务器应用程序是创建对象并且当对象被双击时,可以被启动的应用程序。

Excel就是服务器应用程序。

ActiveX控件的四种属性

⏹Stock:

为每个控件提供的标准属性,如字体或颜色。

⏹Ambient:

围绕控件的环境属性——已被置入容器的属性。

这些属性不能被更改,但控件可以使用它们调整自己的属性。

⏹Extended:

这些是由容器处理的属性,一般包括大小和在屏幕上的位置。

⏹Custom:

由控件开发者添加的属性。

切换到VB的运行环境中。

VB做为ACTIVEX控件测试容器;

VB中加载ACTIVEX控件:

选择工程下面的组件:

选择MICROSOFTWINSOCKCONTROL6.0

(。

OCX是ACTIVEX控件的后缀名,但是ACTIVEX控件的后缀名不一定是.OCX,也可以是其它的名字,比如。

DLL),选上后,点确定。

选择VIEW下的OBJECTBROWSER。

在所有库的下拉列表中,选择MSWINSOCKLIB。

可以看到WINSOCK控件出来了。

其中,绿色控件表示方法。

小手表示控件属性。

闪电表,示事件。

一个典型ACTIVEX控件会有这三个属性。

ACTIVEX控件好处:

把常用的功能封装到ACTIVEX控件中,提供给程序开发使用。

新建一个工程,选择MFC的MFCACTIVEXCONTROLWIZARD,名字是TEST。

(开发一个时钟控件)。

保持缺省,完成。

平放的小勺是接口。

外部的函数通过接口去访问控件的属性和方法。

在接口中定义的所有函数都是纯虚函数。

通过接口调用的函数是调用CTestCtrl中真正实现的函数。

编译一个,会在DEBUG目录下有一个TEST.OCX,这就是控件,要用的话,把它放到要用的目录下面。

不能!

运行程序,因为它必须要有一个容器。

选择ACTIVEXCONTROLTESTCONTAINER。

选择EDIT下面的INSERTNEWCONTROL…….出现下面的图,选择我们的TESTCONTROL。

(VC编译环境中)

下面是VB环境中:

ACTIVEX要先注册,再能使用。

要想删除ACTIVEX的注册信息:

运行regsvr32/u(/u表示反注册,然后将TEST.OCX拉到regsvr32/u后面),弹出:

这时候就找不到TESTACTIVEX控件了。

要想再注册,用上面同样的方法,但是/u要取消。

这时弹出的消息如下:

这时再找,就可以找到TEST.OCX了。

在VC中的TOOLS菜单下的REGISTERCONTROL也可以达到上面的效果。

控件使用之间,都要注册。

在控件上面输出当前时间。

代码如下:

voidCTestCtrl:

:

OnDraw(

CDC*pdc,constCRect&rcBounds,constCRect&rcInvalid)

{

//TODO:

Replacethefollowingcodewithyourowndrawingcode.

CTimet=CTime:

:

GetCurrentTime();

CStringstrtime=t.Format("%H:

%M:

%S");

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

//系统下面自动加的这两句代码是为了填充背景和画椭圆的。

//pdc->FillRect(rcBounds,CBrush:

:

FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH)));

//pdc->Ellipse(rcBounds);

}

编译的时候要先将测试中的TEST控件删除。

上面这段代码的时间是静止的,不会动,下面创建一个动态的时钟。

intCTestCtrl:

:

OnCreate(LPCREATESTRUCTlpCreateStruct)

{

if(COleControl:

:

OnCreate(lpCreateStruct)==-1)

return-1;

//TODO:

Addyourspecializedcreationcodehere

SetTimer(1,1000,NULL);

return0;

}

voidCTestCtrl:

:

OnTimer(UINTnIDEvent)

{

//TODO:

Addyourmessagehandlercodehereand/orcalldefault

Invalidate();

下面这句也可以:

InvalidateControl();

二者等效。

COleControl:

:

OnTimer(nIDEvent);

}

这时时间动起来了。

下面为控件添加设置前景色和背景色。

然后再增加前景色。

voidCTestCtrl:

:

OnDraw(

CDC*pdc,constCRect&rcBounds,constCRect&rcInvalid)

{

//TODO:

Replacethefollowingcodewithyourowndrawingcode.

COLORREFbkcolor=TranslateColor(GetBackColor());

CBrushbrush(bkcolor);

pdc->FillRect(rcBounds,&brush);

COLORREFtxcolor=TranslateColor(GetForeColor());

pdc->SetTextColor(txcolor);

pdc->SetBkMode(TRANSPARENT);

CTimet=CTime:

:

GetCurrentTime();

CStringstrtime=t.Format("%H:

%M:

%S");

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

//系统下面自动加的这两句代码是为了填充背景和画椭圆的。

//pdc->FillRect(rcBounds,CBrush:

:

FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH)));

//pdc->Ellipse(rcBounds);

}

通常一个ACTIVEX控件会提供自己属性页。

在TestCtl.cpp中:

BEGIN_PROPPAGEIDS(CTestCtrl,2)

PROPPAGEID(CTestPropPage:

:

guid)//guid表示全局唯一标识符。

PROPPAGEID(CLSID_CColorPropPage)//颜色属性页

END_PROPPAGEIDS(CTestCtrl)

这时属性页就出现了。

下面给控件添加一个自定义的属性:

增加一个时间间隔的属性。

voidCTestCtrl:

:

OnIntervalChanged()

{

//TODO:

Addnotificationhandlercode

if(m_interval<0||m_interval>6000)

{

m_interval=1000;

}

else

{

m_interval=m_interval/1000*1000;//将用户输入取整,2345-》2000.

KillTimer

(1);//销毁先前的定时器

SetTimer(1,m_interval,NULL);//设置新的定时器

}

SetModifiedFlag();

}

接下来将自定义的属性在属性表单中进行设置。

在IDD_PROPPAGE_TEST中:

并为EDIT它关联一个short型的m_timeinterval;

下面的interval是外部名称。

下面是运行结果:

下面给控件添加方法:

voidCTestCtrl:

:

Hello()

{

//TODO:

Addyourdispatchhandlercodehere

MessageBox("helloworld!

");

}

接下来给控件添加一个事件:

[uuid(00E87A5D-986C-4FF9-BE79-C3F0F96AA13C),

helpstring("TestControl"),control]

coclassTest

{

[default]dispinterface_DTest;

[default,source]dispinterface_DTestEvents;//表示控件用这个接口来发送通知事件,这个接口不是控件本身实现的接口。

};//source表示_DTestEvents是一个源接口,是由窗口来实现的。

这时测试:

下面增加一个自定义的事件:

在_DTestEvents上右击弹出下面对话框:

在voidCTestCtrl:

:

OnDraw中添加:

if(0==t.GetSecond())

{

FireNewminute();

}

测试结果:

新的一分钟到达时,事件发送了。

当添加自定义的事件时,一定要在事件发生时,去发出事件通知。

标准事件时,MFC自动帮我们实现。

将文件设置前景色,背景色,时间间隔,然后保存,再次打开,发现时间间隔没有保存下来(前景色和背景色都保持下来),说明时间间隔没有持久性。

voidCTestCtrl:

:

DoPropExchange(CPropExchange*pPX)//此函数是做持久性的。

{

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

COleControl:

:

DoPropExchange(pPX);

//TODO:

CallPX_functionsforeachpersistentcustomproperty.

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

}

intCTestCtrl:

:

OnCreate(LPCREATESTRUCTlpCreateStruct)

{

if(COleControl:

:

OnCreate(lpCreateStruct)==-1)

return-1;

//TODO:

Addyourspecializedcreationcodehere

SetTimer(1,m_interval,NULL);

return0;

}

接下来再看一个问题:

在VB中做测试,当通过属性页改变时间间隔时,VB窗口中的属性时间间隔并没有随之改变。

这主要是因为自定义的属性在发生改变时,没有通知容器,让容器调整。

由上图可以看出,间隔的属性调度ID为1.

voidCTestCtrl:

:

OnIntervalChanged()

{

//TODO:

Addnotificationhandlercode

if(m_interval<0||m_interval>6000)

{

m_interval=1000;

}

else

{

m_interval=m_interval/1000*1000;//将用户输入取整,2345-》2000.

KillTimer

(1);//销毁先前的定时器

SetTimer(1,m_interval,NULL);//设置新的定时器

BoundPropertyChanged

(1);

}

SetModifiedFlag();

}

在VB中,可以在设计时,也可以在运行时改变控件的属性。

在设计时,时间值不动,在运行时,时间值才改变。

容器知道自己是在设计是还是在运行时。

voidCTestCtrl:

:

OnTimer(UINTnIDEvent)

{

//TODO:

Addyourmessagehandlercodehereand/orcalldefault

if(AmbientUserMode())//运行时

{

InvalidateControl();

}

COleControl:

:

OnTimer(nIDEvent);

}

当编写完ACTIVEX后,可以选择

编译,就可以生成一个发行版的OCX控件,在发行模式下进行编译时,VC程序会做一些优化,同时生成的可执行文件比较小。

下面做一个VC的测试程序,用来访问我们做的ACTIVEX控件。

新建一个MFC的对话框程序(TestTest)

在对话框上点击右键,插入ACTIVEX控件,选择我们刚刚建立的TEST控件。

放置一个,然后右击它,可以看到相应的属性。

还可以通过工程下面的添加到工程(组件和控件),选择ACTIVEX

上面都是通过静态增加的,下面动态增加一个。

在对话框上面增加一个按钮,当点击这个按钮的时候,动态的增加一个时钟控件。

为CTestTestDlg增加:

private:

CTestm_clock;

在头文件中:

#include"test.h"

voidCTestTestDlg:

:

OnButton1()

{

//TODO:

Addyourcontrolnotificationhandlercodehere

m_clock.Create("windowname",WS_VISIBLE|WS_CHILD,CRect(0,0,100,70),this,123);

m_clock.Hello();

m_clock.SetBackColor(RGB(255,0,0));

m_clock.SetForeColor(RGB(0,255,0));

m_clock.SetInterval(m_clock.GetInterval()*2);

}

下面是对事件进行响应:

voidCTestTestDlg:

:

OnnewminuteTestctrl3()

{

//TODO:

Addyourcontrolnotificationhandlercodehere

MessageBox("newminute!

");

}

对于一个动态创建的控件,去响应它的事件对象:

在创建的时候,给它分配了一个ID号,根据这个ID号,自己写。

下面是我写的:

由于创建时,控件ID选为123,修改代码如下:

TestTestDlg.h中:

afx_msgvoidOnnewminute123();

在TestTestDlg.cpp中:

BEGIN_EVENTSINK_MAP(CTestTestDlg,CDialog)

//{{AFX_EVENTSINK_MAP(CTestTestDlg)

ON_EVENT(CTestTestDlg,IDC_TESTCTRL3,1/*newminute*/,OnnewminuteTestctrl3,VTS_NONE)

ON_EVENT(CTestTestDlg,123,1/*newminute*/,Onnewminute123,VTS_NONE)

//}}AFX_EVENTSINK_MAP

END_EVENTSINK_MAP()

voidCTestTestDlg:

:

Onnewminute123()

{

MessageBox("newminute123!

");

}

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 小学教育

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1