|
|
Title |
Interogating an object through Idispatch
|
Summary |
Here is a small segement of code that can be used to enumerate the methods of a IDispatch interface. This can be useful when little is known about the interface. |
Contributor |
John McTainsh
|
Published |
29-Mar-2001 |
Last updated |
29-Mar-2001 |
|
|
Description.
This article will cover how snoop out a little information about an IDispatch
interface you have acquired. There are many thing you can do with the IDispatch
interface and this is a just a small code segment showing the method names and parameters.
What the code does.
The main function TraceInterfaceData() is passed a pointer to a
IDispatch interface. Calls are made to get information about the objects
methods and the method parameters. The data gathered is written to the trace
log. GetVarDesc() could be called in place of GetFuncDesc() to
retrieve the interfaces attributes/properties rather than the methods.
Note: This is just some handy info, if the original authors notes are available
they should contain more detailed information such at variable types and method
descriptions.
The code.
// ***************************************************************************
//DESCRIPTION:
// Convert the Method invoke attribute into a string to display
//PARAMS:
// invkind Invoke type
//RETURN:
// pointer to constant string name.
//CREATED:
// 29-3-2001, 14:50:01 by john@mctainsh.com
// ***************************************************************************
#define CASE_AND_RETURN(x) case x: return _T(#x);
LPCTSTR GetInvokeType( INVOKEKIND invkind )
{
switch( invkind )
{
CASE_AND_RETURN( INVOKE_FUNC )
CASE_AND_RETURN( INVOKE_PROPERTYGET )
CASE_AND_RETURN( INVOKE_PROPERTYPUT )
CASE_AND_RETURN( INVOKE_PROPERTYPUTREF )
}
return _T("{not recognised}");
}
// ***************************************************************************
//DESCRIPTION:
// Look into the interface and display some of the method information.
// This could also be modified to display variables.
//PARAMS:
// pDispatch Pointer to the interface to enumerate.
//CREATED:
// 29-3-2001, 10:09:22 by john@mctainsh.com
// ***************************************************************************
void TraceInterfaceData( IDispatch *const pDispatch )
{
//
//Get access to the type information
//
ITypeInfo *pTypeInfo = NULL;
HRESULT hr = pDispatch->GetTypeInfo( 0, NULL, &pTypeInfo );
if( SUCCEEDED( hr ) )
{
//
//Keep reading function data until an unable to read ony more
//
int i = 0;
while( true )
{
FUNCDESC* pFuncDesc;
//pITypeInfo->GetVarDesc( i, &pVarDesc );
hr = pTypeInfo->GetFuncDesc( i, &pFuncDesc );
if( SUCCEEDED( hr ) )
{
//Display function ID and Invocation type
MEMBERID idMember = pFuncDesc->memid;
TRACE( _T("%9x)"), idMember );
TRACE( GetInvokeType( pFuncDesc->invkind ) );
//Display the function name and first 20 parameters
BSTR pbsNames[20];
unsigned int nCount;
hr = pTypeInfo->GetNames( idMember, pbsNames, 20, &nCount );
if( SUCCEEDED( hr ) )
{
TRACE( _T(" %S ( "), pbsNames[0] );
for( unsigned int nParam = 1; nParam < nCount; nParam++ )
{
if( nParam > 2 )
TRACE( _T(", ") );
TRACE( _T("%S"), pbsNames[nParam] );
}
TRACE( _T(" )\n") );
}
//Release
for( unsigned int nName = 0; nName < nCount; nName++ )
SysFreeString( pbsNames[nName] );
pTypeInfo->ReleaseFuncDesc(pFuncDesc);
}
else
{
break;
}
i++;
}
//Clean up the house
pTypeInfo->Release();
}
}
|