Re: ATL inheritance mistake
On 10 Dic, 14:33, Barzo <dba...@gmail.com> wrote:
Thanks a lot! It works!
Daniele.
Hi,
regarding this thread I have some trouble when I use my DLL with VB6.
To summarize I have the following IDL:
//////////////////////////////////////////////////////////////
[
object,
uuid(AB566C6C-AF54-11DE-B5BE-00A0D15E9B20),
oleautomation,
nonextensible,
helpstring("IAudioDevice Interface"),
pointer_default(unique)
]
interface IAudioDevice : IUnknown
{
.....
}
//-----------------------------------------------------------------------
[
object,
uuid(AB566C6E-AF54-11DE-B5BE-00A0D15E9B20),
dual,
oleautomation,
nonextensible,
helpstring("Dual interface for AudioRecorder objects"),
pointer_default(unique)
]
interface IAudioRecorder : IDispatch
{
....
}
//-----------------------------------------------------------------------
[
uuid(AB566C76-AF54-11DE-B5BE-00A0D15E9B20),
oleautomation,
nonextensible,
helpstring("IAudioDecoder Interface")
]
interface IAudioDecoder : IUnknown
{
[propget, id(40), helpstring("Returns a reference to a
IAudioRecorder interface.")]
HRESULT Recorder([out, retval] IAudioRecorder** pVal);
....
}
//-----------------------------------------------------------------------
library AxAudioLib4
{
[
uuid(AB566C74-AF54-11DE-B5BE-00A0D15E9B20),
helpstring("AudioRecorder Class")
]
coclass AudioRecorder
{
interface IAudioDevice;
[default] interface IAudioRecorder;
[default, source] dispinterface _IAudioRecorderEvents;
};
//-----------------------------------------------------------------------
[
uuid(AB566C77-AF54-11DE-B5BE-00A0D15E9B20),
helpstring("AudioDecoder Class")
]
coclass AudioDecoder
{
interface IAudioDevice;
interface IAudioRecorder;
[default] interface IAudioDecoder;
[default, source] dispinterface _IAudioDecoderEvents;
};
}
//////////////////////////////////////////////////////////////
The get_Recorder method of IAudioDecoder is:
STDMETHODIMP CAudioDecoder::get_Recorder(IAudioRecorder** pVal)
{
if (pVal) {
return this->QueryInterface(IID_IAudioRecorder,
reinterpret_cast<void**>(pVal));
}
else
return E_POINTER;
};
Now, in my VB6 code I use an EventCollection to store objects.
If I wrote this:
Dim Recorder As IAudioRecorder
Set Recorder = New AxAudioLib4.AudioRecorder
RecColl.Add Recorder, "KEY"
It works with no problem, but if I do this:
Dim withevents Decoder As AudioDecoder
Dim Recorder As IAudioRecorder
Set Decoder = New AxAudioLib4.AudioDecoder
Set Recorder = Decoder.Recorder
RecColl.Add Recorder, "KEY"
Debug.Print RecColl("KEY").object is Nothing
I get an error "Type mismatch" reading the "object" property.
This property is implemented like:
Public Property Get Object() As Object
Set Object = m_oObject
End Property
where m_oObject is an olelib.IUnknown and is created in the
RecColl.Add method:
Public Sub Add( _
Item As Object, _
Optional SourceIID As String, _
Optional Key As Variant)
Dim oObjectInfo As ObjectInfo
Dim oCPC As IConnectionPointContainer
Dim oEnm As IEnumConnectionPoints
Dim oCP As IConnectionPoint
Dim oUnk As olelib.IUnknown
Dim tIID As olelib.UUID
Dim lCookie As Long
' Get the IConnectionPointContainer interface
Set oCPC = Item
If LenB(SourceIID) = 0 Then
' Get connection point enumerator
Set oEnm = oCPC.EnumConnectionPoints
' Get the first connection point
oEnm.Next 1, oCP
' Get the IID
oCP.GetConnectionInterface tIID
Else
' Convert from string to UUID
olelib.CLSIDFromString SourceIID, tIID
' Get the connection point
Set oCP = oCPC.FindConnectionPoint(tIID)
End If
' Create the ObjectInfo object
Set oObjectInfo = New ObjectInfo
' Create the event sink object
Set oUnk = CreateEventSinkObj(tIID, oObjectInfo, Me)
' Connect the sink object with
' the source object
lCookie = oCP.Advise(oUnk)
On Error GoTo Disconnect
' Add the object to the collection
m_oCollection.Add oObjectInfo, Key
' Initialize the ObjectInfo object
oObjectInfo.frInitialize Key, _
m_oCollection.Count, _
lCookie, _
Item, _
tIID
Exit Sub
Disconnect:
oCP.Unadvise lCookie
Err.Raise Err.Number, , Err.Description
End Sub
And where the CreateEventSinkObj function is:
Public Function CreateEventSinkObj( _
EventIID As olelib.UUID, _
ByVal ObjInfo As ObjectInfo, _
ByVal Coll As EventCollection) As Object
Dim lEventSinkPtr As Long
Dim lOldProt As Long
Dim EventSink As EventSinkData
With EventSink
' Set the initial reference count to 1
.RefCount = 1
' Save the ID of the events interface
.EventIID = EventIID
' Save a pointer to the parent collection
MoveMemory .EvntColl, Coll, 4&
' Store the object info
MoveMemory .ObjInf, ObjInfo, 4&
' Set the vtable
.lvtablePtr = VarPtr(vtable(0))
End With
' Allocate memory for the object
lEventSinkPtr = GlobalAlloc(GPTR, LenB(EventSink))
If lEventSinkPtr Then
' Copy the structure to the allocated memory
MoveMemory ByVal lEventSinkPtr, EventSink, LenB(EventSink)
' Copy the pointer to the return value
MoveMemory CreateEventSinkObj, lEventSinkPtr, 4
Else
' Raise the error
Err.Raise 7, "CreateEventSinkObj"
End If
End Function
Could someone help me?
Tnx,
Daniele.