views:

629

answers:

7

I am trying to create a COM component using ATL, and I'd like to raise events for my VB client. I've found numerous tutorials, all of which seem to vary in details, and none of them appear to generate a working solution. Here is what I am doing:

(Using Visual Studio 2008):

  1. Create a new ATL DLL Project. I've called it ATLEventTest.
  2. Class View: Right clicked on ATLEventTest, Added a new ATL Simple Object class. I called this MyObject, which generated CMyObject, IMyObject, etc...
  3. This object was created with: a) Apartment Threading b) Aggregation c) Dual Interface d) ISupportErrorInfo e) Connection points

  4. Right clicked on CProxy_IMyObjectEvents<T>, clicked 'Add Function'

  5. Function is of void return type, named someEvent, and takes an int testParam.
  6. Rebuild.
    (At this point, I should be able to see an 'Implement Connection Point' somewhere. I do not...)
  7. Right clicked on CMyObject. 'Add Connection Point'
  8. Moved '_IMyObjectEvents' over into the list.
  9. Did a code search in my solution. Can't find someEvent anywhere!
  10. Added the someEvent function again. Now, it is found in ATLEventTest_i.h
  11. Should be able to call fire_someEvent(...) in my code, but can't.

This has been driving me insane trying to get this to work. If anyone can see what I'm doing wrong, I'd appreciate any corrections, tips, hacks, etc.

At this point, I'm tempted to say screw the wizards, and just try to modify the c++ and idl directly, but I've got a feeling that might not fair much better :(

+4  A: 

Try using the method outlined at this location:

Adding an Event (ATL) @ MSDN

With the example names you have given above, in your MyObject.idl file, you should see a declaration for your outbound even under the section for dispinterface _IMyObjectEvents. Since you right clicked on CProxy_IMyObjectEvents<T> and not on _IMyObjectEvents under the library, your IDL is probably missing the definition. The auto-generated file _IMyObjectEvents_CP.h file should be present in your project header files and should contain the Fire_someEvent() method as a result of adding the method correctly. If not, you may find that it just created a method named someEvent() instead.

Here is an outline you can try in a test project.

  1. Create a new ATL DLL Project. I've called it ATLEventTest1.
  2. Build Project.
  3. Class View: Right clicked on ATLEventTest1, Add a new ATL Simple Object class. Call it MyObject.
  4. Create the definition with a) Apartment Threading b) Dual Interface c) Connection points and whatever else you need.
  5. Rebuild Project.
  6. Class View: Locate the ATLEventTest1Lib library, right click on _MyObjectEvents, and "Add Method".
  7. Method is of void return type, named someEvent, and takes an int testParam with parameter attribute [in].
  8. You should see "[in] int testParam" as a result of adding the parameter.
  9. On the IDL Attributes tab, change the id if necessary. Click Finish.
  10. Class View: Right click on CMyObject, go to Add... , go to Implement Connection Point.
  11. Select _IMyObjectEvents and click ">" to move it to the implemented connection points list. Click Finish.
  12. Rebuild.
  13. Now, in your CMyObject class, you should be able to call Fire_someEvent(). You will see a new method in your ATLEventTest1.idl file under the dispinterface _IMyObjectEvents; the header file _IMyObjectEvents_CP.h file will be created and will create the broadcast code for Fire_someEvent().
meklarian
+1: Works a treat for me. Thanks.
Rob
A: 

Does you class have an implementation of IProvideClassInfo/IProvideClassInfo2? If I recall for non-control objects, VB requires this to locate the event source interface.

Try this:

public IProvideClassInfo2Impl<&CLSID_MyClass NULL, &LIBID_ATLEventTest, 1, 0>,

and then in the interface map

COM_INTERFACE_ENTRY(IProvideClassInfo)
COM_INTERFACE_ENTRY(IProvideClassInfo2)
cantabilesoftware
A: 

Maybe you have a problem with apartment threading. Do you write console application on VB? It requires a classic message pump to work properly (for example classic windows application). Try different apartment mode on your COM object (MTA).

Alex Stankiewicz
A: 

Hello Everyone,

Thanks for the answers. For those of you who are suggesting various solutions relating to the interplay with VB, while those might be problems later on, I'm simply not that far yet. I cannot call fire_someEvent from my C++ code. VB isn't in the picture yet.

Meklarian, I had found those steps previously, and my problem occurs on step 6. I don't have anything in my class view that looks like MyObjectEvents. Only the CProxy....

I won't be able to touch any of this until later this afternoon, but I'm going to double check my steps, and I will report back with any new details.

Anybody else have any suggestions?

Thanks again, -Chris

A: 

Ok. I'm back again. Sorry for the delay. Here is where I am now:

Following Merklarian's steps, I get stuck on step #10. I've tried to right-click on everything looking for 'Implement Connection Point', and have found nothing by that phrase. Right-clicking on CMyObject does provide 'Add Connection Point' and 'Implement Interface'.

Either one of those brings up a similar looking dialog box, but when all is said and done, I still can't find a fire_someEvent anywhere in the code.

There has got to be something small and obvious that I'm missing...

Thanks again, Chris

Hi Christopher, the 'Add Connection Point' option is under a sub-menu when you right click on your primary object. Can you detail the list of items that you see when you right-click? It's also possible that the .suo file accompanying your solution is damaged. Try deleting it while your solution/project is closed, and then after opening your solution/project and closing once more, make sure the file is not marked read-only.
meklarian
I recreated my test solution/project for this once more in VS2005. Can you try opening the project in VS2008 and see if you can add another outbound event? The zip file is located at http://www.amorph.com/stack-overflow/ATLEventTest1.zip
meklarian
I can find 'Add Connection Point', but I don't see an 'Implement Connection Point', which is what all of the tutorials tell me to look for...I downloaded your code, and loaded it into VS2008. I added a new method as indicated, and then clicked 'Add Connection Point'. Moved the thing into the other list. And rebuild. This is what I get now...C2504: CProxy_IMyObjectEvents: base class undefined.And 6 other errors resulting from that first one... I didn't modify any code. Just used the wizards.Happens on VS2008 on a Vista machine, and a Windows 7 RC1 laptop. Is VS2008 screwed?
A: 

Ok. So after a new system rebuild, I have installed both Visual Studio 2005 and Visual Studio 2008. I can get this working in 2005 perfectly. Still can't get the thing working in 2008. Looks like I'm just going to have to work on VS2005 for my ATL stuff...

Thanks again to all who helped.

Christopher
A: 

I was having the same issue. Kept reading the MSDN documents and searched online. Finally, I figured it out.

The main thing that the wizard isn't doing is putting the declaration in the IDL file. I manually added it, and in my class, theres a "Fire_".

Hope this helps you.

henry