`
ispring
  • 浏览: 355795 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

web上用Activex控件开发步骤(MFC)

阅读更多

首先要说明的是 web上用activex是门被抛弃的技术。为什么这么说,主要基于以下几个原因:1.功能过于强大,强大到一旦安装,他所具有的权限可以做任何事,极易被人利用做坏事(相信大家都有浏览网页后莫名被安装流氓软件的经历,当然流氓软件利用的方式不止控件一种);2。通过网页下载控件的中间过程受到操作系统、杀毒软件、浏览器等多方面因素限制,这使你的控件产品未必能在所有用户的电脑上正常使用;3。最恶心的一点,未签名没有正规安全证书的控件,在最新的浏览器上(IE7等)默认安全策略是直接屏蔽掉的,而你如果想要获取这个信任,需要向微软等少数单位申请,花费有多少?据说是每年4千多。。。
   看了以上如果你还是想要知道步骤,如下:
一。用Vc++6.0新建工程里的向导创建MFC activeX controlWizard,细节不说了,根据你控件需要了,略有不同,问题不会太大。

二。你控件代码的主xx.cpp(非xxCtr.cpp)文件中添加安全接口函数,否则每次运行控件时IE都会给出安全提示,很烦!
#include "comcat.h"
#include "Objsafe.h"

// 本控件的CLSID,注册表用
const GUID CDECL CLSID_SafeItem ={ 0x7AE7497B, 0xCAD8, 0x4E66,
                      { 0xA5,0x8B,0xDD,0xE9,0xBC,0xAF,0x6B,0x61 } };
// 版本控制
const WORD _wVerMajor = 1;
// 次版本号
const WORD _wVerMinor = 0;


/////////////////////////////////////////////////////////////////////
// CICCardApp::InitInstance - DLL initialization

BOOL CICCardApp::InitInstance()
{
    BOOL bInit = COleControlModule::InitInstance();

    if (bInit)
    {
   
    }

    return bInit;
}


//////////////////////////////////////////////////////////////////////
// CICCardApp::ExitInstance - DLL termination

int CICCardApp::ExitInstance()
{
    return COleControlModule::ExitInstance();
}


//////////////////////////////////////////////////////////////////////

// 创建组件种类
HRESULT CreateComponentCategory(CATID catid, WCHAR* catDescription)
{
    ICatRegister* pcr = NULL ;
    HRESULT hr = S_OK ;

    hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr,
            NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr);
    if (FAILED(hr))
        return hr;

    // Make sure the HKCR\Component Categories\{..catid...}
    // key is registered.
    CATEGORYINFO catinfo;
    catinfo.catid = catid;
    catinfo.lcid = 0x0409 ; // english

    // Make sure the provided description is not too long.
    // Only copy the first 127 characters if it is.
    int len = wcslen(catDescription);
    if (len>127)
        len = 127;
    wcsncpy(catinfo.szDescription, catDescription, len);
    // Make sure the description is null terminated.
    catinfo.szDescription[len] = '\0';

    hr = pcr->RegisterCategories(1, &catinfo);
        pcr->Release();

    return hr;
}

// 注册组件种类
HRESULT RegisterCLSIDInCategory(REFCLSID clsid, CATID catid)
{
    // Register your component categories information.
    ICatRegister* pcr = NULL ;
    HRESULT hr = S_OK ;
    hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr,
                NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr);
    if (SUCCEEDED(hr))
    {
       // Register this category as being "implemented" by the class.
       CATID rgcatid[1] ;
       rgcatid[0] = catid;
       hr = pcr->RegisterClassImplCategories(clsid, 1, rgcatid);
    }
    if (pcr != NULL)
        pcr->Release();
    return hr;
}
// 卸载组件种类
HRESULT UnRegisterCLSIDInCategory(REFCLSID clsid, CATID catid)
{
    ICatRegister* pcr = NULL ;
    HRESULT hr = S_OK ;

    hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr,
            NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr);
    if (SUCCEEDED(hr))
    {
       // Unregister this category as being "implemented" by the class.
       CATID rgcatid[1] ;
       rgcatid[0] = catid;
       hr = pcr->UnRegisterClassImplCategories(clsid, 1, rgcatid);
    }

    if (pcr != NULL)
        pcr->Release();

    return hr;
}


// DllRegisterServer - Adds entries to the system registry
STDAPI DllRegisterServer(void)
{
    HRESULT hr;

    AFX_MANAGE_STATE(_afxModuleAddrThis);

    if (!AfxOleRegisterTypeLib(AfxGetInstanceHandle(), _tlid))
        return ResultFromScode(SELFREG_E_TYPELIB);

    if (!COleObjectFactoryEx::UpdateRegistryAll(TRUE))
        return ResultFromScode(SELFREG_E_CLASS);

    // 标记控件初始化安全.
    // 创建初始化安全组件种类
    hr = CreateComponentCategory(CATID_SafeForInitializing,
               L"Controls safely initializable from persistent data!");
    if (FAILED(hr))
        return hr;
    // 注册初始化安全
    hr = RegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForInitializing);
    if (FAILED(hr))
        return hr;

    // 标记控件脚本安全
    // 创建脚本安全组件种类
    hr = CreateComponentCategory(CATID_SafeForScripting, L"Controls safely scriptable!");
    if (FAILED(hr))
        return hr;
    // 注册脚本安全组件种类
    hr = RegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForScripting);
    if (FAILED(hr))
        return hr;

    return NOERROR;
}


//////////////////////////////////////////////////////////////////
// DllUnregisterServer - Removes entries from the system registry

STDAPI DllUnregisterServer(void)
{
    HRESULT hr;

    AFX_MANAGE_STATE(_afxModuleAddrThis);

    if (!AfxOleUnregisterTypeLib(_tlid, _wVerMajor, _wVerMinor))
        return ResultFromScode(SELFREG_E_TYPELIB);

    if (!COleObjectFactoryEx::UpdateRegistryAll(FALSE))
        return ResultFromScode(SELFREG_E_CLASS);

    // 删除控件初始化安全入口.
    hr=UnRegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForInitializing);
    if (FAILED(hr))
        return hr;
    // 删除控件脚本安全入口
    hr=UnRegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForScripting);
    if (FAILED(hr))
        return hr;

//////////////////////////
    return NOERROR;
}

三。添加自己的代码到控件文件xxCtr.cpp中,这里最好通过向导添加View->ClassWard->automation。

四。编译生成你的xx.ocx控件文件,这个文件其实就是个DLL函数库,只是后缀不同而已。

五。制作xx.inf文件用于之后的空间打包压缩。红色部分为需要根据你自己情况修改的地方。
[version]  
signature="$CHICAGO$"  
AdvancedINF=1.0  
[Add.Code]  
xx.ocx=xx.ocx  
[xx.ocx]
  
file-win32-x86=thiscab  
clsid={351FC603-D784-4B8D-BA2C-33C212EC5BAA}  
FileVersion=1,0,0,1  
RegisterServer=yes
  

六。打包压缩成xx.cab文件。你需要用到给控件签名的一些工具:cabarc.exe、signcode.exe,另外你可能需要用于制作自己试验证书的工具:makecert.exe、cert2spc.exe。
制作根证书MyCert.cer和私钥myKey.PVK:
makecert -r  -sv "myKey.PVK"  -n CN="xx Electric Industry Co. Ltd."   MyCert.cer
CERT2SPC MyOKIcert.cer MyOKIcert.spc
打包压缩空间为xx.cab:
cabarc -s 6144 n xx.cab xx.ocx xx.inf
数字签名cab文件
双击signocode.exe文件,图形化签名,注意要通过自定义选择自己的证书和私钥而不是选择系统已有的。

七。在你要用空间的Web上添加代码:
             <td colspan="2"><object id='t1' codeBase=/UserMode/xx.cab#version=1,0,0,1 classid='clsid:F3530445-A287-4A0B-AC3E-C4AF2B63EBA7' height=0 width=0 ></object></td>

八。调用控件内方法。通过javascript直接调用控件对象的方法就行了,比如调用空间中存在的一个download()方法: document.getElementByID("t1").download();

八。客户端使用,其他人从网上下载到你的控件后,如果是Window XP系统的话,需要先导入证书为可信任(详细到Google上搜索导入证书,很容易),再安装控件,之后才能用;而如果是Window2000用户则只要安装控件就可以使用了。

九。控件的删除。Internet选项-〉设定-〉显示对象,直接看到你的xx.cab文件,Del掉就行了,注册表中信息会自动消除掉,当然你也可以直接到注册表中删除对应xx.inf中列出的键值的项。

十。升级。只要在源代码中更改xx.rc文件中对应的那些1.0.0.1为你的新版本号,并同时更改你调用控件的web上的版本号就可以了,下一次客户访问这个页面时会自动提示安装新控件,新控件会覆盖就版本的控件。

   以上仅供参考,本人也是新手,最近工作需要用控件才能完成一些功能,以上包含了我开发过程中碰到的诸多问题,希望对所有人能有所帮助

分享到:
评论
1 楼 jerry_zmq 2008-09-11  
您的 STDAPI DllUnregisterServer(void) 在实际调用中,是会报错的,然后仔细看了下你的代码发现,你在调用删除控件初始化安全入口和删除控件脚本安全入口之前就先删除了控件,所以会报错,所以我给你换了下先后位置,这样就好了,如下:
STDAPI DllUnregisterServer(void)
{
HRESULT hr;
AFX_MANAGE_STATE(_afxModuleAddrThis);

// 删除控件脚本安全入口
hr=UnRegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForScripting);
if (FAILED(hr))
{
AfxMessageBox("删除控件脚本安全入口失败!", MB_ICONSTOP | MB_OK);
return hr;
}
// 删除控件初始化安全入口.
hr=UnRegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForInitializing);
if (FAILED(hr))
{
AfxMessageBox("删除控件初始化安全入口!", MB_ICONSTOP | MB_OK);
return hr;
}
if (!AfxOleUnregisterTypeLib(_tlid, _wVerMajor, _wVerMinor))
return ResultFromScode(SELFREG_E_TYPELIB);

if (!COleObjectFactoryEx::UpdateRegistryAll(FALSE))
return ResultFromScode(SELFREG_E_CLASS);

//////////////////////////
return NOERROR;
}

相关推荐

    Activex\web上用Activex控件开发步骤(MFC).

    Activex\web上用Activex控件开发步骤(MFC).

    基于MFC的ActiveX控件开发(VC2005).pdf

    基于MFC的ActiveX控件开发: 在VC 下ActiveX 控件的开发可以分为三种,一种是直接用COM 的API 来开发, 这样做显然非常的麻烦,对程序员要求也非常高,因此一般是不予考虑的;一种是基于传统 的MFC,采用面向对象的...

    基于MFC的ActiveX控件开发.doc

    ActiveX 控件是基于组件对象模型 (COM) 的可重用软件组件,广泛应用于桌面及Web应用中。在VC下ActiveX控件的开发...本文介绍的是采用第二种方式,即应用MFC进行桌面可视控件开发的方法步骤,开发环境则是基于VC2005。

    vc++ 开发实例源码包

    内含各种例子(vc下各种控件的使用方法、标题栏与菜单栏、工具栏与状态栏、图标与光标、程序窗口、程序控制、进程与线程、字符串、文件读写操作、文件与文件夹属性操作、文件与文件夹系统操作、系统控制操作、程序...

    vc++ 应用源码包_1

    内含各种例子(vc下各种控件的使用方法、标题栏与菜单栏、工具栏与状态栏、图标与光标、程序窗口、程序控制、进程与线程、字符串、文件读写操作、文件与文件夹属性操作、文件与文件夹系统操作、系统控制操作、程序...

    vc++ 应用源码包_2

    内含各种例子(vc下各种控件的使用方法、标题栏与菜单栏、工具栏与状态栏、图标与光标、程序窗口、程序控制、进程与线程、字符串、文件读写操作、文件与文件夹属性操作、文件与文件夹系统操作、系统控制操作、程序...

    vc++ 应用源码包_6

    内含各种例子(vc下各种控件的使用方法、标题栏与菜单栏、工具栏与状态栏、图标与光标、程序窗口、程序控制、进程与线程、字符串、文件读写操作、文件与文件夹属性操作、文件与文件夹系统操作、系统控制操作、程序...

    vc++ 应用源码包_3

    内含各种例子(vc下各种控件的使用方法、标题栏与菜单栏、工具栏与状态栏、图标与光标、程序窗口、程序控制、进程与线程、字符串、文件读写操作、文件与文件夹属性操作、文件与文件夹系统操作、系统控制操作、程序...

    vc++ 应用源码包_5

    内含各种例子(vc下各种控件的使用方法、标题栏与菜单栏、工具栏与状态栏、图标与光标、程序窗口、程序控制、进程与线程、字符串、文件读写操作、文件与文件夹属性操作、文件与文件夹系统操作、系统控制操作、程序...

    C#微软培训资料

    4.2 引 用 类 型 .33 4.3 装箱和拆箱 .39 4.4 小 结 .42 第五章 变量和常量 .44 5.1 变 量 .44 5.2 常 量 .46 5.3 小 结 .47 第六章 类 型 转 换 .48 6.1 隐式类型转换 .48 6.2 显式类型转换 .53 ...

Global site tag (gtag.js) - Google Analytics