views:

436

answers:

4

My MFC application using the "ESRI MapObjects LT2" ActiveX plugin throws an ASSERT at me when closing it. The error occurs in cmdtarg.cpp:

CCmdTarget::~CCmdTarget()
{
#ifndef _AFX_NO_OLE_SUPPORT
    if (m_xDispatch.m_vtbl != 0)
     ((COleDispatchImpl*)&m_xDispatch)->Disconnect();
    ASSERT(m_dwRef <= 1); //<--- Fails because m_dwRef is 3
#endif
    m_pModuleState = NULL;
}

I built the (native C++) application with VC9. When I compile the application with VC6, it behaves nicely.

What could be the reason for this?

+1  A: 

That looks like a reference count. Could this "target" be referenced by something else, something that's not releasing it?

Head Geek
D'oh! I just noticed the "reference-counter" tag on the question. Sorry. :-(
Head Geek
No problem.. I try to make all the relevant information easy to spot; didn't work here though, I guess...
mxp
+2  A: 

You can trace the Addref and Release calls defining _ATL_DEBUG_INTERFACES

from http://msdn.microsoft.com/en-us/library/sycfy8ec(VS.80).aspx

_ATL_DEBUG_INTERFACES

Define this macro before including any ATL header files to trace all AddRef and Release calls on your components' interfaces to the output window.

uvts_cvs
A: 

Using _ATL_DEBUG_INTERFACES did not yield any additional output... I defined it on the first line of stdafx.h, directly after #pragma once so I guess this is early enough.

Maybe the reason is how I am using the ActiveX control:
I'm not calling AddRef() or Release() by myself.
The MapObjects Installer comes with sample code with lots of wrapper classes which must have been generated by VC6 or something earlier.
I tried to generate wrapper classes myself with VC9 but there occured errors which I wasn't able to fix. I use the control by letting one of my windows have a member of type CMap1 (derived from CWnd), which is one of those generated wrapper classes. In CMyWnd::OnCreate() I also call CMap1::Create() and that's it, I'm finished: I can add a layer and the control displays a world map.
I have pretty much no idea what the reference-count stuff is about as I have not added or released any references. At least not knowingly...

The control is pretty old: The .OCX file has the year 2000 in its version information.
It's also not officially supported anymore but I don't have any substitue.

mxp
A: 

The following solved it for me: In the window that contains the control, add an OnDestroy() handler:

void CMyWnd::OnDestroy()
{
    // Apparently we have to disconnect the (ActiveX) Map control manually
    // with this undocumented method.
    COleControlSite* pSite = GetOleControlSite(MY_DIALOG_CONTROL_ID);
    if(NULL != pSite)
    {
        pSite->ExternalDisconnect();
    }

    CWnd::OnDestroy();
}
mxp