COM组件开发实践(三)

前面两篇文章分别介绍了MFC ActiveX应用程序和使用ATL开发ActiveX的简单实例,但还有两个问题需要解决:

1)标记ActiveX控件为安全的控件 2)对控件进行数字签名。本文将结合这两点进行简单的介绍。

Building a Safe ActiveX Control

如何不想办法将控件标记为安全的,就会在Web页面与控件进行交互时出现如下图的警告信息:

下面将分别介绍在MFC ActiveX和ATL中如何标记一个控件为安全的控件。

要标记一个MFC ActiveX控件为安全,可以仿照下面代码修改而得:

// CardScan.cpp : CCardScanApp 和DLL 注册的实现。#include "stdafx.h"#include "CardScan.h"#include "comcat.h"#include "strsafe.h"#include "objsafe.h"CCardScanApp theApp;const GUID CDECL BASED_CODE _tlid =        { 0x29959268, 0x9729, 0x458E, { 0xA8, 0x39, 0xBB, 0x39, 0x2E, 0xCB, 0x7E, 0x37 } };const WORD _wVerMajor = 1;const WORD _wVerMinor = 0;const CATID CLSID_SafeItem ={0xB548F3C7,0x2135,0x4242,{0x92,0x0B,0xA7,0xBD,0xEE,0x6D,0x2B,0xA3}};//{ 0x36299202, 0x9ef, 0x4abf,{ 0xad, 0xb9, 0x47, 0xc5, 0x99, 0xdb, 0xe7, 0x78}};// CCardScanApp::InitInstance - DLL 初始化BOOL CCardScanApp::InitInstance(){    BOOL bInit = COleControlModule::InitInstance();    if (bInit)    {    }    return bInit;}// CCardScanApp::ExitInstance - DLL 终止int CCardScanApp::ExitInstance(){    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;}// HRESULT RegisterCLSIDInCategory -//      Register your component categories informationHRESULT 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 registryHRESULT 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 - 将项添加到系统注册表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 - 将项从系统注册表中移除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;}

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索控件
, return
, if
, hresult
, HR
The
前端组件化开发实践、vue组件化开发实践、com组件开发、vc com组件开发教程、com组件开发教程,以便于您获取更多的相关知识。

时间: 2024-08-09 23:40:34

COM组件开发实践(三)的相关文章

COM组件开发实践(八)---多线程ActiveX控件和自动调整ActiveX控件大小(下)

声明:本文代码基于CodeProject的文章<A Complete ActiveX Web Control Tutorial>修改而来,因此同样遵循Code Project Open License (CPOL). 在上一篇文章<COM组件开发实践(七)---多线程ActiveX控件和自动调整ActiveX控件大小(上)>中介绍了ActiveX控件中使用多线程的基本需求,并提出了一个简单的线程模型,但却出现了意想不到的问题,本文将尝试给出问题的一个可行的解法,并同时解决上文中提出

COM组件开发实践(六)---From C++ to COM :Part 3

在上一篇文章<COM组件开发实践(五)---From C++ to COM :Part 2 >中,我们进展到使用COM库加载C++对象了,这一篇中我们将真正将C++对象变成 COM对象,而在下一篇中我们将为它添加多接口支持. C++对象变成COM对象 要将一个C++对象变成一个真正的COM对象,只需要如下操作: 1)实现接口的引用计数.因此每个COM对象都需要有两个函数用于管理引用计数: ULONG AddRef(); ULONG Release(); 这两个函数不返回HRESULT,因为它们

COM组件开发实践(五)---From C++ to COM :Part 2

一,使用抽象基类重用C++对象 在上一篇文章<COM组件开发实践(四)---From C++ to COM :Part 1>中,我们已经将要复用的C++对象封装到DLL中了,对象的声明和实现已经实现了剥离,但还有问题:对象的私有成员(如我们示例中CDB类的数组变量m_arrTables)还是被客户看得一清二楚,即使客户没办法去访问它们:若对象改变了它的数据成员的大小,则所有的客户程序必须重新编译. 而实际上,客户需要的仅仅是对象的成员函数的地址,因此使用抽象基类可以很好地满足以上需求,客户就不

COM组件开发实践(四)---From C++ to COM :Part 1

一,C++客户重用C++对象 假设已经有一个可以重用的类,我们就可以在自己的程序中去重用它,只需要将其定义和实现文件加入到我们自己的工程中,并且在使用它的文件中包含此类的定义文件就可以了,这也是我们最常用的C++标准重用方法.就拿我自己来说,在CodeProject上遇到比较好的控件代码,都是这样直接用到自己的项目中来的. 下面就给出我这个系列的第一个代码示例,在接下来的几篇文章中,将基于此代码不断进行改进,一步步从C++走向COM. 简单介绍下我们要重用的C++对象,它是一个简单的类似数据库的

COM组件开发实践(一)

开发实践(一)-前端组件化开发实践"> Preface 因为项目需要,开始从事ActiveX方面的工作,看了一些资料,可惜都是些COM原理方面的,没有切合实际动手的东西,在CodeProject上读完David Marcionek的文章[1]后,收获良多,但也遇到一些恼人的小问题,因此在其基础上就一些易错点做些小注解.本文版权归David Marcionek所有. 简介 在本文中,我们将创建一个ActiveX控件,当加载控件时,它会显示一个动画进度条,以便向用户表明控件正在加载.此控件会包

COM组件开发实践(七)---多线程ActiveX控件和自动调整ActiveX控件大小(上)

声明:本文代码基于CodeProject的文章<A Complete ActiveX Web Control Tutorial>修改而来,因此同样遵循Code Project Open License (CPOL). 最近遇到两个需求:1)在ActiveX控件中使用工作线程来完成底层的硬件设备扫描任务,并在工作线程中根据操作结果回调外部web页面的JavaScript函数:2)能根据控件任务的不同自动调整控件大小.但在查阅了大量资料后,发现网上讨论ActiveX中多线程开发的文章基本没有,最后

COM组件开发实践(二)

假设需求如下:底层是一个数学运算库DLL,中间是ActiveX控件(它调用底层的数学运算库DLL来完成控制层),界面层在测试时可以是一个exe程序,最后发布到IE浏览器上测试. 数学运算库DLL的开发 新建一个Win32 DLL项目,加入一个头文件MyNum.h,在其中声明所有的数学函数(为简单起见,本文只考虑加法运算),代码如下: #ifndef MY_NUM_H #define MY_NUM_H int __stdcall AddNum(int,int); #endif 请注意这里的方法声明

ASP.NET自定义控件组件开发 第三章 为控件添加事件 后篇

前一篇文章只是简单的说了下事件,但是大家应该方法,在ASP.NET自定义控件中只是简单那么定义事 件是行不通.如果大家开发的是WinForm中的事件,之前的定义可能没有什么大的问题,只是在效率方法 欠考虑而且,还是可以运行的. 下面我们就回到ASP.NET中的事件. 大家也许看了我们之前定义的事件,确实,事件一般是那么定义的,但是那样定义事件后的,运行起 来的效率不搞,因为那样定义事件后,编译器在编译事件代码的时候,会自动的为我们加入很多多线程安 全的代码,就是说,虽然我们只是定义几行代码,大但

ASP.NET自定义控件组件开发 第三章 为控件添加事件 前篇

好了,我们之前以前开发一个控件.而且也添加了属性,开发也很规范,但是那个控件还差最后一点 :添加事件. ASP.NET的开发都是事件驱动的,现在我们就来为控件添加事件.在说事件之前,希望大家对C#的语法 要熟悉,对委托很事件要懂. 其实定义事件的步骤很简单: 1.声明一个委托. 2.定义一个携带事件信息的类. 3.定义事件4.定义一个通事件发生后,通知其他对象的方法首先来理清一下我们的思路: 1.在下拉框中选中一个值,并且在输入框中也输入相应的值. 2.我们在页面点击"提交"按钮,按钮