vc6<实用>开发activex并发布全攻略(二)

原文:http://flashaway.blog.163.com/blog/static/95624576200942211853685/

小南瓜饼(^^):http://blog.csdn.net/Ibznphone


签名问题先关注:

http://blog.csdn.net/ibznphone/article/details/8066322

###########以下是针对上一篇我们自己开发的ActiveX发布时出现的问题补充############

 

 

呵呵,不要以为这样发布就会成功。

博文中说用工具查看我们自己开发的ActiveX控件GUID,但我的好像查看不了。

其实我们在vc工程中就能查看到。双击DMyActiveX接口类,

 

找到       [ uuid(743F39F2-E3A5-4550-A203-4A1CFAE9ABCF),

         helpstring("MyActiveX Control"), control ]

       coclass MyActiveX

       {

              [default] dispinterface _DMyActiveX;

              [default, source] dispinterface _DMyActiveXEvents;

       };

 

方法中743F39F2-E3A5-4550-A203-4A1CFAE9ABCF就是我们ActiveX的GUID.

 

vc6开发activex并发布全攻略(二)(初级篇) - 一闪而过 - 一闪而过的博客

 

还有一种方法就是打开VC的工具OLEView,懒的敲字了,看图吧:

vc6开发activex并发布全攻略(二)(初级篇) - 一闪而过 - 一闪而过的博客

vc6开发activex并发布全攻略(二)(初级篇) - 一闪而过 - 一闪而过的博客

vc6开发activex并发布全攻略(二)(初级篇) - 一闪而过 - 一闪而过的博客

 

我的MyActiveX.inf如下:

    [version]  

    signature="$CHINA$" 

    AdvancedINF=1.0 

     

    [Add.Code]  

    MyActiveX.ocx=MyActiveX.ocx  

    msvcr71.dll=msvcr71.dll  

    mfc71.dll=mfc71.dll  

    msvcp71.dll=msvcp71.dll

   

   [MyActiveX.ocx]  

   file=thiscab  

   clsid={743F39F2-E3A5-4550-A203-4A1CFAE9ABCF}  

   FileVersion=1,0,0,0 

   RegisterServer=yes  

    

   [msvcr71.dll]  

   file-win32-x86=thiscab  

   RegisterServer=no  

   DestDir=11 

   FileVersion=7,10,3052,4 

    

   [mfc71.dll]  

   file-win32-x86=thiscab  

   RegisterServer=no  

   DestDir=11 

   FileVersion=7,10,3077,0 

    

   [msvcp71.dll]  

   file-win32-x86=thiscab  

   RegisterServer=no  

   DestDir=11 

   FileVersion=7,10,3077,0 

 

按照上面的方法,用cabarc -s 6144 n MyActiveX.cab msvcr71.dll mfc71.dll msvcp71.dll MyActiveX.ocx MyActiveX.inf命令制作好MyActiveX..cab。

文件目录:

vc6开发activex并发布全攻略(二)(初级篇) - 一闪而过 - 一闪而过的博客

 

我们来写个测试页面,代码如下:

 

<object id='test1' codeBase='http://10.79.108.108/MyActiveX.cab#version=1,0,0,0' classid='clsid: 743F39F2-E3A5-4550-A203-4A1CFAE9ABCF ' height=0 width=0 ></object>

<script>

       a=test1.test(2,1);

       alert(a);

</script>

注意:链接IP改成你机子的IP

将它保存为test.html格式存放到IIS下,同时把MyActiveX也拷贝到IIS下,也就是C:\Inetpub\wwwroot下。

打开页面测试下:

http://10.79.108.108/test.html

弹出对话框:

vc6开发activex并发布全攻略(二)(初级篇) - 一闪而过 - 一闪而过的博客

 

选择是:

vc6开发activex并发布全攻略(二)(初级篇) - 一闪而过 - 一闪而过的博客

 

呵呵,弹出计算值3。算是成功了一半。那为什么系统没有提示下载控件呢?这是因为VS在编译的时候已经帮我们把控件注册到系统中了。

那现在首要的问题,就是先解决上面那个是否允许activex运行的提示框。

在网上查了下资料,说是要实现ISafeObject接口。那好,我们下面就来实现:打开工程,找到CMyActiveXCtr类,双击打开文件:

vc6开发activex并发布全攻略(二)(初级篇) - 一闪而过 - 一闪而过的博客

 

在文件中添加引用:

#include "comcat.h"

#include "Objsafe.h"

两个头文件。

并在DECLARE_DYNCREATE(CMyActiveXCtro)后添加如下代码:

DECLARE_INTERFACE_MAP()

       BEGIN_INTERFACE_PART(ObjSafe, IObjectSafety)

       STDMETHOD_(HRESULT, GetInterfaceSafetyOptions) (

               /* [in] */ REFIID riid,

               /* [out] */ DWORD __RPC_FAR *pdwSupportedOptions,

               /* [out] */ DWORD __RPC_FAR *pdwEnabledOptions

       );

        

       STDMETHOD_(HRESULT, SetInterfaceSafetyOptions) (

               /* [in] */ REFIID riid,

               /* [in] */ DWORD dwOptionSetMask,

               /* [in] */ DWORD dwEnabledOptions

       );

       END_INTERFACE_PART(ObjSafe);

效果如图:

vc6开发activex并发布全攻略(二)(初级篇) - 一闪而过 - 一闪而过的博客

 

在工程目录中切换到FileView模式,打开MyActiveXCtrl.cpp文件,

然后将以下代码添加到构造函数CMyActiveXCtrl:: CMyActiveXCtrl ()上面,CMyActiveXCtrl替换为你的控件名称:

/

// Interface map for IObjectSafety

 

BEGIN_INTERFACE_MAP( CMyActiveXCtrl, COleControl )

INTERFACE_PART(CMyActiveXCtrl, IID_IObjectSafety, ObjSafe)

END_INTERFACE_MAP()

 

/

// IObjectSafety member functions

 

// Delegate AddRef, Release, QueryInterface

 

ULONG FAR EXPORT CMyActiveXCtrl::XObjSafe::AddRef()

{

    METHOD_PROLOGUE(CMyActiveXCtrl, ObjSafe)

    return pThis->ExternalAddRef();

}

 

ULONG FAR EXPORT CMyActiveXCtrl::XObjSafe::Release()

{

    METHOD_PROLOGUE(CMyActiveXCtrl, ObjSafe)

    return pThis->ExternalRelease();

}

 

HRESULT FAR EXPORT CMyActiveXCtrl::XObjSafe::QueryInterface(

    REFIID iid, void FAR* FAR* ppvObj)

{

    METHOD_PROLOGUE(CMyActiveXCtrl, ObjSafe)

    return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj);

}

 

const DWORD dwSupportedBits =

INTERFACESAFE_FOR_UNTRUSTED_CALLER |

INTERFACESAFE_FOR_UNTRUSTED_DATA;

const DWORD dwNotSupportedBits = ~ dwSupportedBits;

 

/

// CStopLiteCtrl::XObjSafe::GetInterfaceSafetyOptions

// Allows container to query what interfaces are safe for what. We're

// optimizing significantly by ignoring which interface the caller is

// asking for.

HRESULT STDMETHODCALLTYPE

CMyActiveXCtrl::XObjSafe::GetInterfaceSafetyOptions(

/* [in] */ REFIID riid,

        /* [out] */ DWORD __RPC_FAR *pdwSupportedOptions,

        /* [out] */ DWORD __RPC_FAR *pdwEnabledOptions)

{

METHOD_PROLOGUE(CMyActiveXCtrl, ObjSafe)

 

HRESULT retval = ResultFromScode(S_OK);

 

// does interface exist?

IUnknown FAR* punkInterface;

retval = pThis->ExternalQueryInterface(&riid,

     (void * *)&punkInterface);

if (retval != E_NOINTERFACE) { // interface exists

punkInterface->Release(); // release it--just checking!

}

 

// we support both kinds of safety and have always both set,

// regardless of interface

*pdwSupportedOptions = *pdwEnabledOptions = dwSupportedBits;

 

return retval; // E_NOINTERFACE if QI failed

}

 

/

// CStopLiteCtrl::XObjSafe::SetInterfaceSafetyOptions

// Since we're always safe, this is a no-brainer--but we do check to make

// sure the interface requested exists and that the options we're asked to

// set exist and are set on (we don't support unsafe mode).

HRESULT STDMETHODCALLTYPE

CMyActiveXCtrl::XObjSafe::SetInterfaceSafetyOptions(

        /* [in] */ REFIID riid,

        /* [in] */ DWORD dwOptionSetMask,

        /* [in] */ DWORD dwEnabledOptions)

{

    METHOD_PROLOGUE(CMyActiveXCtrl, ObjSafe)

 

// does interface exist?

IUnknown FAR* punkInterface;

pThis->ExternalQueryInterface(&riid, (void * *)&punkInterface);

if (punkInterface) { // interface exists

punkInterface->Release(); // release it--just checking!

}

else { // interface doesn't exist

return ResultFromScode(E_NOINTERFACE);

}

 

// can't set bits we don't support

if (dwOptionSetMask & dwNotSupportedBits) {

return ResultFromScode(E_FAIL);

}

 

// can't set bits we do support to zero

dwEnabledOptions &= dwSupportedBits;

// (we already know there are no extra bits in mask )

if ((dwOptionSetMask & dwEnabledOptions) !=

   dwOptionSetMask) {

return ResultFromScode(E_FAIL);

}       

 

// don't need to change anything since we're always safe

return ResultFromScode(S_OK);

}

效果如下图,注意画红框的地方:

vc6开发activex并发布全攻略(二)(初级篇) - 一闪而过 - 一闪而过的博客

 

F7编译以后,按前面的步骤重新发布。

打开测试页面http://10.79.108.108/test.html,呵呵那个讨厌的对话框消失了。

现在这个ActiveX是完全做好了,下一步我们来看看怎样让用户下载安装。

先在本地电脑测试:

因为我们用VC编译时,VC已经帮我们把ActiveX注册到系统中了,所以我们想看到下载安装画面,先必须删除注册信息。

打开运行窗口,输出regedit命令,查找我们的控件GUI: 743F39F2-E3A5-4550-A203-4A1CFAE9ABCF

vc6开发activex并发布全攻略(二)(初级篇) - 一闪而过 - 一闪而过的博客

 

我这里找到三项,那全部删除。

在打开测试页面之前,我们还得做个工作,就是设置IE安全。打开IE工具->Internet选项,如果是局域网,设置本地Intrance,允许下载未签名和已签名的ActiveX。如果是外网,方法一样。

vc6开发activex并发布全攻略(二)(初级篇) - 一闪而过 - 一闪而过的博客

 

现在打开测试页http://10.79.108.108/test.html

vc6开发activex并发布全攻略(二)(初级篇) - 一闪而过 - 一闪而过的博客

 

成功弹出下载ActiveX对话框。

点击安装,程序正常运行。OK,我们已经成功了一半。

 

上面只是在本地测试成功。现在在其他计算机上访问测试页,不要忘了IE的安全设置。打开页面后也是弹出上面的安装界面。可是,点安装后,程序无法正常运行。而且每次刷新页面,安装对话框总是弹出,很是郁闷。

经过Baidu,又找到了方法。原来是其他计算机上没有安装我们activeX运行所需的库文件。那我们就想办法让用户把这用到的DLL全部下载。

那首先得知道我们的activeX用到了哪些库。如下图,打开VC的工具Depends

vc6开发activex并发布全攻略(二)(初级篇) - 一闪而过 - 一闪而过的博客

 

选择我们的MyActiveX.ocx控件,如下图:

vc6开发activex并发布全攻略(二)(初级篇) - 一闪而过 - 一闪而过的博客

 

那我们可以看到我们用到的DLL有6个,一般Kernel32.DLL和OLEAUT32.DLL文件每个操作系统都有,所以剩下的4个DLL,在你机子上全盘搜索,找到这4个dll后将他们放入你的MyActiveX.ocx相同文件夹下,编辑MyActiveX.inf, 这些dll的版本信息FileVersion可以在此dll上点击右键->属性中得到:

    [version]  

    signature="$CHINA$" 

    AdvancedINF=1.0 

     

    [Add.Code]  

    MyActiveX.ocx=MyActiveX.ocx  

    msvcr71.dll=msvcr71.dll  

    mfc71.dll=mfc71.dll  

    msvcp71.dll=msvcp71.dll

    MFC42D.dll=MFC42D.dll  

    MSVCRTD.DLL=MSVCRTD.DLL

    gdi32.dll=gdi32.dll

    MFCO42D.DLL=MFCO42D.DLL

 

   [MyActiveX.ocx]  

   file=thiscab  

   clsid={743F39F2-E3A5-4550-A203-4A1CFAE9ABCF}  

   FileVersion=1,0,0,0 

   RegisterServer=yes  

    

   [msvcr71.dll]  

   file-win32-x86=thiscab  

   RegisterServer=no  

   DestDir=11 

   FileVersion=7,10,3052,4 

    

   [mfc71.dll]  

   file-win32-x86=thiscab  

   RegisterServer=no  

   DestDir=11 

   FileVersion=7,10,3077,0 

    

   [msvcp71.dll]  

   file-win32-x86=thiscab  

   RegisterServer=no  

   DestDir=11 

   FileVersion=7,10,3077,0 

 

   [MFC42D.dll]  

   file-win32-x86=thiscab  

   RegisterServer=no  

   DestDir=11 

   FileVersion=6.0.9782.0

 

   [MSVCRTD.DLL]  

   file-win32-x86=thiscab  

   RegisterServer=no  

   DestDir=11 

   FileVersion=6.0.9782.0

 

   [gdi32.dll]  

   file-win32-x86=thiscab  

   RegisterServer=no  

   DestDir=11 

   FileVersion=5.2.3790.2542 

 

   [MFCO42D.DLL]  

   file-win32-x86=thiscab  

   RegisterServer=no  

   DestDir=11 

   FileVersion=6.0.9782.0

保存后文件目录如下:

vc6开发activex并发布全攻略(二)(初级篇) - 一闪而过 - 一闪而过的博客

 

用 cabarc -s 6144 n MyActiveX.cab msvcr71.dll mfc71.dll msvcp71.dll MFC42D.dll MSVCRTD.DLL gdi32.dll MFCO42D.DLL MyActiveX.ocx MyActiveX.inf

命令生成MyActiveX.cab文件。

在其他计算机上打开测试页。安装ActiveX成功,并且运行正常。

就此,一个简单的ActiveX发布成功了。

后面,我们还将对我们的ActiveX增加新的功能。敬请关注。

呵呵,好累啊~~~~

打完收工…………………….

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值