Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Implements and CreateObject

Posted on 2000-03-03
9
Medium Priority
?
1,027 Views
Last Modified: 2008-02-26
I have written an ActiveX EXE that exports a IExtender class so I can write DLLs that extend my app later. This class declares a Run method (with empty body) that extensions will need to implement. During initialization, this app looks in the Registry for a specific key indicating what extensions are present and must be loaded. For each one, my app reads from the Registry their progid (Server.Class) in a strProgId variable and does a 'Set ext = CreateObject(strProgId)' to create the extension object and be able to later invoke its Run method. Notice that ext is declared 'Dim ext As IExtender'.

I have created am ActiveX DLL that has a MyExtension class that implements IExtender. I have registered it. My app detects it and reads its progid. The, the CreateObject fails because error 13, Type Mismatch.

MyExtension implements IExtender, so what's not working ok?.

Regards,
César.
0
Comment
Question by:CesarGon
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
9 Comments
 
LVL 3

Expert Comment

by:carruina
ID: 2581114
If you use CreateObject to make an instance of the IExtender you will write

Dim ext as IExtender
Set ext=CreateObject("MyExtension.IExtender")

There is other way to instanciate a class:

Dim ext as new IExtender

Now you don´t need use the CreateObject



0
 
LVL 3

Author Comment

by:CesarGon
ID: 2581215
I know, but:

- I cannot use CreateObject with "MyExtension.IExtender" because componen MyExtensions does not have an IExtender class. Its typelib does not has it so I will get an error if I try. COM won't event create the object.

- I cannot use "Dim ext As New IExtender" because that creates a IExtender object, and I want a MyExtension object. IExtender is an abstract interface (therefore it starts with an 'I') andis not intended to be instatiated.

The thing is: CreateObject works ok, and if I write

0
 
LVL 3

Author Comment

by:CesarGon
ID: 2581225
(sorry, I go on from the previous interrupted comment)

....if I write

Dim ext As Object
Set ext = CreateObject("MyExtension.ExtensionClass")

it works ok, but I cannot statically check that the object created implements the IExtender interface.

Any ideas?
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 1

Expert Comment

by:PatrickVD
ID: 2581474
CesarGon,

I quickly created a similar project in order to test exactly what you are trying to do (without the registry access, but hardcoding the ProgID in the )... In my case it worked perfectly! So you are doing nothing wrong, at least not architecturally speaking...

I don't think that the 'Type Mismatch' error is coming from the interface implementations ...
My best guess is that you probably have a type mismatch error which is caused during your Class_Initialize() of the ExtentionClass ! You must know that this WILL be executed whenever you try to access the implemented interface like you do in your 'Set ext = CreateObject("MyExtention.ExtentionClass")' statement.

Another possibility might be that you are not using the same version of the IExtend in the MyExtention dll... But I assume you are referencing the ActiveX EXE (project references setting) from within the MyExtention DLL ? And I hope you have the binary compatibility set in the ActiveX EXE also ? So this is less likely to be the problem....

I hope this will help you out !

Patrick.
0
 
LVL 1

Expert Comment

by:Misledman
ID: 2583017
It sounds to me like there is some reason why you don't want to get a reference to the EXE server. Is this correct? Otherwise, why would you want to be screwing around with prog ID's and such. I've never tried to get VB to reference a server with just progids and such so I have no idea what you are doing. However, I had the same problem problem you did recently. And it has to do with references. If you want to implement an interface from a server, you will definately have to have a refernece to the server from the project by which you want to use the server. In my case, I had three projects. I was referencing the actual EXE when I actually should have been referencing the VBP. I felt pretty stupid when I figured it out, but it is not hard to do when you have multiple projects involved.
0
 
LVL 3

Author Comment

by:CesarGon
ID: 2587639
PatrickVD, please re-post your comment as an answer so I can give you the points: in fact, the problem was with the binary compatibility of the EXE server.

I had project compatibility set, because is VB's default and I never care to think about that. What's really the difference?.

Thanks,
César.
0
 
LVL 1

Accepted Solution

by:
PatrickVD earned 1400 total points
ID: 2589018
Hi César,

Well, because you so kindly request it ..

<< Snippet of my previous comment >>
A possibility might be that you are not using the same version of the IExtend in the MyExtention dll... But I assume you are referencing the ActiveX EXE (project references setting) from within the MyExtention DLL ? And I hope you have the binary compatibility set in the ActiveX EXE also ?
<< End of snippet >>

I'm happy to see you finally managed to figure out what was going wrong !

As an extra...

The compatibility setting is something very important when it comes to releasing your components to the 'outside world'.
Actually, as you probably know, VB does a lot of things behind the scenes... Especially when it comes to COM object/components.
As a matter of fact, this compatibility setting has a direct impact on the way VB generates the UUID's for the classes (CLSID) and interface (IID).

NO COMPATIBILITY: In this situation, each time you compile your component, VB will generate NEW CLSIDs and IIDs for each public classmodule in your ActiveX component. When a client was already using it before, and you compile a new version, the client will not be able to use this new version. Nevertheless, in this mode the old version remains configured in the Registry, and if you kept the original DLL/EXE/OCX, the client will continue to work with the old version. The new version will never be usable unless you recompile the client application with a reference (Project-References) to the new version.

PROJECT COMPATIBILITY: By default VB sets itself into Project compatibility, which is not a bad thing when you are still developing the component before releasing it for usage by clients. Whenever you compile a new version with this compatibility mode, VB6 will keep the CLSIDs constant only, as long as you keep the classmodule methods and property prototypes constants. Nevertheless, for the IID, this is not the case. This is what might cause a problem with a client application, because in order to have a completely compatible component, both the CLSID and IIDs must remain constant !
There is still one advantage to this mode compared to 'No Compatibility': when you recompile, VB will UNREGISTER the previous version from the registry before registering the newly compiled version. Still, as far as the client applications are concerned, you will have to recompile with a reference to the new version (you will see the old one mentioned as 'MISSING' in Project-References).
[Sidebar: If you where using Project Compatibility in VB5, the both CLSID and IIDs would be generated. Only the advantage of un-registering the previous version would be usefull for this setting.]

BINARY COMPATIBILTY: This is actually the only right setting for a component if you want to expose it to the outside world, and guarantee compatibility with future versions of the component that you will build. In this situation, VB will keep both CLSIDs and IIDs constant for the existing classmodules (no new ones are created, unless you added a new class/interface). Additionally, VB will first perform a check to see that any modification you made might 'break' this compatibility with previous versions of the component... This also means that whenever you compile a new version of your component (as long as you respect the compatibility of your classmodules' properties/methods) you will NOT have to recompiled the older client applications for them to continue working. The new applications can use the newly added classmodules/interface in the new version, but old applications will continue working on the old interfaces.

How does this relate to your problem ? Quite simply, if you have project compatibility set, (In VB6) whenever you recompiled your ActiveX EXE, the CLSIDs where the same but not the IIDs. Since you 'implement INTERFACES (IIDs) and those are changing on each compile, you can now understand why you got the error. :-)

Hope this gives you a good idea about the compatibility settings.. If you want more info just let me know.

Patrick.



0
 
LVL 3

Author Comment

by:CesarGon
ID: 2590892
Great, Patrick. Are you giving seminars on VB & COM?
0
 
LVL 1

Expert Comment

by:PatrickVD
ID: 2590971
Hi César,

Thanks for accepting.

I'm not at all in the seminar business... I'm just another freelance developer on the market... who knows quite a lot on VB/COM/MTS/SQL7/etc...

Hope to see ya around !

Patrick.
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article is the result of a quest to better understand Task Scheduler 2.0 and all the newer objects available in vbscript in this version over  the limited options we had scripting in Task Scheduler 1.0.  As I started my journey of knowledge I f…
You can of course define an array to hold data that is of a particular type like an array of Strings to hold customer names or an array of Doubles to hold customer sales, but what do you do if you want to coordinate that data? This article describes…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…
Suggested Courses

636 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question