更多精彩内容,请见:http://www.16boke.com
by zxy,Java/C++编程交流群:168424095
控件要升级,才发现半年没有看,生疏了,特写此文章留念。
1.生成自己的GUID
方法一:工具->创建GUID->GUID Format选中3.static const struct GUID={...} ->点击Copy按钮
//// {5E600E03-0E88-4c51-9A81-E3DB5A7918AB}
//static const GUID <<name>> =
//{ 0x5e600e03, 0xe88, 0x4c51, { 0x9a, 0x81, 0xe3, 0xdb, 0x5a, 0x79, 0x18, 0xab } };
生成后需要修改三个位置:
(1)demo.idl
// CdemoCtrl 的类信息
//此处helpstring("XXX")是C:\WINDOWS\Downloaded Program Files 中已安装文件的名字
[uuid(5E600E03-0E88-4c51-9A81-E3DB5A7918AB),
helpstring("DemoCtrl"), control]
coclass demo
{
[default] dispinterface _Ddemo;
[default, source] dispinterface _DdemoEvents;
};
(2)demoCtrl.cpp
// 初始化类工厂和 guid
IMPLEMENT_OLECREATE_EX(CdemoCtrl, "test.edit2.0",
0x5e600e03, 0xe88, 0x4c51, 0x9a, 0x81, 0xe3, 0xdb, 0x5a, 0x79, 0x18, 0xab)
(3)demo.cpp
const GUID CDECL CLSID_SafeItem =
{ 0x5e600e03, 0xe88, 0x4c51, { 0x9a, 0x81, 0xe3, 0xdb, 0x5a, 0x79, 0x18, 0xab }};
方法二:打开VS命令提示窗口:输入GUIDGEN,就会打开创建GUID窗口。
2.ActiveX在远程IE页面上执行,需要实现安全接口。
在MFC写的ActiveX中,直接修改注册表。
包含头文件
#include "comcat.h"
#include "Objsafe.h"
//创建组件种类
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 - 将项添加到系统注册表
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(BASED_CODE _tlid , CATID_SafeForInitializing);
if (FAILED(hr)) return hr;
// 标记控件脚本安全
// 创建脚本安全组件种类
hr = CreateComponentCategory(CATID_SafeForScripting, L" Controls safely scriptable! " );
if (FAILED(hr)) return hr;
// 注册脚本安全组件种类
hr = RegisterCLSIDInCategory(BASED_CODE _tlid , 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(BASED_CODE _tlid , CATID_SafeForInitializing);
if (FAILED(hr)) return hr;
// 删除控件脚本安全入口
hr = UnRegisterCLSIDInCategory(BASED_CODE _tlid , CATID_SafeForScripting);
if (FAILED(hr)) return hr;
return NOERROR;
}
3.打包成CAB
(1)准备inf文件,将下面文件存入XX.inf中,例如:test.inf
; Sample INF file for test.ocx
[version]
; version signature (same for both NT and Win95) do not remove
signature="$CHICAGO$"
AdvancedINF=2.0
; Add.Code 节列出所有将要被安装的文件,包括可选文件
[Add.Code]
test.ocx=test.ocx
; needed DLL
;每一个文件自成一节(文件节),并进行单独描述安装属性。
[test.ocx]
file-win32-x86=thiscab
clsid={5E600E03-0E88-4c51-9A81-E3DB5A7918AB}
FileVersion=1,0,0,1
DestDir=11
RegisterServer=yes
; end of INF file
"thiscab" 是一个关键字,意指包含该INF的CAB文件。也可以从网上下载所需要的DLL文件,只要指定一个HTTP 网址即可,如:
file-win32-x86=http://www.mysite.com/mydir/XXX.DLL
关键字"file-win32-x86"指定平台是x86。
"clsid" 指的是要安装控件的CLSID。
文件版本号可见属性。
"DestDir"指的是装载目录或者文件的地址: 11 指定为系统目录 WINDOWS/ /SYSTEM32;
"RegisterServer"可以取两个值yes和no,如果为yes则说明ie要注册该dll,如果是no就不必了;
(2)采用Windows系统目录自带的CAB制作工具IExpress(\WINDOWS\system32\目录下)
开始->运行,打开中输入iexpress.exe命令,出现 Iexpress Wizard(向导),然后依次按“下一步”进入各步骤;
1)选择“Create new Self Extraction Directive file”(建立新的自解压文件),点击下一步。
2)选择“Create compressed files only(ActiveX Installs)”(仅压缩文件),点击下一步。
3)点击Add,选择自己的文件,这里我是:test.inf,test.ocx添加进去,点击下一步。
4)点击Browse,输入.CAB文件的存放地址(包含所取文件名),这里取test.CAB,并且要选中 “Store files using Long File Name inside Package”。点击下一步。
5)选择“Don’t save”(不保存),一直点击下一步,直到完成。
4.网页调用
<html>
<body>
<object id="Object" width="200" height="20" classid="CLSID:5E600E03-0E88-4c51-9A81-E3DB5A7918AB"
codebase="test.cab#version=1,0,0,1">
</object>
</body>
</HTML>
5.红色叉叉 绿色叉叉
一是IE安全级别设置得不对,导致OCX无法下载;二是OCX打包不正确;三是OCX代码有问题。红叉叉说明客户端没有注册成功。
6.修改浏览器
浏览器菜单工具->Internet选项->安全->自定义级别->
由于网页可以包含可能会危害用户计算机的操作内容,浏览器允许用户为安全级别选择选项。 基于这种浏览器实现安全级别,控制是否不能下载,也无法显示证书或警告消息允许用户在运行时选择下载该控件。 Activex 控件行为在高,中等和低安全级别下的在 Internet Explorer 下面列出。
高安全模式
未签名的控件不会下载。
符号控件将显示证书,如果不受信任 (用户可以选择从现在开始始终信任来自此证书所有者的代码)。
为安全标记的控件将具有不可变数据和/或 scriptable。
中等安全模式
无符号控件在下载之前将显示警告。
符号控件将显示证书,如果不受信任的。
为安全未标记的控件将显示警告。
低安全模式
控件下载,而无需警告。
脚本和持久性发生,而无需警告。
7.手动删除控件:
(1)删除C:\WINDOWS\Downloaded Program Files下对应的文件
(2)删除C:\WINDOWS\system32下对应文件
备注:
报错:File:f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\ctlcore.cpp Line:429,说明控件没有注册上,本人是以下代码中断
CdemoCtrl::CdemoCtrl()
{
InitializeIIDs(&IID_Ddemo, &IID_DdemoEvents);
// TODO: 在此初始化控件的实例数据。
}
更多精彩内容,请见:http://www.16boke.com