How can users include Strategy COM 9.x pre-defined constants into a project?
All the symbolic and numeric constants employed for the Strategy COM 9.x interface are pre-defined in m5typlib.dll under C:\Program Files\Common Files\Strategy. If using Microsoft Foundation Class (MFC), the above path must be added under Tools/Options/Directories (for executable files) and the following statement must be inserted into the StdAfx.h file:
#pragma warning( disable : 4146)
#import "M5typlib.dll" raw_interfaces_only no_namespace named_guids rename ("GUID", "_GUID") exclude ("IStream", "tagSTATSTG", "_LARGE_INTEGER", "_ULARGE_INTEGER") exclude ("ISequentialStream", "IErrorInfo", "_FILETIME")
#pragma warning( default : 4146)
NOTE: Please refer to the following technote for instructions on how to set up new project:
How to configure a Visual Basic 6 project for use with MicroStrategy Intelligence Server SDK 9.x How do users start this process?
Initialize the Strategy COM library using CoInitialize() before making any other Application Programming Interface (API) calls. Afterward, CoCreateInstance() can create a single uninitialized object of the class associated with a specified class identifier. In most cases, start from the data source list on the local system, so IDSSDataSourceEnumerator may be the first instance to be created. The format can be as follows:
IDSSDataSourceEnumerator* pDataSourceList;
HRESULT hr = CoCreateInstance(CLSID_DSSDataSourceEnumerator, NULL,
CLSCTX_INPROC_SERVER, IID_IDSSDataSourceEnumerator, (void**)
&pDataSourceList);
How different would it be if using the same API call by Visual C++ compared with Visual Basic?
In Visual Basic (VB), if a variable is defined as 'Dim' without specifying a datatype or object type and if there is no Deftype statement in the module, the variable is Variant by default. Variant is a special datatype that can contain numeric, string or date data as well as user-defined types and the special values Empty and Null. Therefore, users can apply the Dim variable directly without the actual datatype. For example, the following code is applied to list all the projects under the top-level data source:
Dim i
Dim objDS As IDSSDataSource
For i = 1 To mobjTopDS.Enumerator.Count
Set objDS = mobjTopDS.Enumerator.Item(i)
lstSecondLevelDSs.AddItem objDS.ProjectName
Next i
To achieve the same goal from Microsoft Visual C++ (VC), more strict datatype matches are required, as follows:
long projlistcount = 0;
IDSSDataSource* pMyProject;H
RESULT hr = pMyProjectList->Count(&projlistcount);
for (long i = 1; i <= projlistcount; i++)
{
pMyProject = NULL;
CComVariant projIndex = i;
BSTR ProjectName;
hr = pMyProjectList->Item(&projIndex, &pMyProject);
hr = pMyProject->get_Name(&ProjectName);
}
The length of the project lists projectlistcount must be defined as long, projIndex must be Variant and ProjectName must be BSTR.
Another related issue is optional parameters. For example, NewObject method for IDSSSource is defined with one required parameter and three optional parameters as the following:
Function NewObject(Type As EnumDSSObjectType, ,
) As IDSSObjectInfo
From VB, it is possible to only specify the required parameter and omit all optional parameters, as follows:
Dim objSearch As IDSSSearch
Set objSearch = mobjObjSource.NewObject(DssTypeSearch)
However, for VC, each parameter must be specified, even if only the default value is adopted. In this case, the appropriate NULL pointer or corresponding empty value must be assigned explicitly, as follows:
IDSSObjectInfo* pObjectInfo;
hr = pMyObjectSource->NewObject(DssTypeSearch,
static_cast<EnumDSSSourceFlags>(NULL), NULL,&pObjectInfo);
How can users switch between different interfaces of the same 'first class' COM object?
All 'first class' objects (such as templates, filters, reports, etc.) in Strategy SDK 8.0.x support the IDSSObjectInfo interface as well as other type-specific interfaces. For example, a DSS Template object has both the IDSSObjectInfo and IDSSTemplate interfaces. There are two ways to switch between these two interfaces:
- Use '::special' and '::info' methods. Method special can be used to switch from IDSSObjectInfo interface to type-specific interfaces and method info is the reverse way. For example, the following:
IDSSObjectInfo* myTemplateInfo;
… //myTemplateInfo is assigned
IDSSTemplate *pMyTempDef = (IDSSTemplate *) NULL;
HRESULT hr = myTemplateInfo->Special((IDispatch*) &pMyTempDef);
- If users already know what kind of interface is to be returned, the QueryInterface method can be adopted as follows:
IDSSObjectInfo* myTemplateInfo;
…//myTemplateInfo is assigned
IDSSTemplate* pMyTempDef = NULL;
hr = myTemplateInfo->QueryInterface(IID_IDSSTemplate, (void**) &pMyTempDef);
Code Customization:
WARNING:
This customization is provided as a convenience to Strategy users and is only directly applicable to the version stated. While this code may apply to other releases directly, Strategy Technical Support makes no guarantees that the code provided will apply to any future or previous builds. In the event of a code change in future builds, Strategy may not be able to provide additional code on this matter even though this customization is provided at this time for this specific build.