I'm new to COM/ATL and there are different tutorials on what to do when implementing connection points. Is it necessary to create an event sink? Some tutorials have the Fire method (created by ATL wizard) called from within a COM class method when some condition is met and some implement a new COM class that acts as an event sink (ATL Internals book). Would an instance of the COM object act as a sink unto itself? Sorry for dumb questions.
Yes, if you wish to be notified of events occurring in the COM object. Realize that in GUI apps all notifications from controls back to a client\host app are a function pointer setup. That's what a Window Procedure is in a standard Windows GUI app. If a control is built according to the COM standard, its still a similiar function pointer call back to the client, but the terminology and setup is somewhat different.
Would an instance of the COM object act as a sink unto itself?
It could be implemented but it would be dumb to do I think. The COM object has access to everything going on within itself. If its a visual control, for instance, it would have an internal Window Procedure where it would have access to all user or other generated actions. Depending on the nature of the object and what it does and reacts to, it would make calls back to the event sink in the client to notify it of what's going on that may be of interest to the client.
Years ago I posted here an involved event sink example where I had a C++ client connecting to and receiving events from the MSFlexGrid OCX grid control that used to be used a lot with the older versions of Visual Basic. I didn't use ATL but just explained the raw low level COM code including event sinks. Could give you a link to it if you want. I'll warn you though that its complex. Not many present day C++ coders would be able to tolerate it. That's what ATL was made for. Down side is that users don't really understand the generated code loaded with complicated macros.
Thanks Freddie for the response. I managed to get an event sink working but only as a standard C++ class inheriting from IDispEventImpl which I can include in a win32 executable using its header file. I'm trying to implement the sink as a COM object as well with ATL (eventually as a dll that incorporates both COM object and event sink if possible). However, when importing the dll or tlb generated by the COM object compilation into the event sink COM files, it isn't able to generate the tlh file and fails to build and does not recognize the COM object and its Events interface. Any thoughts on why the #import statement does not work and thus making the COM object and its library unidentified? I am using no_namespace and named_guids attribute for the import.
The following example at Microsoft website is basically what I'm doing ATM and this fails to build for the same reason:
Edit: I have the sink working when it's part of an ATL Exe that imports the source COM object dll. Now trying to make a dll that incorporates both the event sink COM object and the source COM object. It compiles (not sure if it really works) but when I try to make an executable, the compiler fails to find the LIBID and IID values of the sink object.
Edit 2: Got it working (I think!) by putting COM source and COM event sink in the same ATL project and compiling as DLL. Using the header for the sink class in the ATL Exe project allowed it to work. However, I don't know if it's working because the DLL is correct or because I included the header file. How can I check if the DLL contains both COM objects and their associated functions since I plan to use this in python and thus can't include the header? A dumpbin of the DLL with /exports flag only shows the 5 DLL install/registration files and /symbols flag shows nothing.
Any thoughts on why the #import statement does not work and thus making the COM object and its library unidentified? I am using no_namespace and named_guids attribute for the import.
Putting the Events interface within a dll likely isn't a good idea. I typically include that code within the source code of the client/host app. Having said that I see no reason conceptually it couldn't be done - only that it would be an unusual thing to do, and since you are using automated tools which auto-generate code for you (ATL), it wouldn't surprise me if they don't have it set up to work that way.
The Events interface really isn't a part of the COM object. Its logically a part of the client/host object whose design is such that it is prepared to accept messages from the COM component.
Been indisposed for some time. That's why it took some time to reply.
You may be right about it not allowing inclusion in the dll. If I keep the sink COM object separate from the dll, I can get it to work. However, if I include the sink object in the dll, it seems to forget that it is derived from IDispEvent since I have no access to the DispEventAdvise function to tie the COM source and sink together. This kinda puts a hamper on what I wanted to do.