0

I am using a COM object in VB6. The COM object has a function Foo(Long, Long, Rect). Rect is a struct defined in the COM object implementation. My VB6 code (a button on a form) is like below:

Private Sub btnTestCom_Click()
    Set ComObj = CreateObject("ObjectName")
    Dim rect As DISPLAY_RECT

    rect.Left = 20
    rect.Top = 20

    ComObj.Foo(101, 0, rect) ' Error here
End Sub

At the last line it is giving me this compilation error: "Only user-defined types defined in public object modules can be coerced to or from a variant or passed to late-bound functions".

Other COM functions that do not have user-defined type parameters are working fine.

How do I solve this problem?

Thanks.

Charlie
  • 764
  • 2
  • 13
  • 24
  • Mitch, what do you mean? DISPLAY_RECT is a struct defined in the 3rd party COM library and I'm referencing to this library. – Charlie Aug 15 '11 at 01:52
  • 1
    The error message is saying that you're not. So does your code, you wouldn't have to use CreateObject() if you are referencing a COM type library. You must use the DISPLAY_RECT that came from the same type library as the one that declared "ObjectName". A different one with the same name cannot work, it will have a different guid. – Hans Passant Aug 15 '11 at 10:18
  • @Hans has a good point. Check which DISPLAY_RECT is being used. I've edited my answer to suggest one way to do that (search for DISPLAY_RECT in the object browser) – MarkJ Aug 15 '11 at 16:10
  • Hi @Hans, what do you mean by "you wouldn't have to use CreateObject() if you are referencing a COM type library"? I always used COM in VB6 like this: (1) add reference to the library (2) call obj = CreateObject(classname) (3) call obj.Foo(), obj.Bar() – Charlie Aug 16 '11 at 02:59
  • 1
    Then you've been always been doing it the wrong way. The point of adding a type library is that you don't have to use CreateObject(). You just use Dim obj As New Foo. No need for a type library if you use it late bound. – Hans Passant Aug 16 '11 at 03:12
  • @Charlie @Hans Hans is right. Late-binding (using `Dim obj As New Foo`) is much better. For example if you use late-binding, it will be easier to get this `ComObj.Foo` method call correct. The IDE will give you "IntelliSense" hints about the parameter types as you type, and the compiler will check whether you have got them correct. – MarkJ Aug 16 '11 at 08:35

2 Answers2

1

The function call is late-bound because your variable ComObj is not typed. You could try declaring it, something like

Dim ComObj As SomeObjectDefinedInComImplementation 

EDIT

I would also check that you are actually using the DISPLAY_RECT from the COM library. Open up the object browser (press F2) and search all libraries for DISPLAY_RECT.

  • If you only see one result, check whether it's from the correct COM library.
    • If it's from the correct COM library, there must be another problem.
    • If it's from the wrong COM library: check whether you actually have the correct library referenced (in project references). If you definitely do already have it referenced, double-check whether you really are supposed to pass a DISPLAY_RECT
  • If you see multiple results, VB6 may be picking up the wrong library. Try explicitly qualifying the DISPLAY_RECT with the name of the library Dim rect As TheCorrectLibraryName.DISPLAY_RECT
MarkJ
  • 30,070
  • 5
  • 68
  • 111
  • Beware that there are some odds that he'll only see the wrong one. – Hans Passant Aug 15 '11 at 16:20
  • Hi @MarkJ and Hans, sorry I did not make my problem clearer. DISPLAY_RECT is actully "XXX_DISPLAY_RECT". So it is the only correct one from the correct COM library. As MarkJ suggested, there must be another problem. Now I am going to try RS Conley's solution. I'll keep you guys updated. Thanks – Charlie Aug 16 '11 at 02:53
  • @Charlie You said this was a 3rd party library? In that case I don't think RS Conley's answer is appropriate. The library is expecting a specific type, you must pass the correct type as defined in the library. You can't just create a class of your own and pass that instead. This would be more appropriate if the library was your code, and you could change it too. – MarkJ Aug 16 '11 at 08:38
0

Assuming DISPLY_RECT is a type, you can't pass types into a public COM method or return a type from a public COM Function in VB6. You will have to make a class duplicating the type, and a helper function that takes the class as a parameter and returns the type.

RS Conley
  • 7,196
  • 1
  • 20
  • 37