我们采用了ActiveX的方式开发了一个嵌入到页面的小程序,可以实现对多文件的上传。因为还不能支持断点续传所以只支持小文件的传输,但是能一次传输多个小文件对于邮件方面的应用也是很方便的。而且有进度条显示这也给了用户较好的提示。同时我们支持拖入功能,用户可以直接将文件拖入到控件中,即完成对上传文件的选取。
下面对开发中遇到的一些问题进行说明,全文基本为原创,其中参考了很多他人的经验和资料,参考处我会注明原出处。
第一个问题如何标记控件为安全
控件发布第一步如何将控件标记为安全的。如果不将控件标记为安全,浏览器将会web页面与控件交互时提示如下信息:
MSDN上对这的解释是:默认,MFC ActiveX控件不被标记为可安全编写脚本和可安全初始化。当IE运行安全级别设置为中等或高时,都回提示控件不安全。
消除提示有两种办法,The first method uses the Component Categories Manager to create the appropriate entries in the system registry.即修改控件的DllRegisterServer函数来,在注册表中标记控件为安全的。The second method implements an interface named
IObjectSafety on your control.第二种方法可以详见
http://dcs.isa.ru/www/vladimirv/inetsdk/inet0002.htm。
这里就第一种方法进行说明,在MSDN上也有第一种方法的详细说明。网址:
http://support.microsoft.com/kb/161873/zh-cn
但是该方法有一些不足,这里结合Phinecos(洞庭散人)的blog
(http://www.cnblogs.com/phinecos/archive/2008/08/07/1263270.html)进行说明。
1.添加辅助函数
控件的基本结构中含有xxApp,xxCtrl,xxPropPage三个类。找到xxApp的头文件,添加三个辅助函数。
// Helper function to create a component category and associated
// description
HRESULT CreateComponentCategory(CATID catid, WCHAR* catDescription);
// Helper function to register a CLSID as belonging to a component
// category
HRESULT RegisterCLSIDInCategory(REFCLSID clsid, CATID catid);
// Helper function to unregister a CLSID as belonging to a component
// category
HRESULT UnRegisterCLSIDInCategory(REFCLSID clsid, CATID catid);
找到xxApp的实现文件,添加三个辅助函数的实现。
// Helper function to create a component category and associated
// description
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;
}
// Helper function to register a CLSID as belonging to a component
// category
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;
}
2.定义GUID
需要定义两个GUID用来注册控件安全性。
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}};
在控件自动注册完成后,可以在注册表的如下地方看到上面的两个GUID。
HKEY_CLASSES_ROOT/CLSID/{"your controls GUID"}/Implemented
Categories/{7DD95801-9882-11CF-9FA9-00AA006C42C4}
HKEY_CLASSES_ROOT/CLSID/{"your controls GUID"}/Implemented
Categories/{7DD95802-9882-11CF-9FA9-00AA006C42C4}
同时需要定义要注册为安全的CLSID。
控件有四个UUID,这里我们需要将xxCtrl的UUID注册成为安全的CLSID,因为我们控件的主体功能是在这个类中实现的。
const GUID CDECL BASED_CODE _tlid =
{ 0x7DE84B6C, 0x9969, 0x4DE0, { 0xBE, 0x25, 0xC6, 0xC0, 0x63, 0x20, 0xA3, 0x70 } };
const WORD _wVerMajor = 1;
const WORD _wVerMinor = 0;
const CATID CLSID_SafeItem =
{0x4e586c5a, 0xfd41, 0x4e4c, {0xb6, 0x6d, 0x63, 0xf1, 0x10, 0xc8, 0xc4, 0xb9}};
这里的CLSID_SafeItem就是xxCtrl的UUID。
3.修改注册代码
// DllRegisterServer - 将项添加到系统注册表
STDAPI DllRegisterServer(void)
{
/*这里是原来的注册代码
OLD
AFX_MANAGE_STATE(_afxModuleAddrThis);
if (!AfxOleRegisterTypeLib(AfxGetInstanceHandle(), _tlid))
return ResultFromScode(SELFREG_E_TYPELIB);
if (!COleObjectFactoryEx::UpdateRegistryAll(TRUE))
return ResultFromScode(SELFREG_E_CLASS);
return NOERROR;*/
//NEW下面是新的注册代码
AFX_MANAGE_STATE(_afxModuleAddrThis);
if (!AfxOleRegisterTypeLib(AfxGetInstanceHandle(), _tlid))
return ResultFromScode(SELFREG_E_TYPELIB);
if (!COleObjectFactoryEx::UpdateRegistryAll(TRUE))
return ResultFromScode(SELFREG_E_CLASS);
if (FAILED( CreateComponentCategory(
CATID_SafeForScripting,
L"Controls that are safely scriptable") ))
return ResultFromScode(SELFREG_E_CLASS);
if (FAILED( CreateComponentCategory(
CATID_SafeForInitializing,
L"Controls safely initializable from persistent data") ))
return ResultFromScode(SELFREG_E_CLASS);
if (FAILED( RegisterCLSIDInCategory(
CLSID_SafeItem, CATID_SafeForScripting) ))
return ResultFromScode(SELFREG_E_CLASS);
if (FAILED( RegisterCLSIDInCategory(
CLSID_SafeItem, CATID_SafeForInitializing) ))
return ResultFromScode(SELFREG_E_CLASS);
return NOERROR;
}
// DllUnregisterServer - 将项从系统注册表中移除
STDAPI DllUnregisterServer(void)
{
/*
OLD这里是原来的代码
AFX_MANAGE_STATE(_afxModuleAddrThis);
if (!AfxOleUnregisterTypeLib(_tlid, _wVerMajor, _wVerMinor))
return ResultFromScode(SELFREG_E_TYPELIB);
if (!COleObjectFactoryEx::UpdateRegistryAll(FALSE))
return ResultFromScode(SELFREG_E_CLASS);
return NOERROR;*/
//NEW下面是新的代码
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;
}
到此完成了控件的安全标记。
分享到:
相关推荐
Active Audio Record ActiveX控件 可以直接录制声音为MP3、WAV、wma 、ogg、au、aiff 和vox格式的音频文件。您可以通过设置内码参量完全控制音像文件的质量。 <br> Active Audio Record ActiveX控件 支持...
MFC ActiveX控件未标记为“安全脚本”和“安全初始化”。当控件在Internet Explorer中运行且安全级别设置为中或高时,这一点就变得很明显。在这些模式中的任何一种模式下,都可能会显示警告,表明控件的数据不安全,...
开发安全标记的MFC_ActiveX_控件及在IIS网页中使用和发布
NULL 博文链接:https://woshizn.iteye.com/blog/569117
HTML Snapshot ActiveX控件 可以把当前整体网页存取为JPG 、BMP 、PNG 、TIFF 和GIF 图象文件。HTML文件可以通过Snapshot ActiveX 容易地转换成图像, 也可以控制JPEG 的压缩质量或改变TIFF 图像压缩方法。 ...
DynaPlot ActiveX控件 是一个实时图表控件,用于技术和科学应用程序。内置的autoscale, pan, scroll, stacked zoom, 和 cursors等工具能让用户快速简便的检查数据。特点包括直线,点线和散点图(scatter plots...
这使您实现所需的功能在这种情况下意味着将标记为可安全编写脚本和初始化该控件。 若要将 IObjectSafetyImpl 需要将其添加到您的控件派生的类的列表。 是例如多边形教程中您看到以下: class ATL_NO_VTABLE ...
通过网页修改activex安全设置,添加信任站点,禁用弹出窗口阻止程序 ...1201 对没有标记为安全的 ActiveX 控件进行初始化和脚本运行 1405 对标记为可安全执行脚本的 ActiveX 控件执行脚本 2201 ActiveX 控件自动提示 **
SIASlider Control(Simulated Instrument ActiveX Slider)即线性滑动条(棒)控件,本控件是可高度定制的。它提供了可修改的旋钮(Knob)和标记(Tic)风格、题(caption)、边框(border)和背景(background)的...
10.2.2 标记控件为初始化/脚本安全 10.2.3 持续属性 10.3 在ActiveX控件中访问DOM对象 10.3.1 什么是DOM(文档对象模型) 10.3.2 在ActiveX控件中访问DOM——例程DOMSamp 10.3.3 测试DOMCtrl控件 10.4 活动服务器...
11.6 Activex控件方法开发 464 11.6.1 添加常用方法 465 11.6.2 添加自定义方法 465 11.6.3 从方法返回错误代码 466 11.7 完整Activex控件范例 467 11.7.1 创建工程 467 11.7.2 clock控件的实现 469 11.7.3 添加常用...
第11章 VisualC++2010MFCActiveX控件 第12章 VisualC++2010MFC文件与注册表操作 第13章 VisualC++2010MFC数据库开发 第14章 VisualC++2010MFC多线程程序设计 第15章 VisualC++2010MFC网络程序设计 第16...
1 必须将ie的internet选项的安全设置中对于没有标记为安全的ActiveX控件进行 设置成提示或者启用 否则会报错 导致不可用 2 如果在vs net编辑环境下编辑该页面 它经常自动的给object添加多余的参数 有了这些东西 ...
第11章 VisualC++2010MFCActiveX控件 第12章 VisualC++2010MFC文件与注册表操作 第13章 VisualC++2010MFC数据库开发 第14章 VisualC++2010MFC多线程程序设计 第15章 VisualC++2010MFC网络程序设计 第16...
bemidioc.zip 轻松播放midi(225KB) 44,record32.zip 录音控件(29KB) 45,dcsmixer.zip activex混音控制(41KB) 46,midiamp3.zip 一个几乎可以播放所有声音格式的控件!(273KB) 47,Mp3Ocx.zip...
SIAKnob Control(Simulated Instrument ActiveX Knob Gauge)即旋钮,这个通用仪表控件是一个可高度定制的仪表或测量控件。 它提供了可修改其量程(scales)刻度(tics)、旋钮(knob)、环行区(annulars)、标题...