一步一步实现ActiveX嵌入网页

更多精彩内容,请见: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

你可能感兴趣的:(windows,浏览器,脚本,null,System)