b2c信息网

您现在的位置是:首页 > 昨日新闻 > 正文

昨日新闻

activex控件源码(activex控件开发教程)

hacker2022-07-10 13:20:25昨日新闻110
本文目录一览:1、vc6中有关activex控件找不到2、

本文目录一览:

vc6中有关activex控件找不到

注册控件方法

1.将*.dll复制到c:\windows\system32\下.

2.然后才用regsvr32 *.dll

不知道你的注册控件方法正确吗?

请问ActiveX 控件(以.ocx为扩展名)是用什么语言编写?怎样查看它的代码?谢谢!

一般是用C++编写的,其他像VB等语言也可以编写

.ocx都是封装好了的,你是看不到原码的!

弹出"已限制此网页运行可以访问计算机的脚本或activex控件“自动运行的源码!

不用但码的,你把这个网页放到服务器上,这种情况自然消失了,本地调试状态,和服务器运行状态不一样的

如何动态加载ActiveX控件

使用ON_EVENT_RANGE就足以满足需要了,不过,还是希望能够更灵活的实现动态的响应,所以又经过对MFC源码一番探查,发现还是可以的,而且应该也不是很复杂的,下面分别来说说这两种方法

例程为Tdax,对话框程序,使用了Microsoft UpDown Control 6.0控件作为控件,添加了MouseDown事件

第一种方法挺简单的:

1.

缺省的映射定义为

BEGIN_EVENTSINK_MAP(CTdaxDlg, CDialog)

//{{AFX_EVENTSINK_MAP(CTdaxDlg)

ON_EVENT(CTdaxDlg, IDC_UPDOWN1, -605 /* MouseDown */, OnMouseDownUpdown1, VTS_I2 VTS_I2 VTS_I4 VTS_I4)

//}}AFX_EVENTSINK_MAP

END_EVENTSINK_MAP()

现改为

BEGIN_EVENTSINK_MAP(CTdaxDlg, CDialog)

//{{AFX_EVENTSINK_MAP(CTdaxDlg)

//}}AFX_EVENTSINK_MAP

ON_EVENT_RANGE(CTdaxDlg, IDC_UPDOWN1, IDC_UPDOWN1+10, -605 /* MouseDown */, OnMouseDownUpdown1, VTS_I4 VTS_I2 VTS_I2 VTS_I4 VTS_I4)

END_EVENTSINK_MAP()

就是说,可以映射至少11个控件(请注意,这里用了至少,也就是说可以少于11个,甚至于1个也无所谓)

a.这里建议把ON_EVENT_RANGE从

//{{AFX_EVENTSINK_MAP(CTdaxDlg)

ON_EVENT_RANGE(CTdaxDlg, IDC_UPDOWN1, IDC_UPDOWN1+10, -605 /* MouseDown */, OnMouseDownUpdown1, VTS_I4 VTS_I2 VTS_I2 VTS_I4 VTS_I4)

//}}AFX_EVENTSINK_MAP

对中拖出来,见上面例子,不拖出来不会对程序产生影响,但可能会影响后续的IDE操作,试试便知。

b.最后的参数类型中要在前面加上VTS_I4,即从VTS_I2 VTS_I2 VTS_I4 VTS_I4变为VTS_I4 VTS_I2 VTS_I2 VTS_I4 VTS_I4,当然事件处理函数也将做相应调整,下面马上讲到。

2.

修改框架建立的事件处理函数

void OnMouseDownUpdown1(short Button, short Shift, long x, long y);

改为

BOOL OnMouseDownUpdown1(UINT nID, short Button, short Shift, long x, long y);

返回类型为void,应该也无所谓的,不过msdn上说是BOOL,咱就BOOL吧,但UINT nID这个参数是一定要加上的

3.做一些于本案无关的工作

a.在对话框编辑器中删掉原来的ID为IDC_UPDOWN1的控件

b.加一个成员变量CObList m_oaUpdowns;

c.在OnInitDialog中,加上

UINT nID = IDC_UPDOWN1;

CRect rect(10, 10, 20, 30);

for(int i=0; i11; i++){

CUpDown* pupdown = new CUpDown;

rect.OffsetRect(0, 20);

pupdown-Create(NULL, WS_CHILD | WS_VISIBLE, rect, this, nID + i);

m_oaUpdowns.Add(pupdown);

}

d.在OnDestroy中,加上

for(int i=0; im_oaUpdowns.GetSize(); i++){

delete m_oaUpdowns[i];

}

e.在OnMouseDownUpdown1中,加上

CString str;

str.Format("%d", nID);

MessageBox(str);

用来指示是否收到事件

4.编译一下,可以发现,绝对OK

下面,我们来看更多灵活的方法:

观察MFC宏

BEGIN_EVENTSINK_MAP,END_EVENTSINK_MAP和ON_EVENT,可以发现MFC将控件ID,事件ID和事件处理函数等等信息都放在AFX_EVENTSINKMAP_ENTRY这个结构,每个映射一个这种结构,所有的结构组成一数组放在AFX_EVENTSINKMAP结构中,本来以为动态修改这两个结构信息,不就可以实现动态映射控件事件了,可惜发现MFC定义了

const AFX_EVENTSINKMAP_ENTRY theClass::_eventsinkEntries[] =

{

...

}

可恶的const,只好另想它途了。

继续观察MFC源码,发现它中间会有一个

BOOL CCmdTarget::OnEvent(UINT idCtrl, AFX_EVENT* pEvent,

AFX_CMDHANDLERINFO* pHandlerInfo)

{

...

}

函数中有如下代码

VARIANT var;

AfxVariantInit(var);

DISPPARAMS dispparams;

dispparams.rgvarg = NULL;

if (bRange)

{

memcpy(dispparams, pEvent-m_pDispParams, sizeof(DISPPARAMS));

dispparams.rgvarg = new VARIANT[++dispparams.cArgs];

memcpy(dispparams.rgvarg, pEvent-m_pDispParams-rgvarg,

sizeof(VARIANT) * (dispparams.cArgs-1));

VARIANT* pvarID成都高级办公软件培训班学习;dispparams.rgvarg[dispparams.cArgs-1];

V_VT(pvarID) = VT_I4;

V_I4(pvarID) = idCtrl;

}

hResult = CallMemberFunc(pEntry-dispEntry, DISPATCH_METHOD, var,

(bRange ? dispparams : pEvent-m_pDispParams), uArgError);

ASSERT(FAILED(hResult) || (V_VT(var) == VT_BOOL));

bHandled = V_BOOL(var);

if (bRange)

delete [] dispparams.rgvarg;

break;

好了,切入口找到了,就用这个CallMemberFunc了,唯一的问题就是重新组织这个函数所需的参数了。

开始:

1.为避免干扰,干脆注释掉OnInitDialog上一例中添加的代码,再加入如下代码:

UINT nID = 10004;

CRect rect(10, 10, 20, 30);

for(int i=0; i11; i++){

CUpDown* pupdown = new CUpDown;

rect.OffsetRect(0, 20);

pupdown-Create(NULL, WS_CHILD | WS_VISIBLE, rect, this, nID + i);

m_oaUpdowns.Add(pupdown);

}

其实就改了一个nID,之所以改nID,是为了表示这个ID是可以你自己动态确定的,当然这里省事,将这些ID连在了一起,其实分开也是没问题的。

2.注释掉事件映射

BEGIN_EVENTSINK_MAP(CTdaxDlg, CDialog)

//{{AFX_EVENTSINK_MAP(CTdaxDlg)

//}}AFX_EVENTSINK_MAP

// ON_EVENT_RANGE(CTdaxDlg, IDC_UPDOWN1, IDC_UPDOWN1+10, -605 /* MouseDown */, OnMouseDownUpdown1, VTS_I4 VTS_I2 VTS_I2 VTS_I4 VTS_I4)

END_EVENTSINK_MAP()

3.重载对话框的OnCmdMsg,加入代码如下:

if(nCode == CN_EVENT nID = 10004 nID = 10014){

AFX_EVENT* pEvent = (AFX_EVENT*)pExtra;

if(pEvent != NULL pEvent-m_dispid == -605){//根据dispid来判断是否正确的事件

AFX_DISPMAP_ENTRY e;

e.lpszName = _T("");

e.lDispID = -605; //dispID,事件的dispID

e.vt = VT_BOOL; //返回类型

e.pfn = (AFX_PMSG)OnMouseDownUpdown1;//事件处理函数

e.pfnSet = (AFX_PMSG)0;

e.nPropOffset = 0;

e.flags = afxDispCustom;

//下面是参数类型,如果事件处理函数不加控件ID的话,应该改为VTS_I2 VTS_I2 VTS_I4 VTS_I4

e.lpszParams = VTS_I4 VTS_I2 VTS_I2 VTS_I4 VTS_I4;

UINT uArgError = (UINT)-1; // no error yet

VARIANT var;

AfxVariantInit(var);

//如果需要每个控件的ID信息,应该为框架生成的事件处理函数的参数最前面加上1个UINT nID参数,代码如下:

DISPPARAMS dispparams;

dispparams.rgvarg = NULL;

memcpy(dispparams, pEvent-m_pDispParams, sizeof(DISPPARAMS));

dispparams.rgvarg = new VARIANT[++dispparams.cArgs];

memcpy(dispparams.rgvarg, pEvent-m_pDispParams-rgvarg,

sizeof(VARIANT) * (dispparams.cArgs-1));

VARIANT* pvarID = dispparams.rgvarg[dispparams.cArgs-1];

pvarID-vt = VT_I4;

pvarID-intVal = nID;

CallMemberFunc(e, DISPATCH_METHOD, var,

dispparams, uArgError);

delete []dispparams.rgvarg;

//如果不需要控件的ID信息,代码如下,不过函数就不用加上第1个参数(控件ID)了:

/* CallMemberFunc(e, DISPATCH_METHOD, var,

(pEvent-m_pDispParams), uArgError);*/

}

return TRUE;

}

return CDialog::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);

4.编译运行,OK了。

例程为Tdax,对话框程序,使用了Microsoft UpDown Control 6.0控件作为控件,添加了MouseDown事件

第一种方法挺简单的:

1.

缺省的映射定义为

BEGIN_EVENTSINK_MAP(CTdaxDlg, CDialog)

//{{AFX_EVENTSINK_MAP(CTdaxDlg)

ON_EVENT(CTdaxDlg, IDC_UPDOWN1, -605 /* MouseDown */, OnMouseDownUpdown1, VTS_I2 VTS_I2 VTS_I4 VTS_I4)

//}}AFX_EVENTSINK_MAP

END_EVENTSINK_MAP()

现改为

BEGIN_EVENTSINK_MAP(CTdaxDlg, CDialog)

//{{AFX_EVENTSINK_MAP(CTdaxDlg)

//}}AFX_EVENTSINK_MAP

ON_EVENT_RANGE(CTdaxDlg, IDC_UPDOWN1, IDC_UPDOWN1+10, -605 /* MouseDown */, OnMouseDownUpdown1, VTS_I4 VTS_I2 VTS_I2 VTS_I4 VTS_I4)

END_EVENTSINK_MAP()

就是说,可以映射至少11个控件(请注意,这里用了至少,也就是说可以少于11个,甚至于1个也无所谓)

a.这里建议把ON_EVENT_RANGE从

//{{AFX_EVENTSINK_MAP(CTdaxDlg)

ON_EVENT_RANGE(CTdaxDlg, IDC_UPDOWN1, IDC_UPDOWN1+10, -605 /* MouseDown */, OnMouseDownUpdown1, VTS_I4 VTS_I2 VTS_I2 VTS_I4 VTS_I4)

//}}AFX_EVENTSINK_MAP

对中拖出来,见上面例子,不拖出来不会对程序产生影响,但可能会影响后续的IDE操作,试试便知。

b.最后的参数类型中要在前面加上VTS_I4,即从VTS_I2 VTS_I2 VTS_I4 VTS_I4变为VTS_I4 VTS_I2 VTS_I2 VTS_I4 VTS_I4,当然事件处理函数也将做相应调整,下面马上讲到。

2.

修改框架建立的事件处理函数

void OnMouseDownUpdown1(short Button, short Shift, long x, long y);

改为

BOOL OnMouseDownUpdown1(UINT nID, short Button, short Shift, long x, long y);

返回类型为void,应该也无所谓的,不过msdn上说是BOOL,咱就BOOL吧,但UINT nID这个参数是一定要加上的

3.做一些于本案无关的工作

a.在对话框编辑器中删掉原来的ID为IDC_UPDOWN1的控件

b.加一个成员变量CObList m_oaUpdowns;

c.在OnInitDialog中,加上

UINT nID = IDC_UPDOWN1;

CRect rect(10, 10, 20, 30);

for(int i=0; i11; i++){

CUpDown* pupdown = new CUpDown;

rect.OffsetRect(0, 20);

pupdown-Create(NULL, WS_CHILD | WS_VISIBLE, rect, this, nID + i);

m_oaUpdowns.Add(pupdown);

}

d.在OnDestroy中,加上

for(int i=0; im_oaUpdowns.GetSize(); i++){

delete m_oaUpdowns[i];

}

e.在OnMouseDownUpdown1中,加上

CString str;

str.Format("%d", nID);

MessageBox(str);

用来指示是否收到事件

4.编译一下,可以发现,绝对OK

下面,我们来看更多灵活的方法:

观察MFC宏

BEGIN_EVENTSINK_MAP,END_EVENTSINK_MAP和ON_EVENT,可以发现MFC将控件ID,事件ID和事件处理函数等等信息都放在AFX_EVENTSINKMAP_ENTRY这个结构,每个映射一个这种结构,所有的结构组成一数组放在AFX_EVENTSINKMAP结构中,本来以为动态修改这两个结构信息,不就可以实现动态映射控件事件了,可惜发现MFC定义了

const AFX_EVENTSINKMAP_ENTRY theClass::_eventsinkEntries[] =

{

...

}

可恶的const,只好另想它途了。

继续观察MFC源码,发现它中间会有一个

BOOL CCmdTarget::OnEvent(UINT idCtrl, AFX_EVENT* pEvent,

AFX_CMDHANDLERINFO* pHandlerInfo)

{

...

}

函数中有如下代码

VARIANT var;

AfxVariantInit(var);

DISPPARAMS dispparams;

dispparams.rgvarg = NULL;

if (bRange)

{

memcpy(dispparams, pEvent-m_pDispParams, sizeof(DISPPARAMS));

dispparams.rgvarg = new VARIANT[++dispparams.cArgs];

memcpy(dispparams.rgvarg, pEvent-m_pDispParams-rgvarg,

sizeof(VARIANT) * (dispparams.cArgs-1));

VARIANT* pvarID = dispparams.rgvarg[dispparams.cArgs-1];

V_VT(pvarID) = VT_I4;

V_I4(pvarID) = idCtrl;

}

hResult = CallMemberFunc(pEntry-dispEntry, DISPATCH_METHOD, var,

(bRange ? dispparams : pEvent-m_pDispParams), uArgError);

ASSERT(FAILED(hResult) || (V_VT(var) == VT_BOOL));

bHandled = V_BOOL(var);

if (bRange)

delete [] dispparams.rgvarg;

break;

好了,切入口找到了,就用这个CallMemberFunc了,唯一的问题就是重新组织这个函数所需的参数了。

开始:

1.为避免干扰,干脆注释掉OnInitDialog上一例中添加的代码,再加入如下代码:

UINT nID = 10004;

CRect rect(10, 10, 20, 30);

for(int i=0; i11; i++){

CUpDown* pupdown = new CUpDown;

rect.OffsetRect(0, 20);

pupdown-Create(NULL, WS_CHILD | WS_VISIBLE, rect, this, nID + i);

m_oaUpdowns.Add(pupdown);

}

其实就改了一个nID,之所以改nID,是为了表示这个ID是可以你自己动态确定的,当然这里省事,将这些ID连在了一起,其实分开也是没问题的。

2.注释掉事件映射

BEGIN_EVENTSINK_MAP(CTdaxDlg, CDialog)

//{{AFX_EVENTSINK_MAP(CTdaxDlg)

//}}AFX_EVENTSINK_MAP

// ON_EVENT_RANGE(CTdaxDlg, IDC_UPDOWN1, IDC_UPDOWN1+10, -605 /* MouseDown */, OnMouseDownUpdown1, VTS_I4 VTS_I2 VTS_I2 VTS_I4 VTS_I4)

END_EVENTSINK_MAP()

3.重载对话框的OnCmdMsg,加入代码如下:

if(nCode == CN_EVENT nID = 10004 nID = 10014){

AFX_EVENT* pEvent = (AFX_EVENT*)pExtra

4.编译运行,OK了。

发表评论

评论列表

  • 晴枙浊厌(2022-07-10 16:22:15)回复取消回复

    4;V_I4(pvarID) = idCtrl;}hResult = CallMemberFunc(pEntry-dispEntry, DISPATCH_METHOD, var,(bRange ? dispparams : pEvent-

  • 蓝殇清淮(2022-07-10 13:54:06)回复取消回复

    发现MFC将控件ID,事件ID和事件处理函数等等信息都放在AFX_EVENTSINKMAP_ENTRY这个结构,每个映射一个这种结构,所有的结构组成一数组放在AFX_EVENTSI

  • 冬马僚兮(2022-07-10 19:34:15)回复取消回复

    dispID,事件的dispIDe.vt = VT_BOOL; //返回类型e.pfn = (AFX_PMSG)OnMouseDownUpdown1;//事件处理函数e.pfnSet = (AFX_PMSG)0;e.nPropO