如何在.Net下通过CoGetClassObjectFromURL安装ActiveX控件?
如何在.Net下通过CoGetClassObjectFromURL安装ActiveX控件?
.Net下通过CoGetClassObjectFromURL 安装 ActiveX控件
1.CoGetClassObjectFromURL在MSDN上的说明
CoGetClassObjectFromURL Function
Returns a factory object for a given CLSID.
Syntax
HRESULTCoGetClassObjectFromURL(
REFCLSIDrclsid,
REFCLSIDrclsid,
LPCWSTRszCodeURL,
DWORDdwFileVersionMS,
DWORDdwFileVersionLS,
LPCWSTRszContentType,
LPBINDCTXpBindCtx,
DWORDdwClsContext,
LPVOIDpvReserved,
REFIIDriid,
VOID**ppv
);
Parameters
rclsid
[in]CLSID of the Microsoft ActiveX object to be installed. If the value is CLSID_NULL, szContentType is used to determine the CLSID.
需要安装的ClassID,如果为空,则根据安装包里Inf文件信息进行安装。不过通常这样安装的时候会报错,但是基本上ActiveX都能安装上去。
szCodeURL
[in]Address of a string value that contains the full URL of the code for the ActiveX object.
AcitveX的安装路径,路径除了URL格式外,本地文件路径格式也支持。
dwFileVersionMS
[in]Unsigned long integer value that contains the major version number for the object to be installed. If this value and the value for dwFileVersionLS are both 0xFFFFFFFF, the latest version of the code should always be installed. This means that Internet Component Download will always attempt to download new code.
在安装AcitveX的时候,需要通过传入的的版本号与以安装文件的版本号进行比对,如果传入的版本号大于文件的版本号,则需要重新下载ActiveX控件。
通常文件版本由4位数字组成 a,b,c,d。例:1,0,0,3。这里的主版本由版本号的前两位a, b数字组成,并使用MAKELONG(b,a)函数进行合并。对于下面的副版本,则通过MAKELONG(d,c)进行合并。
如果想每次安装都进行更新就将参数设为0xFFFFFFFF,实际上就是按照最大的版本号进行更新。
dwFileVersionLS
[in]Unsigned long integer value that contains the minor version number for the object to be installed. If this value and the value for dwFileVersionMS are both 0xFFFFFFFF, the latest version of the code should always be installed. This means that Internet Component Download will always attempt to download new code.
szContentType
[in]Pointer to a string value that contains the Multipurpose Internet Mail Extensions (MIME) type to be understood by the installed ActiveX object. If rclsid is CLSID_NULL, this string is used to determine the CLSID of the object to be installed. Note that this parameter is useful only when trying to download a viewer for a particular media type, when the MIME type of media is known but the CLSID is not.
pBindCtx
[in]Pointer to the bind context to use for downloading/installing component code. An implementation of IBindStatusCallback must be registered on this bind context before calling this function.
一个绑定有IbindStatuseCallback接口的对象,通常是用于显示ActiveX的安装进度。这个对象创建比较简单。按照提供的示例代码一步步完成即可。
dwClsContext
[in]Unsigned long integer value that specifies the execution context for the class object. This can be one of the values taken from the CLSCTX enumeration.
pvReserved
[in]Reserved. Must be set to NULL.
riid
[in]Reference identifier of the interface to obtain on the factory object. Usually this interface is IClassFactory.
ppv
[out]Address of an interface pointer for synchronous calls, or NULL otherwise.
Return Value
Returns one of the following values:
S_OK
|
The operation completed successfully and the ppv parameter contains the requested interface pointer.
ActiveX已经安装过
|
E_NOINTERFACE
|
The requested interface pointer is not available.
|
MK_S_ASYNCHRONOUS
|
Component code will be downloaded and installed asynchronously. The client will receive notifications through the IBindStatusCallback interface registered on pBindCtx.
ActiveX没有安装过,正在进行异步的安装,安装过程通过IBindStatusCallback的回调过程通知用户
|
Remarks
If no CLSID is specified (CLSID_NULL), this function chooses the appropriate CLSID for interpreting the MIME type specified in szContentType. If the desired object is installed on the system, it is instantiated. Otherwise, the necessary code is downloaded and installed from the location specified in szCodeURL.
CoGetClassObjectFromURL was designed to be used by MSHTML to retrieve the code for objects on a Web page. When the requested object is available for use on the user's computer, this function typically returns synchronously with a valid object reference. For objects that aren't available on the user's computer and need to be downloaded from szCodeURL, CoGetClassObjectFromURL will return asynchronously with MK_S_ASNYNCHRONOUS and notify the calling application through the IBindStatusCallback interface that was registered on pBindCtx.
FunctionInformation
Stock Implementation
|
urlmon.dll
|
Custom Implementation
|
No
|
Header
|
Urlmon.h
|
Import library
|
Urlmon.lib
|
Minimum availability
|
Internet Explorer 4.0
|
Minimum operating systems
|
Windows NT4.0, Windows95
|
2.CoGetClassObjectFromURL的.Net 封装
说明:安装ActiveX代码是用MSDN上的例子程序改编而成的,其目是为了给.net程序安装AcitveX控件。例子程序可以以“CoGetClassObjectFromURL”为关键字进行搜索MSDN找到。
2.1 .Net类
regActiveX是一个封装了安装AcitveX控件的.net类,用托管C++编写(实际上是因为在调用windows资源的时候托管C++比C#方便)其主要功能是调用CoGetClassObjectFromURL函数去安装AcitveX控件。在类里还增加两个时间,用于通知用户当前的安装进度已经安装结果。
CDownload 实现了IBindStatusCallback接口,在安装ActiveX的过程中实现安装函数异步安装时的回调功能。该函数为C++代码。
StdAfx.h
#pragmaonce
#defineVC_EXTRALEAN//Excluderarely-usedstufffromWindowsheaders
#include<afxwin.h>//MFCcoreandstandardcomponents
#include<afxext.h>//MFCextensions
regActiveX.h
#pragmaonce
#include"stdafx.h"
#include"string"
usingnamespaceSystem;
namespaceRegActiveX
{
public__delegatevoidOnProcessHandler(intProgress,intProgressMax,intStatusCode,System::String*StatusText);
public__delegatevoidOnStopBindingHandler(inthrResult,System::String*Error);
__gcpublicclassregActiveX:publicSystem::Object
{
private:
regActiveX()
{
hwnd=NULL;
}
protected:
//注册ActiveX控件,该函数为执行函数
voidRegisterActiveX(wchar_t*classid,wchar_t*url,intv1,intv2,intv3,intv4);
public:
regActiveX(System::IntPtrhWnd)
{
hwnd=hWnd;
}
System::IntPtrhwnd;
voidRegisterActiveX(System::String*classid,System::String*url);
voidRegisterActiveX(System::String*classid,System::String*url,intv1,intv2,intv3,intv4);
__eventOnProcessHandler*OnProcess;
__eventOnStopBindingHandler*OnStopBinding;
voidonProcess(intProgress,intProgressMax,intStatusCode,System::String*StatusText)
{
if(OnProcess)
OnProcess(Progress,ProgressMax,StatusCode,StatusText);
}
voidonStopBinding(inthrResult,System::String*Error)
{
if(OnStopBinding)
OnStopBinding(hrResult,Error);
}
};
}
regActiveX.cpp
#include"stdafx.h"
#include"RegActiveX.h"
#include"DownLoad.h"
#include"urlmon.h"
#pragmacomment(lib,"Urlmon.lib")
usingnamespaceRegActiveX;
voidregActiveX::RegisterActiveX(System::String*classid,System::String*url,intv1,intv2,intv3,intv4)
{
usingnamespaceSystem::Runtime::InteropServices;
wchar_t*id=(wchar_t*)(void*)(Marshal::StringToHGlobalUni(classid));
wchar_t*u=(wchar_t*)(void*)(Marshal::StringToHGlobalUni(url));
RegisterActiveX(id,u,v1,v2,v3,v4);
}
voidregActiveX::RegisterActiveX(System::String*classid,System::String*url)
{
usingnamespaceSystem::Runtime::InteropServices;
wchar_t*id=(wchar_t*)(void*)(Marshal::StringToHGlobalUni(classid));
wchar_t*u=(wchar_t*)(void*)(Marshal::StringToHGlobalUni(url));
RegisterActiveX(id,u,0xFFFF,0xFFFF,0xFFFF,0xFFFF);
}
voidregActiveX::RegisterActiveX(wchar_t*classid,wchar_t*url,intv1,intv2,intv3,intv4)
{
LPCLASSFACTORYpClassFactory;
HRESULThr;
CLSIDm_clsid;
LPBINDCTXm_pBindContext=NULL;
LPBINDSTATUSCALLBACKm_pBindStatusCallback=NULL;
hr=OleInitialize(NULL);
USES_CONVERSION;
CLSIDFromString(classid,&m_clsid);
hr=CreateBindCtx(0,&m_pBindContext);
BIND_OPTSbindopts;
m_pBindContext->GetBindOptions(&bindopts);
bindopts.grfFlags|=BIND_MAYBOTHERUSER;
m_pBindContext->SetBindOptions(&bindopts);
//绑定回调函数
CDownload*download=newCDownload(this);
download->ExternalQueryInterface(&IID_IBindStatusCallback,(void**)&m_pBindStatusCallback);
hr=RegisterBindStatusCallback(m_pBindContext,m_pBindStatusCallback,0,0);
//调用安装AcitveX的API函数
hr=CoGetClassObjectFromURL(m_clsid,url,
MAKELONG(v2,v1),MAKELONG(v4,v3),
NULL,m_pBindContext,
CLSCTX_INPROC_HANDLER|CLSCTX_INPROC_SERVER,
0,IID_IClassFactory,(void**)&pClassFactory);
//如果ActiveX已经安装过,直接触发安装结束的事件
if(hr==0)
if(OnStopBinding)
OnStopBinding(0,System::String::Empty);
}
intmain()
{
//不要问我为什么有这个东西,我也不清楚,反正没这个东西编译器不让我编译过去
}
CDownLoad.h
#pragmaonce
#include"RegActiveX.h"
#defineVC_EXTRALEAN//Excluderarely-usedstufffromWindowsheaders
#include<afxwin.h>//MFCcoreandstandardcomponents
#include<afxext.h>//MFCextensions
//#include<afxdisp.h>//MFCOLEautomationclasses
//#ifndef_AFX_NO_AFXCMN_SUPPORT
//#include<afxcmn.h>//MFCsupportforWindowsCommonControls
//#endif//_AFX_NO_AFXCMN_SUPPORT
#defineWM_ONSTOPBINDINGWM_USER+1001
/////////////////////////////////////////////////////////////////////////////
//CDownloadcommandtarget
classCDownload:publicCCmdTarget
{
DECLARE_DYNCREATE(CDownload)
CDownload();//protectedconstructorusedbydynamiccreation
//在安装过程中,需要触发一些安装事件,因此需要有一个regActiveX对象
gcroot<RegActiveX::regActiveX*>active;
//Attributes
public:
CFormView*m_pView;
CDownload(gcroot<RegActiveX::regActiveX*>act)
{
active=act;
hwnd=(HWND)(void*)act->hwnd;
}
//Operations
public:
virtual~CDownload();//hadtomakethedestructorpublic
//显示安全提示时需要的句柄,这个不是必须存在的
//到时候可以通过active来获取,这里独立出来只是为了方便而已。
HWNDhwnd;
//Overrides
//ClassWizardgeneratedvirtualfunctionoverrides
//{{AFX_VIRTUAL(CDownload)
//}}AFX_VIRTUAL
//Implementation
protected:
//virtual~CDownload();
//Generatedmessagemapfunctions
//{{AFX_MSG(CDownload)
//NOTE-theClassWizardwilladdandremovememberfunctionshere.
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
public:
DECLARE_INTERFACE_MAP()
//IBindStatusCallback
BEGIN_INTERFACE_PART(BindStatusCallback,IBindStatusCallback)
STDMETHOD(OnStartBinding)(DWORDgrfBSCOption,IBinding*pbinding);
STDMETHOD(GetPriority)(LONG*pnPriority);
STDMETHOD(OnLowResource)(DWORDdwReserved);
STDMETHOD(OnProgress)(ULONGulProgress,ULONGulProgressMax,ULONGulStatusCode,LPCWSTRszStatusText);
STDMETHOD(OnStopBinding)(HRESULThrResult,LPCWSTRszError);
STDMETHOD(GetBindInfo)(DWORD*pgrfBINDF,BINDINFO*pbindinfo);
STDMETHOD(OnDataAvailable)(DWORDgrfBSCF,DWORDdwSize,FORMATETC*pfmtetc,STGMEDIUM*pstgmed);
STDMETHOD(OnObjectAvailable)(REFIIDriid,IUnknown*punk);
END_INTERFACE_PART(BindStatusCallback)
//IWindowForBindingUI
BEGIN_INTERFACE_PART(WindowForBindingUI,IWindowForBindingUI)
STDMETHOD(GetWindow)(REFGUIDrguidReason,HWND*phwnd);
END_INTERFACE_PART(WindowForBindingUI)
};
CDownLoad.cpp
#include"StdAfx.h"
#include".download.h"
#using<mscorlib.dll>
IMPLEMENT_DYNCREATE(CDownload,CCmdTarget)
CDownload::CDownload()
{
hwnd=NULL;
}
CDownload::~CDownload()
{
}
BEGIN_MESSAGE_MAP(CDownload,CCmdTarget)
//{{AFX_MSG_MAP(CDownload)
//NOTE-theClassWizardwilladdandremovemappingmacroshere.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
BEGIN_INTERFACE_MAP(CDownload,CCmdTarget)
INTERFACE_PART(CDownload,IID_IBindStatusCallback,BindStatusCallback)
INTERFACE_PART(CDownload,IID_IWindowForBindingUI,WindowForBindingUI)
END_INTERFACE_MAP()
/////////////////////////////////////////////////////////////////////////////
//CDownloadmessagehandlers
STDMETHODIMP_(ULONG)CDownload::XBindStatusCallback::AddRef()
{
METHOD_PROLOGUE(CDownload,BindStatusCallback)
returnpThis->ExternalAddRef();
}
STDMETHODIMP_(ULONG)CDownload::XBindStatusCallback::Release()
{
METHOD_PROLOGUE(CDownload,BindStatusCallback)
returnpThis->ExternalRelease();
}
STDMETHODIMPCDownload::XBindStatusCallback::QueryInterface(REFIIDiid,void**ppvObj)
{
METHOD_PROLOGUE(CDownload,BindStatusCallback)
return(HRESULT)pThis->ExternalQueryInterface(&iid,ppvObj);
}
STDMETHODIMPCDownload::XBindStatusCallback::OnStartBinding(DWORDgrfBSCOption,IBinding*pbinding)
{
METHOD_PROLOGUE(CDownload,BindStatusCallback)
returnS_OK;
}
STDMETHODIMPCDownload::XBindStatusCallback::GetPriority(LONG*pnPriority)
{
METHOD_PROLOGUE(CDownload,BindStatusCallback)
returnE_NOTIMPL;
}
STDMETHODIMPCDownload::XBindStatusCallback::OnLowResource(DWORDdwReserved)
{
METHOD_PROLOGUE(CDownload,BindStatusCallback)
returnE_NOTIMPL;
}
STDMETHODIMPCDownload::XBindStatusCallback::OnProgress(ULONGulProgress,ULONGulProgressMax,ULONGulStatusCode,LPCWSTRszStatusText)
{
METHOD_PROLOGUE(CDownload,BindStatusCallback)
//触发OnProcess事件,通知用户当前Activex安装进度
if(pThis->active)
{
pThis->active->onProcess(ulProgress,
ulProgressMax,
ulStatusCode,
szStatusText?newSystem::String(szStatusText):System::String::Empty//状态字符串,在给用户的时候,把NULL转为空串);
#pragmaonce
#defineVC_EXTRALEAN//Excluderarely-usedstufffromWindowsheaders
#include<afxwin.h>//MFCcoreandstandardcomponents
#include<afxext.h>//MFCextensions
regActiveX.h
#pragmaonce
#include"stdafx.h"
#include"string"
usingnamespaceSystem;
namespaceRegActiveX
{
public__delegatevoidOnProcessHandler(intProgress,intProgressMax,intStatusCode,System::String*StatusText);
public__delegatevoidOnStopBindingHandler(inthrResult,System::String*Error);
__gcpublicclassregActiveX:publicSystem::Object
{
private:
regActiveX()
{
hwnd=NULL;
}
protected:
//注册ActiveX控件,该函数为执行函数
voidRegisterActiveX(wchar_t*classid,wchar_t*url,intv1,intv2,intv3,intv4);
public:
regActiveX(System::IntPtrhWnd)
{
hwnd=hWnd;
}
System::IntPtrhwnd;
voidRegisterActiveX(System::String*classid,System::String*url);
voidRegisterActiveX(System::String*classid,System::String*url,intv1,intv2,intv3,intv4);
__eventOnProcessHandler*OnProcess;
__eventOnStopBindingHandler*OnStopBinding;
voidonProcess(intProgress,intProgressMax,intStatusCode,System::String*StatusText)
{
if(OnProcess)
OnProcess(Progress,ProgressMax,StatusCode,StatusText);
}
voidonStopBinding(inthrResult,System::String*Error)
{
if(OnStopBinding)
OnStopBinding(hrResult,Error);
}
};
}
regActiveX.cpp
#include"stdafx.h"
#include"RegActiveX.h"
#include"DownLoad.h"
#include"urlmon.h"
#pragmacomment(lib,"Urlmon.lib")
usingnamespaceRegActiveX;
voidregActiveX::RegisterActiveX(System::String*classid,System::String*url,intv1,intv2,intv3,intv4)
{
usingnamespaceSystem::Runtime::InteropServices;
wchar_t*id=(wchar_t*)(void*)(Marshal::StringToHGlobalUni(classid));
wchar_t*u=(wchar_t*)(void*)(Marshal::StringToHGlobalUni(url));
RegisterActiveX(id,u,v1,v2,v3,v4);
}
voidregActiveX::RegisterActiveX(System::String*classid,System::String*url)
{
usingnamespaceSystem::Runtime::InteropServices;
wchar_t*id=(wchar_t*)(void*)(Marshal::StringToHGlobalUni(classid));
wchar_t*u=(wchar_t*)(void*)(Marshal::StringToHGlobalUni(url));
RegisterActiveX(id,u,0xFFFF,0xFFFF,0xFFFF,0xFFFF);
}
voidregActiveX::RegisterActiveX(wchar_t*classid,wchar_t*url,intv1,intv2,intv3,intv4)
{
LPCLASSFACTORYpClassFactory;
HRESULThr;
CLSIDm_clsid;
LPBINDCTXm_pBindContext=NULL;
LPBINDSTATUSCALLBACKm_pBindStatusCallback=NULL;
hr=OleInitialize(NULL);
USES_CONVERSION;
CLSIDFromString(classid,&m_clsid);
hr=CreateBindCtx(0,&m_pBindContext);
BIND_OPTSbindopts;
m_pBindContext->GetBindOptions(&bindopts);
bindopts.grfFlags|=BIND_MAYBOTHERUSER;
m_pBindContext->SetBindOptions(&bindopts);
//绑定回调函数
CDownload*download=newCDownload(this);
download->ExternalQueryInterface(&IID_IBindStatusCallback,(void**)&m_pBindStatusCallback);
hr=RegisterBindStatusCallback(m_pBindContext,m_pBindStatusCallback,0,0);
//调用安装AcitveX的API函数
hr=CoGetClassObjectFromURL(m_clsid,url,
MAKELONG(v2,v1),MAKELONG(v4,v3),
NULL,m_pBindContext,
CLSCTX_INPROC_HANDLER|CLSCTX_INPROC_SERVER,
0,IID_IClassFactory,(void**)&pClassFactory);
//如果ActiveX已经安装过,直接触发安装结束的事件
if(hr==0)
if(OnStopBinding)
OnStopBinding(0,System::String::Empty);
}
intmain()
{
//不要问我为什么有这个东西,我也不清楚,反正没这个东西编译器不让我编译过去
}
CDownLoad.h
#pragmaonce
#include"RegActiveX.h"
#defineVC_EXTRALEAN//Excluderarely-usedstufffromWindowsheaders
#include<afxwin.h>//MFCcoreandstandardcomponents
#include<afxext.h>//MFCextensions
//#include<afxdisp.h>//MFCOLEautomationclasses
//#ifndef_AFX_NO_AFXCMN_SUPPORT
//#include<afxcmn.h>//MFCsupportforWindowsCommonControls
//#endif//_AFX_NO_AFXCMN_SUPPORT
#defineWM_ONSTOPBINDINGWM_USER+1001
/////////////////////////////////////////////////////////////////////////////
//CDownloadcommandtarget
classCDownload:publicCCmdTarget
{
DECLARE_DYNCREATE(CDownload)
CDownload();//protectedconstructorusedbydynamiccreation
//在安装过程中,需要触发一些安装事件,因此需要有一个regActiveX对象
gcroot<RegActiveX::regActiveX*>active;
//Attributes
public:
CFormView*m_pView;
CDownload(gcroot<RegActiveX::regActiveX*>act)
{
active=act;
hwnd=(HWND)(void*)act->hwnd;
}
//Operations
public:
virtual~CDownload();//hadtomakethedestructorpublic
//显示安全提示时需要的句柄,这个不是必须存在的
//到时候可以通过active来获取,这里独立出来只是为了方便而已。
HWNDhwnd;
//Overrides
//ClassWizardgeneratedvirtualfunctionoverrides
//{{AFX_VIRTUAL(CDownload)
//}}AFX_VIRTUAL
//Implementation
protected:
//virtual~CDownload();
//Generatedmessagemapfunctions
//{{AFX_MSG(CDownload)
//NOTE-theClassWizardwilladdandremovememberfunctionshere.
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
public:
DECLARE_INTERFACE_MAP()
//IBindStatusCallback
BEGIN_INTERFACE_PART(BindStatusCallback,IBindStatusCallback)
STDMETHOD(OnStartBinding)(DWORDgrfBSCOption,IBinding*pbinding);
STDMETHOD(GetPriority)(LONG*pnPriority);
STDMETHOD(OnLowResource)(DWORDdwReserved);
STDMETHOD(OnProgress)(ULONGulProgress,ULONGulProgressMax,ULONGulStatusCode,LPCWSTRszStatusText);
STDMETHOD(OnStopBinding)(HRESULThrResult,LPCWSTRszError);
STDMETHOD(GetBindInfo)(DWORD*pgrfBINDF,BINDINFO*pbindinfo);
STDMETHOD(OnDataAvailable)(DWORDgrfBSCF,DWORDdwSize,FORMATETC*pfmtetc,STGMEDIUM*pstgmed);
STDMETHOD(OnObjectAvailable)(REFIIDriid,IUnknown*punk);
END_INTERFACE_PART(BindStatusCallback)
//IWindowForBindingUI
BEGIN_INTERFACE_PART(WindowForBindingUI,IWindowForBindingUI)
STDMETHOD(GetWindow)(REFGUIDrguidReason,HWND*phwnd);
END_INTERFACE_PART(WindowForBindingUI)
};
CDownLoad.cpp
#include"StdAfx.h"
#include".download.h"
#using<mscorlib.dll>
IMPLEMENT_DYNCREATE(CDownload,CCmdTarget)
CDownload::CDownload()
{
hwnd=NULL;
}
CDownload::~CDownload()
{
}
BEGIN_MESSAGE_MAP(CDownload,CCmdTarget)
//{{AFX_MSG_MAP(CDownload)
//NOTE-theClassWizardwilladdandremovemappingmacroshere.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
BEGIN_INTERFACE_MAP(CDownload,CCmdTarget)
INTERFACE_PART(CDownload,IID_IBindStatusCallback,BindStatusCallback)
INTERFACE_PART(CDownload,IID_IWindowForBindingUI,WindowForBindingUI)
END_INTERFACE_MAP()
/////////////////////////////////////////////////////////////////////////////
//CDownloadmessagehandlers
STDMETHODIMP_(ULONG)CDownload::XBindStatusCallback::AddRef()
{
METHOD_PROLOGUE(CDownload,BindStatusCallback)
returnpThis->ExternalAddRef();
}
STDMETHODIMP_(ULONG)CDownload::XBindStatusCallback::Release()
{
METHOD_PROLOGUE(CDownload,BindStatusCallback)
returnpThis->ExternalRelease();
}
STDMETHODIMPCDownload::XBindStatusCallback::QueryInterface(REFIIDiid,void**ppvObj)
{
METHOD_PROLOGUE(CDownload,BindStatusCallback)
return(HRESULT)pThis->ExternalQueryInterface(&iid,ppvObj);
}
STDMETHODIMPCDownload::XBindStatusCallback::OnStartBinding(DWORDgrfBSCOption,IBinding*pbinding)
{
METHOD_PROLOGUE(CDownload,BindStatusCallback)
returnS_OK;
}
STDMETHODIMPCDownload::XBindStatusCallback::GetPriority(LONG*pnPriority)
{
METHOD_PROLOGUE(CDownload,BindStatusCallback)
returnE_NOTIMPL;
}
STDMETHODIMPCDownload::XBindStatusCallback::OnLowResource(DWORDdwReserved)
{
METHOD_PROLOGUE(CDownload,BindStatusCallback)
returnE_NOTIMPL;
}
STDMETHODIMPCDownload::XBindStatusCallback::OnProgress(ULONGulProgress,ULONGulProgressMax,ULONGulStatusCode,LPCWSTRszStatusText)
{
METHOD_PROLOGUE(CDownload,BindStatusCallback)
//触发OnProcess事件,通知用户当前Activex安装进度
if(pThis->active)
{
pThis->active->onProcess(ulProgress,
ulProgressMax,
ulStatusCode,
szStatusText?newSystem::String(szStatusText):System::String::Empty//状态字符串,在给用户的时候,把NULL转为空串);