📄 cmpnt.cpp
字号:
//
// Cmpnt.cpp - Component
//
#include <objbase.h>
#include <stdio.h> // sprintf
#include <stdlib.h> //splitpath
#include "Iface.h"
#include "Util.h"
#include "CUnknown.h"
#include "CFactory.h" // Needed for module handle
#include "Cmpnt.h"
static inline void trace(char* msg)
{ Util::Trace("Component", msg, S_OK) ;}
static inline void trace(char* msg, HRESULT hr)
{ Util::Trace("Component", msg, hr) ;}
//
// Type library name
//
const char szTypeLibName[] = "Server.tlb" ;
///////////////////////////////////////////////////////////
//
// Interface IX - Implementation
//
HRESULT __stdcall CA::Fx()
{
trace("!!!!! We made it here!!!!!") ;
return S_OK ;
}
HRESULT __stdcall CA::FxStringIn(BSTR bstrIn)
{
// Display the incoming string.
ostrstream sout ;
sout << "FxStringIn received a string: "
<< bstrIn
<< ends ;
trace(sout.str()) ;
return S_OK ;
}
HRESULT __stdcall CA::FxStringOut(BSTR* pbstrOut)
{
const wchar_t wsz[] = L"[String from FxStringOut]" ;
// Allocate an outgoing string.
*pbstrOut = ::SysAllocString(wsz) ;
if (*pbstrOut == NULL)
{
return E_OUTOFMEMORY ;
}
return S_OK ;
}
HRESULT __stdcall CA::FxFakeError()
{
trace("FxFakeError is faking an error.") ;
// Create the error info object.
ICreateErrorInfo* pICreateErr ;
HRESULT hr = ::CreateErrorInfo(&pICreateErr) ;
if (FAILED(hr))
{
return E_FAIL ;
}
// pICreateErr->SetHelpFile(...) ;
// pICreateErr->SetHelpContext(...) ;
pICreateErr->SetSource(L"InsideCOM.Chap11") ;
pICreateErr->SetDescription(
L"This is a fake error generated by the component.") ;
IErrorInfo* pIErrorInfo = NULL ;
hr = pICreateErr->QueryInterface(IID_IErrorInfo,
(void**)&pIErrorInfo) ;
if (SUCCEEDED(hr))
{
::SetErrorInfo(0L, pIErrorInfo) ;
pIErrorInfo->Release() ;
}
pICreateErr->Release() ;
return E_FAIL ;
}
//
// Constructor
//
CA::CA(IUnknown* pUnknownOuter)
: CUnknown(pUnknownOuter),
m_pITypeInfo(NULL)
{
// Empty
}
//
// Destructor
//
CA::~CA()
{
if (m_pITypeInfo != NULL)
{
m_pITypeInfo->Release() ;
}
trace("Destroy self.") ;
}
//
// NondelegatingQueryInterface implementation
//
HRESULT __stdcall CA::NondelegatingQueryInterface(const IID& iid,
void** ppv)
{
if (iid == IID_IX)
{
return FinishQI(static_cast<IX*>(this), ppv) ;
}
else if (iid == IID_IDispatch)
{
trace("Queried for IDispatch.") ;
return FinishQI(static_cast<IDispatch*>(this), ppv) ;
}
else if (iid == IID_ISupportErrorInfo)
{
trace("Queried for ISupportErrorInfo.") ;
return FinishQI(static_cast<ISupportErrorInfo*>(this), ppv) ;
}
else
{
return CUnknown::NondelegatingQueryInterface(iid, ppv) ;
}
}
//
// Load and register the type library.
//
HRESULT CA::Init()
{
HRESULT hr ;
// Load TypeInfo on demand if we haven't already loaded it.
if (m_pITypeInfo == NULL)
{
ITypeLib* pITypeLib = NULL ;
hr = ::LoadRegTypeLib(LIBID_ServerLib,
1, 0, // Major/Minor version numbers
0x00,
&pITypeLib) ;
if (FAILED(hr))
{
trace("LoadRegTypeLib Failed, now trying LoadTypeLib.", hr) ;
// If it wasn't registered, try to load it from the path.
// Get the fullname of the server's executable.
char szModule[512] ;
DWORD dwResult = ::GetModuleFileName(CFactory::s_hModule,
szModule,
512) ;
// Split the fullname to get the pathname.
char szDrive[_MAX_DRIVE];
char szDir[_MAX_DIR];
_splitpath(szModule, szDrive, szDir, NULL, NULL) ;
// Append name of registry.
char szTypeLibFullName[_MAX_PATH];
sprintf(szTypeLibFullName,
"%s%s%s",
szDrive,
szDir,
szTypeLibName) ;
// convert to wide char
wchar_t wszTypeLibFullName[_MAX_PATH] ;
mbstowcs(wszTypeLibFullName, szTypeLibFullName, _MAX_PATH) ;
// if LoadTypeLib succeeds, it will have registered
// the type library for us.
// for the next time.
hr = ::LoadTypeLib(wszTypeLibFullName,
&pITypeLib) ;
if(FAILED(hr))
{
trace("LoadTypeLib Failed.", hr) ;
return hr;
}
// Ensure that the type library is registered.
hr = RegisterTypeLib(pITypeLib, wszTypeLibFullName, NULL) ;
if(FAILED(hr))
{
trace("RegisterTypeLib Failed.", hr) ;
return hr ;
}
}
// Get type information for the interface of the object.
hr = pITypeLib->GetTypeInfoOfGuid(IID_IX,
&m_pITypeInfo) ;
pITypeLib->Release() ;
if (FAILED(hr))
{
trace("GetTypeInfoOfGuid failed.", hr) ;
return hr ;
}
}
return S_OK ;
}
///////////////////////////////////////////////////////////
//
// Creation function used by CFactory
//
HRESULT CA::CreateInstance(IUnknown* pUnknownOuter,
CUnknown** ppNewComponent )
{
if (pUnknownOuter != NULL)
{
// Don't allow aggregation (just for the heck of it).
return CLASS_E_NOAGGREGATION ;
}
*ppNewComponent = new CA(pUnknownOuter) ;
return S_OK ;
}
///////////////////////////////////////////////////////////
//
// IDispatch implementation
//
HRESULT __stdcall CA::GetTypeInfoCount(UINT* pCountTypeInfo)
{
trace("GetTypeInfoCount call succeeded.") ;
*pCountTypeInfo = 1 ;
return S_OK ;
}
HRESULT __stdcall CA::GetTypeInfo(
UINT iTypeInfo,
LCID, // This object does not support localization.
ITypeInfo** ppITypeInfo)
{
*ppITypeInfo = NULL ;
if(iTypeInfo != 0)
{
trace("GetTypeInfo call failed -- bad iTypeInfo index.") ;
return DISP_E_BADINDEX ;
}
trace("GetTypeInfo call succeeded.") ;
// Call AddRef and return the pointer.
m_pITypeInfo->AddRef() ;
*ppITypeInfo = m_pITypeInfo ;
return S_OK ;
}
HRESULT __stdcall CA::GetIDsOfNames(
const IID& iid,
OLECHAR** arrayNames,
UINT countNames,
LCID, // Localization is not supported.
DISPID* arrayDispIDs)
{
if (iid != IID_NULL)
{
trace("GetIDsOfNames call failed -- bad IID.") ;
return DISP_E_UNKNOWNINTERFACE ;
}
trace("GetIDsOfNames call succeeded.") ;
HRESULT hr = m_pITypeInfo->GetIDsOfNames(arrayNames,
countNames,
arrayDispIDs) ;
return hr ;
}
HRESULT __stdcall CA::Invoke(
DISPID dispidMember,
const IID& iid,
LCID, // Localization is not supported.
WORD wFlags,
DISPPARAMS* pDispParams,
VARIANT* pvarResult,
EXCEPINFO* pExcepInfo,
UINT* pArgErr)
{
if (iid != IID_NULL)
{
trace("Invoke call failed -- bad IID.") ;
return DISP_E_UNKNOWNINTERFACE ;
}
::SetErrorInfo(0, NULL) ;
trace("Invoke call succeeded.") ;
HRESULT hr = m_pITypeInfo->Invoke(
static_cast<IDispatch*>(this),
dispidMember, wFlags, pDispParams,
pvarResult, pExcepInfo, pArgErr) ;
return hr ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -