Search code examples
comvbscriptautomationdispatch

Automating an Application using COM


I am building an automation interface for an existing application. After implementing a DLL server and an EXE server (mainly for getting familiar with the basics of COM) I am now at the point where I generate a type library from an IDL file and can, for example, basically automate my application from VBScript:

Set oApp = CreateObject("MyApp.1") 
oApp.ShowAboutBox()

This simple call to a function that takes no parameters works. The next step I want to take is call a function that takes a parameter.

The signature of the function in the IDL file is

HRESULT CreateSomeChildWindow([out, retval] MyChildWindow** ppChildWindow);

and in VBScript I assume it would be

Dim oWnd As MyChildWindow
oWnd = oApp.CreateSomeChildWindow()

This call already works in C++ although MyChildWindow is not currently registered as a COM object in the registry. The reason MyChildWindow doesn't need to be registered is that CreateSomeChildWindow simply returns the interface pointer to the created MyChildWindow object in a parameter. And the reason it isn't registered is that I want to avoid redundancy, and also I don't want MyChildWindow to be instantiated directly (e.g. by calling CreateObject in VBScript).

Question:

Now I'm trying to find out whether it will be necessary to register MyChildWindow after all. Is my assumption correct that in order to call CreateSomeChildWindow in VBScript

  • I need to write Dim oWnd As MyChildWindow
  • For this to work, MyChildWindow must be registered

And if the answer to that is yes, hopefully clients still can't MyChildWindow directly, since I don't implement a class object for it? Or will I have to implement a class object?


Solution

  • Your out/retval is not an object (on the scripting side), it is an interface pointer. And since the method CreateSomeChildWindow is on IDL, in type library, in registered type library - scripting/automation is aware of interface definition, such as methods etc, because the whole type library is already registered. You are already well set, no additional registration required.

    When caller receives an interface pointer, it does not care what object the pointer belongs to. Interface pointer alone is good enough, and scripting/automation environment known how to deal with it.

    On the callee side however, you need to return an interface pointer, and you are dealing with objects. So you need some class which implements this interface and you return this object's interface.