OLE Tips

OLE and NT services
You have to be careful about when you call OleInitialize when you are writing an NT service application - don't just blindly use it if you think you might need OLE stuff. If you need OLE functions from within your program, you may wind up locking out other applications that use OLE, even if your program is working fine and doesn't leak a thing. The work-around is to call OleInitialize and OleUninitialize before and after your OLE calls. Obviously, you can't do this if your service is providing some form of OLE object for others to get to.

Listing all functions and parms
If you've every wondered how Visual Studio gets a list of the functions and parms in a OLE Server, or want to list them out yourself (say to find functions that can take class objects that you provide in your side of the equation), here's how. And hey, as Free Bonus, this also works with Windows Script Host, so you can use this in your code that uses ActiveScript. This example code simply lists out to the stdout via printf, but you can adapt this to do pretty much whatever you want:


// This function will scan through the passed dispatch pointer and dump
// all the names of all the functions AND their parms (if any).
// This will not list out any functions that are marked as "private". For example:
// Private Sub Foo()
// End Sub
// Sub weird()
//		Foo
// End Sub
// Will only list out weird, and not Foo (but remove Private from Foo and it
// will list out too!)
// Pass it a valid IDispatch pointer.
void FindAllFunctionNames(IDispatch *pDisp)
{
	ITypeInfo *pTypeInfo = NULL;
	HRESULT hr = pDisp->GetTypeInfo(0,NULL,&pTypeInfo);
	TYPEATTR* ta=NULL;
	hr =pTypeInfo->GetTypeAttr(&ta);
	for(int i=0;i < ta->cFuncs;i++)
	{
		FUNCDESC* fd;
		hr = pTypeInfo->GetFuncDesc(i,&fd);	
		BSTR name=NULL;
		hr = pTypeInfo->GetDocumentation(fd->memid,&name,NULL,NULL,NULL);
		char sname[256];
		W2A(name,sname,256);
		SysFreeString(name);
		int numParms=fd->cParams;
		printf("name = %s, #parms=%d\n",sname,numParms);
		if (numParms)
		{
			BSTR *pNames = new BSTR[numParms+1];
			memset(pNames,0,sizeof(BSTR)*(numParms+1));
			unsigned int numNamesGot=0;;
			hr = pTypeInfo->GetNames(fd->memid, pNames, numParms+1, &numNamesGot);

			for (int pn=0;pn<fd->cParams;pn++)
			{
				ELEMDESC *pElm=&fd->lprgelemdescParam[pn];
				printf("\t parm#%d = %d ",pn+1,pElm->tdesc.vt);	// usually 12 for the vt
				W2A(pNames[pn+1],sname,256);
				printf("name=%s",sname);
			}
			printf("\n");
			for (pn=0;pn<numNamesGot;pn++)
				SysFreeString(pNames[pn]);
		}
		pTypeInfo->ReleaseFuncDesc(fd);
	}
	pTypeInfo->ReleaseTypeAttr(ta);
	pTypeInfo->Release();
}


Updated: Thursday, Sep 18, 2008
Contents copyright © 1999-2003 by NOPcode.com and its subsidiaries. Reproduction in part or in whole prohibited unless explicitly granted. All information and products, be it documentation, essays, source code, programs, or installs, are provided "as-is" and neither the author nor NOPcode.com will be held responsible for any resulting damages, either physical or mental. No warranty is expressed nor implied. All rights reserved. All trademarks used are property of their respected companies. For further information contact .