`
jgsj
  • 浏览: 957418 次
文章分类
社区版块
存档分类
最新评论

vs2008 外部调用ActiveX控件接口方法

 
阅读更多

转自:http://topic.csdn.net/u/20090605/16/018e26e9-06e2-4e0d-8099-bc8eb326afde.html

sndaxdrs:
初学activeX ,我写的一个 activeX控件测试程序。 分别调用两个 自定义方法, 分别出现 “找不到成员”,和“非选择性的参数”的提示对话框。 一直不知道原因 。但是调用 AboutBox() 方法可以调用成功。

我用activeX控件测试容器测试时。 AboutBox() 也可以成功。而调用其它方法时会显示
tstcon32.exe 中的 0x7c812afb 处最可能的异常: Microsoft C++ exception: COleException @ 0x0012ef70 。
调用不成功。

我已经分别用 控件测试容器和 regsvr32 注册过 控件了,控件测试成功。

由于是初学者,在此 希望能够得到大家的帮助。

fengrx:
使用向导加方法只是生成接口文件中的接口定义吧。
看下类文件中有没有方法的实现,如果没有就自己手工添加接口的实现。

举例:
接口文件中定义:
[id(DISPID_ABOUTBOX), helpstring("AboutBox")] HRESULT AboutBox(void);

头文件中定义:
STDMETHOD(AboutBox)(void);

cpp文件中实现:
STDMETHODIMP CResoftSignCtrl::AboutBox(void)
{
CAboutDlg dlg;
dlg.DoModal();
return S_OK;
}

sndaxdrs:
有实现的 void CCurveChartCtrl::Hello(void)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());

// TODO: 在此添加调度处理程序代码

MessageBox("Hello!");
}

这是我写的一个 实现。


顺便说一下。 我自己写 activeX控件。 添加几个方法。都可以测试成功的。

我现在 需要用到别人给我的一个 控件 。 我调用 它的方法 。 显示是 “找不到成员”,

我又在 程序中又添加了一个方法。 就是上面这段代码。 当调用 时显示 “非选择性的参数”


求助大家/希望能得到帮助。

fengrx:
此控件在什么程序中使用的,一般使用此控件的程序会缓存一份此控件的函数表。
如果增加了新函数,不删除缓存文件,新函数是无法使用的。

此控件在什么程序中使用的?

例如对于word2003使用控件时会在临时文件夹保存两个文件夹:
VBE
Word8.0

你这个图表控件是在哪儿使用的?

sndaxdrs:
这个 控件是一个 显示曲线。有点 类似 股票的 波动曲线。

我还想问下 如果添加新函数。怎么来删除缓存文件呢?

lzy91093:
我以前遇到“非选择性的参数”问题原因:
1,接口文件中定义的参数(个数、类型、顺序)与实现类中不同
2,接口文件定义的该函数id与实现的cpp文件中的一些映射宏(如BEGIN_EVENT_MAP/END_EVENT_MAP、BEGIN_DISPATCH_MAP/END_DISPATCH_MAP)里面的函数列表的顺序不一致

不知对你有没有帮助

sndaxdrs:

fengrx .. 你好,问题并没有解决。你只是告诉我添加一个方法我只是编译通过而已。但“找不到成员” 还是没有解决。你告诉我的方法。即使可以解决“非选择性参数”这个问题。也是解决不了“找不到成员“ 这个问题。 我的最终目的是 要解决“非选择性参数”


我再重复一下我的问题。 别人给我一外activeX 控件。 上面有且仅有一个方法 [id(1), helpstring("方法Initialize")] LONG InitEx(BSTR target, LONG chart_id, LONG type, LONG item, BSTR verify);. 我写客户端调用 这个方法时 显示“找不到成员”。 我一直不知道原因 。


为了 测试这个控件 。我又加了一个方法。 调用 我加入的 方法时会 出现 “非选择性参数”


我的最终目的是要解决 “ 找不到成员” 的问题。 希望能得到大家的帮助。 这个问题我几天解决不了。 工作无法继续。

修改一个 笔误, 上面第二行的 “我的最终目的是 要解决“非选择性参数””改成“我的最终目的是 要解决“找不到成员””

lzy91093:
两个问题好像是同一个问题,DISPID_ABOUTBOX定义的是几?贴出头文件和cpp文件帮你看看

sndaxdrs:
#define DISPID_ABOUTBOX (-552)

下面只有一个方法
dispinterface _DCurveChart
{
properties:
methods:

[id(DISPID_ABOUTBOX)] void AboutBox();
[id(1), helpstring("方法Initialize")] LONG InitEx(BSTR target, LONG chart_id, LONG type, LONG item, BSTR verify);
};

这是方法的实现部分
LONG CCurveChartCtrl::InitEx(LPCTSTR target, LONG chart_id, LONG type, LONG item, LPCTSTR verify)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());

g_pSysLog->AppendLog(LOG_DEBUG,"InitEx");

strcpy(m_szVerify, verify);
m_nChartID = chart_id;
m_nChartType = type;
m_nTypeFlag = type | (item << 6);
m_nItem = item;
strcpy(m_szSoapEndPoint,target);
m_bInitChart = TRUE;

if (m_bCreateChart)
{
InitChartData();
return 0;
}

return 0;
}

lzy91093:
1,改成[id(2)] void AboutBox();
2,实现类中确保映射表中AboutBox函数在InitEx下面

再试试
BEGIN_DISPATCH_MAP/END_DISPATCH_MAP中间是怎么写的?

sndaxdrs:
BEGIN_DISPATCH_MAP(CCurveChartCtrl, COleControl)
DISP_FUNCTION_ID(CCurveChartCtrl, "AboutBox", DISPID_ABOUTBOX, AboutBox, VT_EMPTY, VTS_NONE)
DISP_FUNCTION_ID(CCurveChartCtrl, "InitEx", dispidInitialize, InitEx, VT_I4, VTS_BSTR VTS_I4 VTS_I4 VTS_I4 VTS_BSTR)
END_DISPATCH_MAP()

fengrx:
在我印象中接口中的返回值类型只能是:HRESULT
上次加的方法也是吧。
你自己加方法时,接口文件中定义的,返回值类型都定义成HRESULT试下,如果需要返回其它类型,请在参数中定义,设置为out

sndaxdrs:
http://topic.csdn.net/u/20071103/10/80B268B1-61C6-4C31-BF22-203AEB49FA7A.html
http://topic.csdn.net/u/20080219/21/4080D185-40C3-4490-ADAA-A3F0D84A0F7A.html


给大家看看两个相关的主题。

lzy91093:
to fengrx:返回类型可以不是HRESULT

to sndaxdrs:解决了?

AboutBox的id改成2后把映射
BEGIN_DISPATCH_MAP(CCurveChartCtrl, COleControl)
DISP_FUNCTION_ID(CCurveChartCtrl, "AboutBox", DISPID_ABOUTBOX, AboutBox, VT_EMPTY, VTS_NONE)
DISP_FUNCTION_ID(CCurveChartCtrl, "InitEx", dispidInitialize, InitEx, VT_I4, VTS_BSTR VTS_I4 VTS_I4 VTS_I4 VTS_BSTR)
END_DISPATCH_MAP()
里面的两个函数位置颠倒一下,编译,注册,再在控件调用端重新添加控件(重新到处CCurveChartCtrl类)应该就好了

重新导出CCurveChartCtrl类

BEGIN_DISPATCH_MAP(CCurveChartCtrl, COleControl)
DISP_FUNCTION_ID(CCurveChartCtrl, "AboutBox", DISPID_ABOUTBOX, AboutBox, VT_EMPTY, VTS_NONE)
DISP_FUNCTION_ID(CCurveChartCtrl, "InitEx", dispidInitialize, InitEx, VT_I4, VTS_BSTR VTS_I4 VTS_I4 VTS_I4 VTS_BSTR)
END_DISPATCH_MAP()

改成
BEGIN_DISPATCH_MAP(CCurveChartCtrl, COleControl)
DISP_FUNCTION(CCurveChartCtrl, "InitEx", InitEx, VT_I4, VTS_BSTR VTS_I4 VTS_I4 VTS_I4 VTS_BSTR)
DISP_FUNCTION(CCurveChartCtrl, "AboutBox", AboutBox, VT_EMPTY, VTS_NONE)
END_DISPATCH_MAP()

[id(DISPID_ABOUTBOX)] void AboutBox();
[id(1), helpstring("方法Initialize")] LONG InitEx(BSTR target, LONG chart_id, LONG type, LONG item, BSTR verify);
改成
[id(1), helpstring("方法Initialize")] LONG InitEx(BSTR target, LONG chart_id, LONG type, LONG item, BSTR verify);
[id(2)] void AboutBox();

顺便说一句,调用AboutBox出现“非选择性参数”错误是因为在空间内部调用的是InitEx,由于该函数的参数都是必选的(不是可选参数),调用时按AboutBox的格式传入的是无参数

注意DISP_FUNCTION和DISP_FUNCTION_ID的区别,如果用DISP_FUNCTION,其ID按映射中的顺序从1开始依次排列,用DISP_FUNCTION_ID则在影射中指定ID(如这里的dispidInitialize),不管是哪一种,都要保证该ID与idl文件中对应的接口定义里面的id一致。
再有就是注册与重新导出控件类,如果方便建议重做一个调用控件的工程。

sndaxdrs:
问题解决。非常非常感谢lzy91093 对我的帮助。 同时也 非常感谢lzy91093。解决办法为 lzy91093 的方法。

BEGIN_DISPATCH_MAP(CCurveChartCtrl, COleControl)
DISP_FUNCTION_ID(CCurveChartCtrl, "AboutBox", DISPID_ABOUTBOX, AboutBox, VT_EMPTY, VTS_NONE)
DISP_FUNCTION_ID(CCurveChartCtrl, "InitEx", dispidInitialize, InitEx, VT_I4, VTS_BSTR VTS_I4 VTS_I4 VTS_I4 VTS_BSTR)
END_DISPATCH_MAP()

改成
BEGIN_DISPATCH_MAP(CCurveChartCtrl, COleControl)
DISP_FUNCTION(CCurveChartCtrl, "InitEx", InitEx, VT_I4, VTS_BSTR VTS_I4 VTS_I4 VTS_I4 VTS_BSTR)
DISP_FUNCTION(CCurveChartCtrl, "AboutBox", AboutBox, VT_EMPTY, VTS_NONE)
END_DISPATCH_MAP()

[id(DISPID_ABOUTBOX)] void AboutBox();
[id(1), helpstring("方法Initialize")] LONG InitEx(BSTR target, LONG chart_id, LONG type, LONG item, BSTR verify);
改成
[id(1), helpstring("方法Initialize")] LONG InitEx(BSTR target, LONG chart_id, LONG type, LONG item, BSTR verify);
[id(2)] void AboutBox();

不过我还要问一下 lzy91093 , 发生这种错误的根源在哪里呢?

lzy91093:
控件内部是根据调用方传来的ID区寻找内部的函数的,ID给错了,就调用不到或调用到其他函数里了。(粗浅认识,不对处请方家指正)
其实你影射里用DISP_FUNCTION_ID也是可以的,是要保证IDL文件中定义的一致也是可以的:

BEGIN_DISPATCH_MAP(CCurveChartCtrl, COleControl)
DISP_FUNCTION_ID(CCurveChartCtrl, "AboutBox", DISPID_ABOUTBOX, AboutBox, VT_EMPTY, VTS_NONE)
DISP_FUNCTION_ID(CCurveChartCtrl, "InitEx", 1, InitEx, VT_I4, VTS_BSTR VTS_I4 VTS_I4 VTS_I4 VTS_BSTR) //
END_DISPATCH_MAP()

[id(DISPID_ABOUTBOX)] void AboutBox();
[id(1), helpstring("方法Initialize")] LONG InitEx(BSTR target, LONG chart_id, LONG type, LONG item, BSTR verify);

分享到:
评论

相关推荐

    ActiveX控件加载外部dll及html测试Demo

    ActiveX控件加载外部dll及html测试Demo 用VC2010编写,自已测试成功 Test.html为测试ActiveX控件页面 TestDll是dll动态库 Loaddll是测试TestDll的Demo FROMYANTAI为ActiveX控件,加载外部库TestDll,使用VC STL项目

    Labwindows调用ActiveX

    Labwindows调用ActiveX控件的例程,这里是调用多媒体库。

    VB6.0动态加载ActiveX控件漫谈

    ---- 这些语法很容易造成误导,以为动态加载ActiveX控件也是此方法,可能有朋 友也象我一样利用CreateObject尝试了无数次,却无功而返,不知微软公司是出于何种 考虑,动态加载ActiveX控件是扩展控件集合的方式实现...

    WebX Server ActiveX控件

    WebX Server ActiveX... &lt;br&gt; WebX Server ActiveX控件的特点: 从HTML调用已编译程序内的函数; 嵌入式或外部HTML网页; 支持CGI, Server Side Includes (SSI) 和 Authentication; 包括40多种属性和方法。

    VC++在ActiveX控件中动态调用外部DLL函数

    内容索引:VC/C++源码,系统相关,ActiveX 一个VC++系统相关的编程实例,程序演示如何在ActiveX控件中动态调用来自外部的DLL函数,虽然不常用,但很修复研究一下,以帮助您更好的学习VC++技术。

    VC 在ActiveX中动态调用外部DLL函数.rar

    VC 在ActiveX中动态调用外部DLL函数,演示如何在ActiveX控件中动态调用来自外部的DLL函数,虽然不常用,研究学习一下也不多余哦,里面有两个调用DLL的例子。

    VBA开发手册(控件使用以及调用外部程序)

    VBA开发手册,描述了ActiveX的使用以及通过VBA控制外部程序的方法

    vc实例精通源码,windows基本控件的使用Demo

    02_MyActiveX2 为ActiveX控件增加属性和方法。 03_ActiveXInDlg 在应用程序中使用ActiveX控件。 04_ActiveXInWeb 在浏览器中使用ActiveX控件。 05_MyActiveX3 在VC中显示动态的GIF动画。 06_RegOCX 在...

    Crk Report 报表平台程序及功能简介

    2、Web Crk Report企业版ActiveX控件:支持打印预览、打印等功能,并提供给第三方应调用的集成接口API,支持从报表外部传入复杂的查询条件,支持.Net(ASP),J2EE(Java)、PHP、HTML等网页界面中调用,该功能需要与Crk ...

    Delphi开发IEActiveX插件封装外部DLL完整示例

    将外部DLL文件编译入ActiveX资源(res),运行时再将DLL释放到指定位置,供ActiveX调用,特别注意:DLL或EXE不能加壳,编译的不要做任何改动,否则IE环境下无法加载。 内附完整JAVASCRIPT与ActiveX互通消息的HTML...

    LabVIEW高级编程与虚拟仪器工程应用

    4.1.2使用ActiveX控件 4.1.3使用ActiveX自动化 4.1.4 LabVIEW作为ActiveX服务器 4.2.NET技术应用 4.2.1.NET技术简介 4.2.2 .NET技术应用 4.3动态数据交换 4.3.1 LabVIEW的DDE功能 4.3.2向Excel文件写数据 ...

    滴答表格企业版 5.1.2

    答表格目前拥有600多个直接编程接口,几十个子对象,集成了表格控件的编辑展现、公式运算功能,同时又拥有报表组件的数据源绑 定、外部数据的导入导出等功能;滴答表格的接口简单易用,类似打开/保存文件,打印,...

    DOCX to HTML Converter试用版:一款专业的Word转换为HTML的控件

    试用版 试用版 试用版 开发语言: ActiveX/Delphi/ASP/.NET/DLL 可用平台: ActiveX/Delphi/ASP/...当您在使用这个转换器的时候,您不需要任何其它外部控件或程序。该转换器包括一个功能强大的DOCX解析器,用于我们的

    精通matlab7.0混合编程.

    3.3.3 利用activex控件 3.3.4 利用mat文件 3.3.5 c-mex 3.3.6 利用mideva/matcom 3.3.7 利用matrix[lib]实现混合编程 3.3.8 利用matlab add-in 3.3.9 matlab com builder 3.3.10 matlab和excel混合编程 3.4 小结 第4...

    滴答表格专业版 4.2.2

    滴答表格目前拥有600多个直接编程接口,几十个子对象,集成了表格控件的编辑展现、公式运算功能,同时又拥有报表组件的数据源绑定、外部数据的导入导出等功能;滴答表格的接口简单易用,类似打开/保存文件,打印,...

    VB6.0源码:DLL文件的编译链接插件.rar

    建立ActiveX dll程序,添加一个模块(DLL的函数只能在模块中才有效),在模块中编写你的DLL function过程函数,编写完毕,点保存,然后点"文件"菜单下的”选择DLL出口函数",在弹出窗口中选择需要申明为可以外部调用的...

    ZLG_UDS_DEMO.rar

    该应用程序包含对使用 ActiveX 控件的支持。 其他标准文件: StdAfx.h, StdAfx.cpp 这些文件用于生成名为 ZLG_UDS_DEMO.pch 的预编译头 (PCH) 文件和名为 StdAfx.obj 的预编译类型文件。 Resource.h 这是标准...

    Excel VBA实用技巧大全 附书源码

    01053利用CentimetersToPoints方法将计量单位从cm转换为磅 01054利用InchesToPoints方法将计量单位从in转换为磅 01055显示Excel内置对话框 01056显示常用的Excel内置对话框 01057获取Excel菜单栏信息 01058获取Excel...

Global site tag (gtag.js) - Google Analytics