分享

VC ActiveX插件开发

 daren2011 2014-09-06

VC ActiveX插件开发

全文参考:组件开发:http://www.cnblogs.com/phinecos/archive/2008/07/25/1251743.html

          安全接口:http://www.cnblogs.com/phinecos/archive/2008/08/07/1263270.html

                    http://blog.csdn.net/isadream/archive/2008/05/14/2445493.aspx

          签名:http://hi.baidu.com/ipeter/blog/item/5bfa75f08f878bc67831aa08.html

          免费数字证书:http://blog.csdn.net/Mobidogs/archive/2008/01/23/2062040.aspx

          CSDN打包:http://support.microsoft.com/kb/167158

CSDN安全接口:http://support.microsoft.com/kb/161873/en-us

一、           确定目标:

二、使用VS 2005 MFC ActiveX Ctronl进行开发。

三、           创建工程步骤:

1、打开VS2005,选择-》new project-》VC++->MFC ActiveX Controll如下图:

             

                                    图1

2、 选择OK-》NEXT出现:

 

                                     图2

3、选中Run-time license项,再点击NEXT-》NEXT出现如下对话框:

 

                                     图3

 

我们选择AcitveX when visible 和 fisker-free activeation,不需要选择:has an about box dialog,如果你想要该项则选中它。最后点击FINISH,我们在这里就完成了ActiveX插件的创建过程,该插件为空,使用VS自带工具ActiveX Control test container里测试只显示一个空圆。

   

 

四、           创建对话框:

 在创建完ActiveX后,我们可以看到工程里包含以下几个文件:

 

 1)CTestActiveXApp:这是ActiveX应用程序类,从COleControlModule类继承下来的。它是OLE控件模块对象继承自的基类,包含了初始化(InitInstance)和清理(ExitInstance)的代码

      2)CTestActiveXCtrl:从COleControl继承而来,这里是我们实现控件大部分功能的地方。

      3)CTestActiveXPropPage:从COlePropertyPage继承而来,用于管理控件的属性页对话框。向导已经为我们创建了一个默认的对话框来作为控件的属性页对话框。

此处,我们不使用向导创建的对话框(也可使用,为了更好让各位了解方法,采用新建对话框方式 )。

1、  插入对话框:

 选择Resource View右键单击Dialog项目选择-》insert dialog

 

在属性页里我们更改对话ID为IDD_MAIN_DIALOG, 更改属性:Border—none, Style – Child, System Menu – False, Visible – True.这里我们就已经插入了一个对话。

2、  为对话框添加类

右键IDD_MAIN_DIALOG对话框空白处-》Add Class,我们为对话框添加类:CMainDlg,Base Class选择:CDialog点击FINISH即完成了添加类过程。

3、  显示对话框:

在以上我们添加的对话框在我们测试时它不会显示出来,我们还需要以下过程 :

在CTestActiveXCtrl类中添加头文件#include”MainDlg.h”并添加变量CMainDlg m_pMainDlg;

为CTestActiveXCtrl类添加WM_CREATE消息,并添加以下内容:

   int CMyActiveXCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
 if (COleControl::OnCreate(lpCreateStruct) == -1)
  return -1;

 // TODO:  Add your specialized creation code here
    m_MainDlg.Create(IDD_MAIN_DIALOG, this);
 return 0;
}

在OnDrawn函数中我们需移动对话位置以让它显示出来 :

  void CMyActiveXCtrl::OnDraw(
   CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
{
 DoSuperclassPaint(pdc, rcBounds);
 m_MainDlg.MoveWindow(rcBounds, TRUE);
 CBrush brBackGnd(TranslateColor(AmbientBackColor()));
 pdc->FillRect(rcBounds, &brBackGnd);
}

编译:修改project属性:

我们将use of mfc改为静态库连接,选择Release编译,我们就可得到TestActiveX.ocx文件。这就是我们开发的插件了。

到这里一个简单的ActiveX开发已经完毕,我们使用VS自带工具ActiveX Control test container测试可发现可显示出一个对话框。

注:本机注册组件方法:

Regsvr32 桌面/TestActiveX\Release\TestAtiveX.ocx即可注册,在注册表里我们可以找到相应CLASSID

五、           在网页中使用此ActiveX

       开发至此,我们将学习在网页里使用ActiveX,可以使用微软的ActiveX Control Pad(点击下载)。要利用它在Web页面中插入一个ActiveX控件,在<BODY>标记中右键,选择“Insert ActiveX Control”,选择你需要的就可以了。

 

                                                     图4

 

                                                         图5

 

 

我们更改为<object>标签添加codebase属性

 <object  id=”MyActiveX1”width=350 height=50 classid=”CLSID:36299202-09ef-4abf-adb9-47c599dbe778” codebase=http://192.168.1.12/dd/ocx/TestActiveX.ocx#version=1,0,0,2>//客户端可根据//CODEBASE路径属性下载插件安装

           ……………..

</object>

至此网页容器开发完毕,我们在IIS或本地浏览将可看到对话显示出来 。

但至此ActiveX控件并末开发完毕,我们还需为其添加安全接口和数字签名。

 

六、           添加安全接口:

在客户端浏览器ActiveX容器时,我们可看到会弹出窗口:

 

下面我们介绍将其定义为安全接口 :

 参考:MSDN帮助http://support.microsoft.com/kb/161873/en-us

在APP里参照以下进行更改即可。

CMyActiveXApp theApp;

#include "strsafe.h"

#include <comcat.h>   

#include <objsafe.h>    //需要包含这三个头文件

// 本控件的CLSID,注册表用  

 

 

const GUID CDECL BASED_CODE _tlid =

      { 0x6a7e4bf6, 0xc523, 0x479d, { 0xbe, 0xac, 0x98, 0xce, 0xc2, 0x1, 0x2, 0x33 } }; //带version(1.0)字段,在工程里ODL文件中获取[ uuid(6A7E4BF6-C523-479D-BEAC-98CEC2010233), version(1.0), helpfile("MyActiveX.hlp"),helpstring("MyActiveX ActiveX Control module"),control ] 

 

// 版本控制  

const WORD _wVerMajor = 1;   

// 次版本号  

const WORD _wVerMinor = 0;   

const CATID CATID_SafeForScripting     =

      {0x7dd95801,0x9882,0x11cf,{0x9f,0xa9,0x00,0xaa,0x00,0x6c,0x42,0xc4}};//此段无需更改

      const CATID CATID_SafeForInitializing  =

      {0x7dd95802,0x9882,0x11cf,{0x9f,0xa9,0x00,0xaa,0x00,0x6c,0x42,0xc4}};//此段无需更改

 

const CATID CLSID_SafeItem =

       {0xABAD1B64,0xCD91,0x4839,{0xAB,0xE6,0xBA,0xE8,0x2C,0xC3,0xE6,0xF7}};//在工程里ODL文件中获取后带control字段,为本控件的注册CLASSID。[ uuid(ABAD1B64-CD91-4839-ABE6-BAE82CC3E6F7),helpstring("MyActiveX Control"), control ]

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

// CMyActiveXApp::InitInstance - DLL initialization

 

BOOL CMyActiveXApp::InitInstance()

{

     BOOL bInit = COleControlModule::InitInstance();

    if (bInit)

    {

    }

    return bInit;

}

 

 

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

// CMyActiveXApp::ExitInstance - DLL termination

 

int CMyActiveXApp::ExitInstance()

{

     // TODO: Add your own module termination code here.

 

     return COleControlModule::ExitInstance();

}

 

 

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

 

 

 

// 创建组件种类  

HRESULT CreateComponentCategory(CATID catid, CHAR *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

    size_t len;

    // Make sure the provided description is not too long.

    // Only copy the first 127 characters if it is.

    // The second parameter of StringCchLength is the maximum

    // number of characters that may be read into catDescription.

    // There must be room for a NULL-terminator. The third parameter

    // contains the number of characters excluding the NULL-terminator.

    hr = StringCchLength(catDescription, STRSAFE_MAX_CCH, &len);

    if (SUCCEEDED(hr))

    {

        if (len>127)

        {

            len = 127;

        }

    

    else

    {

        // TODO: Write an error handler;

    }

    // The second parameter of StringCchCopy is 128 because you need

    // room for a NULL-terminator.

    hr = StringCchCopy(COLE2T(catinfo.szDescription), len + 1, catDescription);

    // Make sure the description is null terminated.

    catinfo.szDescription[len + 1] = '\0';

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

    pcr->Release();

    return hr;

}

 

//      Register your component categories information

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 - Remove entries from the registry

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);

    // Mark the control as safe for initializing.

    hr = CreateComponentCategory(CATID_SafeForInitializing,

        _T("Controls safely initializable from persistent data!"));

    if (FAILED(hr))

        return hr;

    hr = RegisterCLSIDInCategory(CLSID_SafeItem,

        CATID_SafeForInitializing);

    if (FAILED(hr))

        return hr;

    // Mark the control as safe for scripting.

    hr = CreateComponentCategory(CATID_SafeForScripting,

        _T("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);

    // Remove entries from the registry.

    hr=UnRegisterCLSIDInCategory(CLSID_SafeItem,

        CATID_SafeForInitializing);

    if (FAILED(hr))

        return hr;

    hr=UnRegisterCLSIDInCategory(CLSID_SafeItem,

        CATID_SafeForScripting);

    if (FAILED(hr))

        return hr;

    if (!AfxOleUnregisterTypeLib(_tlid, _wVerMajor, _wVerMinor))

        return ResultFromScode(SELFREG_E_TYPELIB);

    if (!COleObjectFactoryEx::UpdateRegistryAll(FALSE))

        return ResultFromScode(SELFREG_E_CLASS);

    return NOERROR;

}

至此,我们已对控件进行安全接口定义,WINDOWS系统将可识别其为安全脚本。

但在IE6以上版本对AcitveX进行了约束,我们需要对其添加数字签名才能被客户下载。

 

六、数字签名:

在VS里有附带makecert.exe工具可产生测试证书,并此证书并不能在互联使用,我们需要一个正版数字证书,不过大部分需要钱。

数字签名:

    在VS里有个签名工具signtool(VC6里为signcode)在VS 命令行里我们输入 signtool signwizard可弹出签名向导,我们只需按步骤即可完成签名。

有问题联系 QQ:574781136

           email:johin.123@hotmail.com

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多