If you look at the MIDL or Automation documentation for the attribute "oleautomation," which is used on interfaces, you will notice that it is valid for interfaces that aren't derived from IDispatch. To put it simply: regular IUnknown-derived interfaces are valid for Automation, as long as they are valid interfaces for Automation, as described in the documentation.

The only difference between using IUnknown and IDispatch is that a type library is required to use an IUnknown-derived interface. It only works for environments that use early-binding with type libraries (like VBA, which is embedded in all MS Office programs). You can't use IUnknown from a scripting language.

I've quickly written a COM object to try it out. Both properties and methods can be defines inside of an IUnknown interface. The only problem is that when calling a get property like:

void Value( LONG * pRet);

causes an error because pRet turns out to be NULL, for some reason. What do you think the problem could be? The object is inside of a DLL, but I suspect it is a marshalling error because VBA isn't dumb enough to call the function with a null pointer.
Posted on 2003-07-10 12:54:32 by Paulicles the Philosopher
Hi PtP,

AFAIK if an interface has attribute "oleautomation" all parameters must be oleautomation-compatible so marshalling may be done by standard ole mechanisms. And for a in-proc-server (a dll) marshalling isnt reqired at all.
Posted on 2003-07-10 14:45:23 by japheth
I got this to work. I really don't know what went wrong before, but I rewrote the interface and the code and now it works.


helpstring("ICustom Interface"),

interface ICustom : IUnknown
import "oaidl.idl";

HRESULT CustomFunction();
HRESULT MsgBox( BSTR Message);
HRESULT GetName( BSTR * Name);

// Had trouble with propget, but it now works
HRESULT Value( LONG *pRet);
HRESULT Value( LONG NewValue);

VBA Client Code:

Dim myObj As MyComObject

Set myObj = CreateObject("TestDll.MyComObject")

Dim var As Variant

myObj.Value = 10
var = myObj.Value

MsgBox (var)
MsgBox (myObj.GetName)

myObj.MsgBox ("Hello, World")

Set myObj = Nothing

Thanks anyway.
Posted on 2003-07-10 15:01:59 by Paulicles the Philosopher
"I think I have the solution!" - Homestar Runner

It's the HRESULT. The property can be void.
Posted on 2003-07-10 15:53:34 by Paulicles the Philosopher