我测试IE刷新时调用顺序为:
~CComObject()->~A->DllGetClassObject()->A->CComObject();
A为控件类,但是我关闭时却没有调用析构函数,那位高手指点下为什么?这样造成的问题是,从IE窗口a,点击连接进入加载控件的窗口b,然后关掉b后,再点击a中的链接时,b加载的控件还没释放?
如果想在关掉b时释放掉b加载的控件(此时父窗口a还在),该如何处理,谢谢。本人刚接触控件这一块,深感activex控件和IE的机制之间的概念比较模糊,有没有高人给总结一下控件和IE之间的关系,比如,加载时调用控件哪些函数,刷新时调用控件哪些函数,ctrl+n时调用那些函数,关闭时调用控件哪些函数?非常感谢阿!

解决方案 »

  1.   

    在OnDestroy中进行处理,该释放的释放,该结束的结束
      

  2.   

    一楼DentistryDoctor说的“Release是否被正常的调用了”控件类没有重载这个方法,类定义见后,该如何来处理?
    需要重载这个方法吗?
    二楼zhucde说的“在OnDestroy中进行处理,该释放的释放,该结束的结束”没有这个方法啊,是ATL控件中的方法吗?要新增?能否讲一下关IE时,都进行了那些处理?谢谢两位,类定义如下:
    class ATL_NO_VTABLE CiSipCore : 
    public CComObjectRootEx<CComMultiThreadModel>,
    public CComCoClass<CiSipCore, &CLSID_iSipCore>,
    public ISupportErrorInfo,
    public IConnectionPointContainerImpl<CiSipCore>,
    public IDispatchImpl<IiSipCore, &IID_IiSipCore, &LIBID_SIPCORELib>,
    public CProxy_IiSipCoreEvents< CiSipCore >,
    public IProvideClassInfo2Impl<&CLSID_iSipCore, &DIID__IiSipCoreEvents>,
    public CComControl<CiSipCore>,
    public IOleControlImpl<CiSipCore>,
    public IOleObjectImpl<CiSipCore>,
    public IOleInPlaceActiveObjectImpl<CiSipCore>,
    public IViewObjectExImpl<CiSipCore>,
    public IOleInPlaceObjectWindowlessImpl<CiSipCore>

    {
    public:
    CiSipCore();
    ~CiSipCore();
    DECLARE_REGISTRY_RESOURCEID(IDR_ISIPCORE)DECLARE_PROTECT_FINAL_CONSTRUCT()BEGIN_COM_MAP(CiSipCore)
    COM_INTERFACE_ENTRY(IiSipCore)
    COM_INTERFACE_ENTRY(IDispatch)
    COM_INTERFACE_ENTRY(ISupportErrorInfo)
    COM_INTERFACE_ENTRY(IConnectionPointContainer)
    COM_INTERFACE_ENTRY_IMPL(IConnectionPointContainer) COM_INTERFACE_ENTRY(IProvideClassInfo)
    COM_INTERFACE_ENTRY(IProvideClassInfo2)
    COM_INTERFACE_ENTRY(IViewObjectEx)
    COM_INTERFACE_ENTRY(IViewObject2)
    COM_INTERFACE_ENTRY(IViewObject)
    COM_INTERFACE_ENTRY(IOleInPlaceObjectWindowless)
    COM_INTERFACE_ENTRY(IOleInPlaceObject)
    COM_INTERFACE_ENTRY2(IOleWindow, IOleInPlaceObjectWindowless)
    COM_INTERFACE_ENTRY(IOleInPlaceActiveObject)
    COM_INTERFACE_ENTRY(IOleControl)
    COM_INTERFACE_ENTRY(IOleObject)
    END_COM_MAP()
    BEGIN_CONNECTION_POINT_MAP(CiSipCore)
    CONNECTION_POINT_ENTRY(DIID__IiSipCoreEvents)
    END_CONNECTION_POINT_MAP()BEGIN_PROP_MAP(CiSipCore)
    //  PROP_ENTRY("Digits", 1, CLSID_NULL)
    END_PROP_MAP()
    BEGIN_CATEGORY_MAP(CiSipCore)
    IMPLEMENTED_CATEGORY(CATID_SafeForScripting)
    IMPLEMENTED_CATEGORY(CATID_SafeForInitializing)
    END_CATEGORY_MAP()BEGIN_MSG_MAP(CiSipCore)
    CHAIN_MSG_MAP(CComControl<CiSipCore>)
    DEFAULT_REFLECTION_HANDLER()
    END_MSG_MAP()// ISupportsErrorInfo
    STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);// IiSipCore
    /*接口方法及其他*/
    };
      

  3.   

    Handle IOleObject::OnClose and release your resource there.
      

  4.   

    see the source code of IOleControlImpl
      

  5.   

    蒋老大,看了IOleControlImpl的源码,IOleControl->IUnknown中有AddRef和Release。
    但我还是不明白我该怎么处理,在CiSipCore中没有调用或重载这些方法。另外没看到OnClose方法。IE关闭时会调用哪些函数阿?比如我在CiSipCore中的某个方法中创建了一个进程,在关IE时我想关掉这个进程,或者有一个信号变量,在CiSipCore的构造函数中初始化,关IE时需要将信号变量还原。加载控件时调用了构造函数,关闭时却没有调用,奇怪阿。刚接触这一块,请指点,谢谢。
    template <class T>
    class ATL_NO_VTABLE IOleControlImpl : public IOleControl
    {
    public:
    STDMETHOD(GetControlInfo)(LPCONTROLINFO /* pCI */)
    {
    ATLTRACENOTIMPL(_T("IOleControlImpl::GetControlInfo"));
    }
    STDMETHOD(OnMnemonic)(LPMSG /* pMsg */)
    {
    ATLTRACENOTIMPL(_T("IOleControlImpl::OnMnemonic"));
    }
    STDMETHOD(OnAmbientPropertyChange)(DISPID dispid)
    {
    dispid;
    ATLTRACE2(atlTraceControls,2,_T("IOleControlImpl::OnAmbientPropertyChange\n"));
    ATLTRACE2(atlTraceControls,2,_T(" -- DISPID = %d (%d)\n"), dispid);
    return S_OK;
    }
    STDMETHOD(FreezeEvents)(BOOL bFreeze)
    {
    T* pT = static_cast<T*>(this);
    ATLTRACE2(atlTraceControls,2,_T("IOleControlImpl::FreezeEvents\n"));
    if (bFreeze)
    pT->m_nFreezeEvents++;
    else
    pT->m_nFreezeEvents--;
    return S_OK;
    }
    };
      

  6.   

    跟踪发现关闭IE时,DllMain中执行了Release。
    但是这个函数是在构造函数执行前调用的,此时构造函数还没有执行,构造函数中的设置不能在这个函数中初始化,并且在关IE时来进行相关信号的还原吧?
    谢谢。
      

  7.   

    呜呜呜呜 谁来救救我啊测试发现,刷新时有时候调用了控件的析构函数,有时候没有调用。在没调用的时候,连着快速刷新两次(连按两下F5,即在第一次刷新还没有完成时再刷新第二次),从打的log看就又调用了。 后台跟踪发现,计数器不为0。
    这个计数器不是系统给封装起来自动实现的吗??
      

  8.   

    IOleObject::Close
    it should be IOleObjectImpl, sorry
      

  9.   

    进程内组建在IE里确实是这样,唯一的解决办法是将清理功能单独包装一个方法,并在IE脚本的window_onunload里调用