VC写ActiveX客户端控件和服务器端控件(二十三)
本文讲述用VC来写ActiveX客户端控件和服务器端控件。
一. 首先来讲述用VC写ActiveX客户端控件
1. 创建一个ATL工程。
2. 添加对象,可以是Simple Object也可以是FullControl。不过,如果添加了ISupportsErrorInfo,在FullControl中是在.h文件中,而Simple Object是在.cpp文件中。
3. 客户端控件需要添加如下两个函数来实现屏蔽IE的交互对话,否则,你每次调用函数的时候,IE都会弹出一个窗口,告诉你进行不安全的交互是否继续。我们分为一下几个步骤来进行。所有的下面的步骤都是在.h文件中进行。
1> 首先在头文件的最下面添加一个变量的声明,如下:
private:
DWORDm_dwSafety;
2> 在构造函数中初始化上述变量,如下:
m_dwSafety = 0;
3> 在类继承的父类中,添加如下的一个类,只需要根据需要把CHTActXCtrl改成你的名称就可以了。
publicIObjectSafetyImpl<CHTActXCtrl, INTERFACESAFE_FOR_UNTRUSTED_CALLER>,
4> 在消息映射中,添加如下的一个消息函数:
BEGIN_COM_MAP(CHTActXCtrl)
//添加如下的一个消息映射
COM_INTERFACE_ENTRY(IObjectSafety)
//end
END_COM_MAP()
5> 在ISupportsErrorInfo下面,添加如下两个函数的实现就可以了。直接拷贝就可以用。
STDMETHOD(GetInterfaceSafetyOptions)(REFIIDriid, DWORD *pdwSupportedOptions,
DWORD *pdwEnabledOptions)
{
if(riid == IID_IDispatch)
{
*pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER;
*pdwEnabledOptions = m_dwSafety & INTERFACESAFE_FOR_UNTRUSTED_CALLER;
returnS_OK;
}
elseif((riid == IID_IPersistStreamInit)||(riid == IID_IPersistStorage))
{
*pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA;
*pdwEnabledOptions = m_dwSafety & INTERFACESAFE_FOR_UNTRUSTED_DATA;
returnS_OK;
}
else
{
*pdwSupportedOptions = 0;
*pdwEnabledOptions = 0;
returnE_FAIL;
}
}
STDMETHOD(SetInterfaceSafetyOptions)(REFIIDriid, DWORDdwOptionSetMask,
DWORDdwEnabledOptions)
{
m_dwSafety|=dwEnabledOptions & dwOptionSetMask;
if((riid == IID_IDispatch)&&(m_dwSafety & INTERFACESAFE_FOR_UNTRUSTED_CALLER))
{
returnS_OK;
}
elseif(((riid == IID_IPersistStreamInit)||(riid == IID_IPersistStorage))&&(m_dwSafety &INTERFACESAFE_FOR_UNTRUSTED_DATA))
{
returnE_FAIL;
}
else
{
returnE_FAIL;
}
}
剩下的,就是自己来添加方法和实现了。
二. 首先来讲述用VC写ActiveX客户端控件
1. 创建一个ATL工程。
2. 添加对象,可以是Simple Object也可以是FullControl。不过,如果添加了ISupportsErrorInfo,在FullControl中是在.h文件中,而Simple Object是在.cpp文件中。
3. 添加几个对象,OnEndPage和OnStartPage函数,我们按如下的步骤来完成。
1> 在头文件中添加如下几个对象:
private:
CComPtr<IRequest> m_piRequest; //Request Object
CComPtr<IResponse> m_piResponse; //Response Object
CComPtr<ISessionObject> m_piSession; //Session Object
CComPtr<IServer> m_piServer; //Server Object
CComPtr<IApplicationObject> m_piApplication; //Application Object
BOOLm_bOnStartPageCalled; //OnStartPage successful
注意,需要包含头文件:
#include <asptlb.h> // Active Server Pages Definitions
2> 在构造函数中初始化如下:
m_bOnStartPageCalled = FALSE;
3> 在cpp文件中添加OnStartPage和OnEndPage的实现如下:
STDMETHODIMPCHTSrvActXCtrl::OnStartPage (IUnknown* pUnk)
{
if(!pUnk)
returnE_POINTER;
CComPtr<IScriptingContext> spContext;
HRESULThr;
// Get the IScriptingContext Interface
hr = pUnk->QueryInterface(IID_IScriptingContext, (void **)&spContext);
if(FAILED(hr))
returnhr;
// Get Request Object Pointer
hr = spContext->get_Request(&m_piRequest);
if(FAILED(hr))
{
spContext.Release();
returnhr;
}
// Get Response Object Pointer
hr = spContext->get_Response(&m_piResponse);
if(FAILED(hr))
{
m_piRequest.Release();
returnhr;
}
// Get Server Object Pointer
hr = spContext->get_Server(&m_piServer);
if(FAILED(hr))
{
m_piRequest.Release();
m_piResponse.Release();
returnhr;
}
// Get Session Object Pointer
hr = spContext->get_Session(&m_piSession);
if(FAILED(hr))
{
m_piRequest.Release();
m_piResponse.Release();
m_piServer.Release();
returnhr;
}
// Get Application Object Pointer
hr = spContext->get_Application(&m_piApplication);
if(FAILED(hr))
{
m_piRequest.Release();
m_piResponse.Release();
m_piServer.Release();
m_piSession.Release();
returnhr;
}
m_bOnStartPageCalled = TRUE;
returnS_OK;
}
STDMETHODIMPCHTSrvActXCtrl::OnEndPage ()
{
m_bOnStartPageCalled = FALSE;
// Release all interfaces
m_piRequest.Release();
m_piResponse.Release();
m_piServer.Release();
m_piSession.Release();
m_piApplication.Release();
returnS_OK;
}
4>.h文件中添加函数声明如下:
//Active Server Pages Methods
STDMETHOD(OnStartPage)(IUnknown* IUnk);
STDMETHOD(OnEndPage)();
5>.idl文件中添加函数声明如下:
//Standard Server Side Component Methods
HRESULT OnStartPage([in] IUnknown* piUnk);
HRESULT OnEndPage();
剩下的问题,就是自己来添加方法和实现了,和客户端就没什么区别了。