tags:

views:

421

answers:

4

I need to implement a simple ATL COM object that implements a specific interface for which I have been given both a .tlb file and a .idl file. The interface is very simple and only consists of a single method. I have created many ATL objects in the past but never one that has to implement a specific interface. What do I need to achieve this? I'm assuming that I somehow need to reference the interface's IDL or TLB in my new objects IDL somewhere?

Any pointers are welcome.

A: 

When you compile the .idl file you can ask MIDL to produce a header file with C++ interface definitions - include that header file and inherit your implementation class from the C++ equivalent of the specific interface. You might also need to pass the C++ interface as the parameter to the ATL helper base classes like IDispatchImpl.

sharptooth
See this question on how to inherit: http://stackoverflow.com/questions/1729834/whats-the-purpose-of-iunknown-member-functions-in-endcommap
sharptooth
A: 

if you have a interface.tlb file, you can use

#import "interface.tlb"

to include it in a .cpp file, the compiler will convert the .tlb to a C++ style interface declaration. It creates a file called interface.tlh on the fly and then #includes it automatically.

Then you use the usual C++ style code to write a class that implements the interfaces in the generated .tlh file.

John Knoeller
+1  A: 

It's much more automatic than the other answers here are suggesting. All the boilerplate code is written for you by Visual Studio.

You're lucky you have the .idl, it's by far the most conveninent, I think.

You could paste the contents of the .idl file into your ATL COM project's existing .idl file, which would give you access to the declarations in it. For example, something like this could be pasted into an IDL file:

[
    object,
    uuid(ecaac0b8-08e6-45e8-a075-c6349bc2d0ac),
    dual,
    nonextensible,
    helpstring("IJim Interface"),
    pointer_default(unique)
]
interface IJim : IDispatch
{
    [id(1), helpstring("method SpliceMainbrace")] HRESULT SpliceMainbrace(BSTR* avast);
};

Then in Class View, right click your class and choose Add | Implement Interface.

Notice that in this dialog, you can actually browse for a .tlb file, but I think it's better to have plain-text source for these things, for version control and the like.

Pick IJim from the list, press the > button to add it to the list to be implemented. Press Finish.

Visual Studio will add this to your class (along with a bunch of other crap to make it work):

// IJim Methods
public:
    STDMETHOD(SpliceMainbrace)(BSTR * avast)
    {
        // Add your function implementation here.
        return E_NOTIMPL;
    }
Daniel Earwicker
The helpstring mismatches the interface name in the snippet.
sharptooth
Perfect! Thanks.
Rob
@sharptooth - good point, wouldn't want people to get IFred and IJim mixed up so I fixed it.
Daniel Earwicker
A: 

I can't see how to add my question to the accepted answer but I tried to follow the instructions given in his example but I couldn't get the IJim interface listed in the "Implement Interface" dialog when selecting the project radio button there were no interfaces listed even after I compiled the IDL file, choosing instead to navigate to the type library did not help either.

Stone Free
I've figured out the answer the class view won't allow you to implement your own interface. If instead choose a different ATL object and choose "Implement Interface" I can then see IJim in the list of interfaces
Stone Free