Adding Connection Points to an Object
The ATL Tutorial demonstrates how to create a control with support for connection points, how to add events and then how to implement the connection point. IConnectionPointImpl discusses how ATL implements a connection point.
To implement a connection point, you have two choices:
-
Implement your own out-going event source (connection point).
-
Reuse a connection point interface defined in another type library.
In either case, the connection point wizard uses a type library to do its work.
Note Whenever you add a method to a dispinterface on which you have already implemented a connection point, you must recompile the .idl file and then follow the procedure to add a connection point to a control or object.
To add a connection point to a control or object
-
Define a dispinterface in the library block of the .idl file. If you selected the Support Connection Points check box in the Attributes tab of the ATL Object Wizard, the dispinterface will already be created. If you did not check the Support Connection Points check box, you must manually add a dispinterface to the .idl file. The following is an example of a dispinterface. Outbound interfaces are not required to be dispatch interfaces but many scripting languages such as VBScript and JavaScript require this, so this example uses two dispinterfaces:
library DProjLib
{
importlib("stdole32.tlb");
importlib("stdole2.tlb");
[
uuid(57BC50F0-780B-11d1-8C44-0060083E866C),
helpstring("Buddy Events")
]
dispinterface DBuddyEvents
{
properties:
methods:
};
Use either the uuidgen.exe or guidgen.exe utilities to generate a GUID.
-
Add the dispinterface as the [default,source] interface in the coclass for the object. Again, if you selected the Support Connection Points check box in the Attributes tab of the ATL Object Wizard for this control, the wizard will create the [default,source] entry. To manually add this entry, add the line in bold:
coclass Buddy
{
[default] interface IBuddy;
[default,source] dispinterface DBuddyEvents;
};
See the .idl file in the Circ ATL sample for an example.
-
Use ClassView to add methods and properties to the event interface.
-
After the dispinterface is fully defined, compile the .idl file by right-clicking the .idl file in FileView and selecting the compile option. This will produce the type library.
-
Right-click the class in ClassView and select Implement Connection Point.... A dialog box will display one or more type library tabs and each tab will display the interfaces for that type library. If you choose an interface and press OK, you will:
-
Generate a header file with an event proxy class that implements the code that will make the out-going calls for the event.
-
Add an entry to the connection point map.
-
Add a comment and #error (telling you to replace the NULL parameter with the address of the dispID) to the parameter list of IProvideClassInfo2Impl.
If you have not built your type library, you will see a list of all the typelibs on your computer. You should only use one of these other typelibs to define your connection point if you want to implement the exact same outgoing interface found in another typelib. If you build a typelib with no default source interface in the coclass, the dialog box will display a warning message reporting no suitable (source) interface in the type library.
To implement a connection point taken from another object's type library
-
In ClassView, right-click on a class that implements a BEGIN_COM_MAP macro, and select Implement connection point from the shortcut menu.
-
In the Implement Connection Point dialog box, click Add Typelib....
-
Select from one of the available type libraries. After you select the type library, you will see a list of the available interfaces in the type library.
-
Choose one or more of the available interfaces and click OK.
-
Edit the .idl file to either:
-
Copy the dispinterface from the idl file for the object whose event-source is being used.
-
Use the importlib instruction on that type library.
Here's an example from an .idl file that is using the connection point from the Circ control.
[
uuid(38BBFD91-7575-11D1-8C3C-0060083E866C),
version(1.0),
helpstring("16190 1.0 Type Library")
]
library MY16190Lib
{
importlib("stdole32.tlb");
importlib("stdole2.tlb");
importlib("D:\\ATL25\\samples\\circ\\circ.tlb"); //**** add this line
[
uuid(38BBFD9E-7575-11D1-8C3C-0060083E866C),
helpstring("Atl16190Ctl Class")
]
coclass Atl16190Ctl
{
[default] interface IAtl16190Ctl;
[default,source] dispinterface _CircEvents; //**** and this one
};
};