This is a particularily nasty error because of the way the IDE maps
external components through the vb6debug.dll and their current OCA -
thus due to the several layers of indirection it can be difficult to
isolate exactly what the IDE is complaining about.
But some suggestions:
Been awhile since I done the MFC COM model (perferring ATL myself) so
I can't be specific, but recheck your MFC component to make sure you
are not prematurely releasing it or otherwise doing anything too
creative when the state of the control is changing from 'running' back
to 'design'.
Make sure you are chewing on the animal you think you are.
Clean-up both projects.
Delete any .OCAs (VB will recreate as needed)
Make sure you have only one compiled component (*below).
Do a Registry Clean.
Make sure you have only one Registry entry and it points to the
correct component.
Reset the VB Project Reference/Components to that component.
Run a Dependency Walker to make sure it isn't perhaps another
component that is mis-matched.
* You can have several Registry entries, eg. a debug OCX and a release
OCX, but make sure your VB Reference/Components is pointing to the
correct component and that that component does exist. If you are using
this scenario insure the filesnames and Prog/App IDs are also unique -
not an issue with VC++ but can be with VB.
hth
-ralph
> We are all over this problem, focused how to fix it. I have used
>"fix"
> 'cause this entire situation is not present on VC++ and VB.Net version of the
> exactly same ocx.
> For giving a bit more details we are now focused on the analysis of the memory
> during the execution of the ocx ( important note on this control is its
> dimension, about 5 megabytes ). Some exceptions are founded about the way we
> close some windows, but we trust is something else that make the mentioned
>error
> ( We trust otherwise the correct execution on VC++ and B.Net is not
> explainable).
>
It is not uncommon for this to be the case for owner controls written
with other languages or frameworks. In fact I should probably say
*very common*.
[Note: I was a VC/VC++ programmer long before I dabbled in VB. So I
can understand a certain amount of superior thinking when experienced
with a "real" programming language and then having to work with ...
Ugh! ... VB! Been there, done that. However such feelings are
dangerous and will only lead to trouble. And here is why ...
<g>]
First off, appreciate that the 'basic rules' for how an ActiveX
Control should behave with a client came from the orginal VB product,
and mostly by adopting convenient conventions - ie, not from any
high-level scholarly brain-tank.
Therefore while us 'real' programmers know of multiple ways to manage
a COM component and COM interfaces, VB knows of only one (or rather
variations of a single theme).
Second, VB conveniently hides most of COM/OLE away from the User by
Design. Just like its Form Engine hides away the details of creating
windows, setting up WinProcs, etc. Therefore, a control must behave
as VB expects. If not, there is very little adjustment that can be
made on the VB side of things. Nor very little that can be done on the
control side to *force* VB to do something different.
Thus what VB wants is what VB needs to get. Or, to put it another way,
VB's management of ActiveX controls is THE defacto standard. No matter
if us 'real' COM programmers know a better way.
In the old days, it was common to create a "ransom note" VB
application to test our VC++ ActiveX COM components. Essentially a
blank VB app to plop the control on top of and test. If it worked
there it was good to go. We often did this before the actual object
code was written - just stubs.
The most common area where third-party controls go wrong is with
Interfaces and Interface Inheritance. By rule any published interface
can be derived from another. When working with a VC++ client we can
directly manipulate by simple casts/conversions/offsets etc. to get
any animal we need, or equally be assured we are dealing with the
correct animal. And as already noted - with raw COM - there is always
more than one way to get a result. VB on the other hand doesn't have a
facility for doing that - Interfaces are derived by its own built-in
coercion rules.
Also a common mistake is to pass non-VB OLE datatypes, or worse to
some MFC one. VC++/MFC and .Net have access to a greater variety than
VB does.
Thus, yes an ActiveX component build with MFC will work just fine with
a MFC client, because you had a programmer familar with both sides
writing it. Any problems and the programmer "fixes" it on the spot.
[Oops said derived above - meant it in its de-reference sense, but you
get the idea.]
Based on the error I highly doubt you will find any mysterious memory
or other internal issues with your component. The problem will be
found in how your component is presenting itself and an unexpected
(from VB's point of view) change in who VB thinks he is talking to
when you change from 'run-time' to 'design-time'. (Look carefully at
any aliasing or clever pointer handling.)
It has been ten years since I've worked with the MFC model for ActiveX
controls, but I vaguely remember it had a few Gotchas. They were IIRC
mostly concerned with Automation which should not be an issue in your
scenario. But ... ?
I've always preferred ATL. ATL has the advantage of direct
class/object templates for creating ActiveX components and Interfaces
classes VB and VBA expect to see. The MFC classes for the same support
is more of a bolt-on after-thought.
The actual Interface portion of your control is (or should be) rather
straight-forward, and like all COM components essentially separate
from the co-classes that support it. If you can't find the problem -
you might consider simply creating a ATL component with the published
interface (and stubbed objects beneath) and test it with a VB/VBA
applications. If it works - it would be a simple process to migrate
your MFC objects over.
Whew! Sorry I'm so windy.
Hth
-ralph
>
> By the way, while investigating this issue, I found
> some memory leaking and (maybe) occasional heap corruption.
> Though these seem not too damaging, judging from the
> acceptable stability of our C++ containers, I intend to
> get rid of them as soon as possible. Are you aware of
> any good, possibily open-source, tool to track this kind
> of problems in a Visual C environment ? In the very remote
> past I bought a commercial library (MemCheck) which seems
> gone by now.
>
I'm going back through my notes and the dusty drafting parts of my
memory to see if I can remember anything that might help with that
error.
As for Memory Leaks - I'm in the same boat. (Ghod I miss NuMega. <g>)
I've tried a few commercial products ($$$+) but have found that using
C++ built-in debug memory methods,
http://www.codeguru.com/forum/showthread.php?t=312742), WinDbg, and
then grinding it out one damn line/block at a time is the only thing
that seems to work in the end. <g>
-ralph
Still chewing ...
In the meantime take a look at this
http://edndoc.esri.com/arcobjects/9.0/ArcGISDevHelp/DevelopmentEnvs/COM%5CVB6%5CVBEnvGeneral.htm#Working_With_HRESULTs
(Tried to find a better site, but this will give you a clue on the
basics.)
Scroll down to "Working With HRESULTS".
This is not referring to the same problem (you are not writting in
VB), but the point is VB is catching an COM error and passing it on,
but hiding the actual HRESULT - letting you know only that it is
annoyed.
You might do the same with your OCX, log or raise what might be
"minor" errors. For example, in VC++/.Net we have the luxury of
ignoring returns - VB doesn't.
[OR I may only be delusional. <g>]
Also it is apparent it is not the primary component interface that is
the problem - it lies with something lower.
hth
-ralph