Com Interop and VB6 Collections


DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

Results 1 to 3 of 3

Thread: Com Interop and VB6 Collections

  1. #1
    Esmond Hart Guest

    Com Interop and VB6 Collections

    One of the goals of COM interopability is (to paraphrase slightly) 'that
    either the client or the server portion of existing applications can be
    upgraded to .NET independently without impacting the functionality of the
    application.'

    Bearing this in mind I created a simple VB6 client and server and after
    learning a bit about COM interop attributes was able to replace the
    VB6 server with a VB7 server. After running RegAsm.exe the VB6 client used
    the
    the VB7 server without any change whatever - certainly no need for a
    recompilation. Top marks for .NET developers!

    I had a lot more trouble with my second example where the VB6 server I was
    replacing used a VB6 collection; surely a very likely case in practice.
    Here is the code of my example server followed by the Form.Load method
    of the trivial client which will show 'Greetings from V6' in the
    labresult label of its only form. This in turn is followed by the IDL
    of V6Server.dll' s type library as displayed by oleview.exe

    -----------------------------------V6Server Create.cls
    Option Explicit

    Public Function Results() As Collection
    Dim col As New Collection
    col.Add "Greetings from V6"
    Set Results = col
    End Function


    ------------------------------------V6Client FClient.frm

    Private Sub Form_Load()
    Dim svr As New V6Server.Create
    Dim col As Collection
    Set col = svr.Results
    labResults = col(1)
    End Sub

    -------------------------------------IDL from V6Server.dll

    // Generated .IDL file (by the OLE/COM Object Viewer)
    //
    // typelib filename: V6Server.dll

    [
    uuid(AF929B74-60DA-4040-997C-4A953DDA5D68),
    version(1.0)
    ]
    library V6Server
    {
    // TLib : // TLib : OLE Automation :
    {00020430-0000-0000-C000-000000000046}
    importlib("stdole2.tlb");
    // TLib : Visual Basic For Applications :
    {000204EF-0000-0000-C000-000000000046}
    importlib("MSVBVM60.DLL");

    // Forward declare all types defined in this typelib
    interface _Create;

    [
    odl,
    uuid(5625567F-5568-4DC5-A010-6D22496B0E5F),
    version(1.0),
    hidden,
    dual,
    nonextensible,
    oleautomation
    ]
    interface _Create : IDispatch {
    [id(0x60030000)]
    HRESULT Results([out, retval] _Collection** );
    };

    [
    uuid(DD5C041B-73E8-467D-9E4D-F378E37B65F1),
    version(1.0)
    ]
    coclass Create {
    [default] interface _Create;
    };
    };
    --------------------------------------------------------------------------
    When I had got this far I realised that the V7 server project would need
    to make a COM reference to MSVBVM60.DLL ie VBA version 6. Here is the
    code that eventually succesfully replaced VB6Server.dll and, after RegAsm
    caused VB6Client to show the message 'Greetings from VB7' in its label.
    (Note how MSVBVM60.DLL has been imported as assembly VBA)

    -----------------------------------------------V7Server.dll
    <Assembly: System.Runtime.InteropServices.GUID _
    ("AF929B74-60DA-4040-997C-4A953DDA5D68")>
    Imports System.Runtime.InteropServices


    Interface <GUID("5625567F-5568-4DC5-A010-6D22496B0E5F")> _Create
    Function Results() As VBA._Collection
    End Interface

    Public Class <HasDefaultInterface(), _
    GUID("DD5C041B-73E8-467D-9E4D-F378E37B65F1")> Create
    Implements _Create
    Public Function Results() As VBA._Collection Implements _Create.Results
    Dim srv As New V7Helper.CMake() 'THIS IS LAME
    Dim col As VBA._Collection = srv.NewCol 'AND SO IS THIS
    col.Add("Greetings from V7")
    Return col
    End Function
    End Class

    ------------------------------------------------------------------------
    Now, really the two lines commented 'THIS IS LAME AND SO IS THIS' are
    subject of this note. There didn't seem to be anything strange about
    VBA.Collection as far as the browser was concerned and the compiler
    happily compiled
    Dim coln As New VBA.Collection()
    Dim col As VBA._Collection = CType(coln, VBA._Collection)
    which I would have liked to use in their place. However, when run, the
    first line suffers:

    System.Runtime.InteropServices.COMException: Class not registered

    but if you look for the CLSID in the registry it seems to be there OK:

    [HKEY_CLASSES_ROOT\CLSID\{A4C4671C-499F-101B-BB78-00AA00383CBB}\InprocServer
    32]
    "Class"="VBA.Collection"
    "Assembly"="VBA, Ver=6.0.0.0, Loc=\"\", SN=null"

    I've tried hacking the registry a bit to no avail so I gave up and wrote
    VSHelper.dll in VB6 then made it a COM reference.

    ---------------------------------------V7Helper.dll CMake.cls----------
    Public Function NewCol() As Collection
    Dim col As New Collection
    Set NewCol = col
    End Function
    ------------------------------------------------------------------------

    So the question I raise is 'Is there a better way of doing this?' or is
    there one planned for when VB7 ships?






  2. #2
    Atif Aziz Guest

    Re: Com Interop and VB6 Collections


    >I had a lot more trouble with my second example where the VB6 server I was
    >replacing used a VB6 collection; surely a very likely case in practice.


    If this is a common practice, then it's an unforunate one because Collection
    is a private class (just like App, Printer, Clipboard, Form, etc.) that you
    are not allowed to export/expose from public members of your ActiveX objects.
    The fact that VB does not explicitly warn against this is probably the cause
    of this practice, but the docs definitely warn against it.

  3. #3
    Esmond Hart Guest

    Re: Com Interop and VB6 Collections


    "Atif Aziz" <atifa@microsoft.com> wrote in message
    news:3a730944$1@news.devx.com...
    >
    > >I had a lot more trouble with my second example where the VB6 server I

    was
    > >replacing used a VB6 collection; surely a very likely case in practice.

    >
    > If this is a common practice, then it's an unforunate one because

    Collection
    > is a private class (just like App, Printer, Clipboard, Form, etc.) that

    you
    > are not allowed to export/expose from public members of your ActiveX

    objects.
    > The fact that VB does not explicitly warn against this is probably the

    cause
    > of this practice, but the docs definitely warn against it.


    Thanks for replying to my post. Here is an extract from the VB6
    documentation on
    The Jan 2001 MSDN Library

    __________________________________________________________________

    Visual Basic Concepts

    Data Types Allowed in Properties and Methods


    Classes can have properties and methods of any public data type supported by
    Automation. This includes all arguments of properties and methods, as well
    their return values. The allowed data types include:

    Public objects provided by another component, such as DAO or a component
    authored using Visual Basic.

    Public objects provided by Visual Basic for applications, such as the Error
    and Collection objects

    <some other allowable stuff snipped>
    __________________________________________________________________

    So this is a real problem. The private classes you refer to DO NOT include
    collections, but do included forms, and controls as indicated a little later
    in this
    documentation

    __________________________________________________________________
    On the Evils of Returning Private Objects

    The following data types are not allowed, and references to them should
    never be returned to client applications:

    All of the objects provided in the Visual Basic (VB) object library - for
    example, controls. Use the Object Browser to view the entire list.


    All forms.


    All class modules whose Instancing property is set to Private.
    ________________________________________________________________



Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center
 
 
FAQ
Latest Articles
Java
.NET
XML
Database
Enterprise
Questions? Contact us.
C++
Web Development
Wireless
Latest Tips
Open Source


   Development Centers

   -- Android Development Center
   -- Cloud Development Project Center
   -- HTML5 Development Center
   -- Windows Mobile Development Center