Raising Events Handled by a COM Sink

M

Michael Tissington

I have created a class with a number of methods and events as described in
the MSDN infor for handling events.

I am trying to use the attributes GuidAttribute and DispID. The problem that
I'm having is that when I try to use the tlb file the guid and dispid
attributes seem to have been ignored - here is some of the code I'm using.

Any ideas ?

-------- snip ---------------
<GuidAttribute("20000000-3371-0000-AF8A-AFFECC1B0967"),
InterfaceTypeAttribute(ComInterfaceType.InterfaceIsDual)> _
Public Interface _Form
DispId(10)> _
Sub ShowForm(ByVal sCN As String, ByVal sGUID As String)
<DispId(20)> _
Event ShutDownForm()
End Interface
<GuidAttribute("10000000-3371-0000-AF8A-AFFECC1B0967"),
InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)> _
Public Interface MAPIFormEvents
Sub ShutdownForm()
End Interface

<GuidAttribute("30000000-3371-0000-AF8A-AFFECC1B0967"),
ClassInterface(ClassInterfaceType.None),
ComSourceInterfaces(GetType(MAPIFormEvents))> _
Public Class Form
Implements _Form
Public Event ShutDownForm() Implements _Form.ShutDownForm

--------- snip ----------------
 
S

stand__sure

starting from the general and moving into the more specific...
0) Your class "Form" needs to inherit from ServicedComponent
1) the compiler will assume the Attribute portion of the tag -- so, you
can simply write Guid(...) in lieu of GuidAttribute
2) <ClassInterface(ClassInterfaceType.None)> is the recommended setting
-- ClassInterfaceType.AutoDual causes versioning problems
3) DispIds are generated based upon the position of the members in the
class; yo can override them, but this level of control is generally not
needed unless you are attempting to prevent a new version of your
component from breaking an app that uses a previous version

Are you trying to call your .NET component in non-.NET code? If so,
see "Calling a .NET Component from a COM Component"
http://msdn.microsoft.com/library/en-us/dndotnet/html/callnetfrcom.asp?frame=true
and
"Packaging an Assembly for COM"
http://msdn2.microsoft.com/library/bctyca52(en-us,vs.80).aspx
 
M

Michael Tissington

Hi,

Why do I need to use ServicedComponent - I thought this was for COM+ ?

According to the MSDN docs I should use GuidAttribute to avoid confusion
with the type guid

I'm not using ClassInterfaceType.AutoDual

I don't think your comments tell me why my guids are not being using when
generating the code - the tlb shows a completely different set of guids.

How do I get me tlb to contain definitions (my guids) for the interfaces ?
 
S

stand__sure

sorry, about the dual thing... could have sworn I read it in your
code... as for ServicedComponent inherit it -- you are doing COM...

I have been unable to replicate your problem on my box... please post
FULL code
 
S

stand__sure

also, lest I forget are you using a .NET COM component in a non .NET
language (I assume that you are, but more details as to where and how
you are trying to use the class would be helpful). how are you
registering the component? regsvcs? regasm? what is your command line
for doing this?
 
M

Michael Tissington

Yes, I'm creating a .NET component and trying to use if BOTH from VB 6 and
VC++.

The class functions correctly in VB6

In VC++ I #import the type library but when I look at the generated tli and
tlh files the guids are NOT the guids that I specified when I used the
GuidAttribute. In addition there are no definitions for the interfaces that
I created in .NET (there are definitions for the Methods and Events but
again they do not have the Despid that I assigned to them)
 
S

stand__sure

Michael said:
Yes, I'm creating a .NET component and trying to use if BOTH from VB 6 and
VC++.

The class functions correctly in VB6

In VC++ I #import the type library but when I look at the generated tli and
tlh files the guids are NOT the guids that I specified when I used the
GuidAttribute. In addition there are no definitions for the interfaces that
I created in .NET (there are definitions for the Methods and Events but
again they do not have the Despid that I assigned to them)

VB is doing the work behind the scenes that you must explicitly do in
c++

AGAIN, PLEASE POST CODE -- IT IS IMPOSSIBLE TO KNOW WHAT YOU ARE DOING
WITHOUT AN EXEMPLAR!

your code should (probably) look something like this (meta-code)
//
HRESULT hr;
IUnknown * punk;
hr = CoCreateInstanceEx(CLSID,punk,...);
//test hr
void ** ppobj;
hr = punk->QueryInterface(IID,ppobj);
//test hr
hr = punk->AddRef();
//
 
M

Michael Tissington

Hello,

Thanks for the code snipet .. its very similar to mine.

The BIG question is the definitions for the CLSID and IID (that I specify in
my .NET) are not being generated in my tlb file - in fact they seem to being
ignored.

---- VB.NET code. --------

Imports System
Imports System.Runtime.InteropServices

Namespace MapiForm

<GuidAttribute("20000000-3371-0000-AF8A-AFFECC1B0967"),
InterfaceTypeAttribute(ComInterfaceType.InterfaceIsDual)> _
Public Interface _Form
<DispId(10)> _
Sub ShowForm(ByVal sCN As String, ByVal sGUID As String)
<DispId(20)> _
Event ShutDownForm()
End Interface

<GuidAttribute("10000000-3371-0000-AF8A-AFFECC1B0967"),
InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)> _
Public Interface MAPIFormEvents
Sub ShutdownForm()
End Interface

<GuidAttribute("30000000-3371-0000-AF8A-AFFECC1B0967"),
ClassInterface(ClassInterfaceType.None),
ComSourceInterfaces(GetType(MAPIFormEvents))> _
Public Class Form
Implements _Form

Public Event ShutDownForm() Implements _Form.ShutDownForm

Private WithEvents oForm As New Form1

Public Sub ShowForm(ByVal sCN As String, ByVal sGUID As String)
Implements _Form.ShowForm
oForm.txtCON.Text = sCN
oForm.txtGUID.Text = sGUID
oForm.Show()
End Sub

Private Sub oForm_ShutDownForm() Handles oForm.ShutDownForm
RaiseEvent ShutDownForm()
End Sub

End Class
End Namespace
 
M

Michael Tissington

Oh, what a boo boo - i was looking at the wrong tlb, so each time I made
some changes the one I was importing was not getting changed - anyway thanks
for your efforts.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top