ATL控件(不用MFC),除CoClass之外,想把其他的自动化接口也添加到到ScriptEngine的NamedItem。
问题是: 我的GetItemInfo函数该怎么写才能支持多个自动化接口呢?怎么取得其他自动化接口的
UnKnow指针和TypeInfo指针?

解决方案 »

  1.   

    将所有的支持自动化的对象保存在一个map 里:
    typedef  std::map<std::string, CCmdTarget*, LessNoCase<std::string> >  MAP_OBJECT;  
    class CServerScript : public CScriptEngine  
    {
    public:
    CServerScript();
    virtual ~CServerScript();
    virtual HRESULT OnGetItemInfo(
    /* [in] */ LPCOLESTR pstrName,
    /* [in] */ DWORD dwReturnMask,
    /* [out]*/ IUnknown** ppUnknownItem,
    /* [out]*/ ITypeInfo** ppTypeInfo); virtual void OnScriptErrorEx(long nLine, long nChar, LPCTSTR lpszSource, LPCTSTR lpszDecs); virtual HRESULT OnGetWindow(HWND* phWnd); void AddObject(LPCTSTR name, CCmdTarget* pObj);
    BOOL RemoveObject(LPCTSTR name);
    MAP_OBJECT   m_mapObject;
    };///////////////////////////////////////////////////////////////////////////////////void CServerScript::AddObject(LPCTSTR name, CCmdTarget* pObj)
    {
    ASSERT_VALID(pObj);
    ASSERT_KINDOF(CCmdTarget, pObj);
    m_mapObject[std::string(name)] = pObj;
    }BOOL CServerScript::RemoveObject(LPCTSTR name)
    {
    MAP_OBJECT::iterator it = m_mapObject.find(name);
    if(it == m_mapObject.end()) return FALSE;
    m_mapObject.erase(it);
    return TRUE;
    }HRESULT CServerScript::OnGetItemInfo(LPCOLESTR pstrName, DWORD dwReturnMask, IUnknown** ppUnknownItem, ITypeInfo** ppTypeInfo)
    {
    HRESULT  hr = S_OK;
    if(ppUnknownItem)
    *ppUnknownItem = 0;
    if(ppTypeInfo)
    *ppTypeInfo = 0; USES_CONVERSION;
    MAP_OBJECT::iterator  it = m_mapObject.find(OLE2CA(pstrName));
    if(it != m_mapObject.end())
    {
    CCmdTarget*  pObject = it->second;
    LPUNKNOWN  pUnk = NULL;
    if(pObject->IsKindOf(RUNTIME_CLASS(CCmdTargetPlug)))
    pUnk = pObject->GetIDispatch(TRUE);
    else if(pObject->IsKindOf(RUNTIME_CLASS(CWnd)))
    pUnk = ((CWnd*)pObject)->GetControlUnknown();
    else
    pUnk = pObject->GetIDispatch(TRUE); ASSERT(pUnk != 0);
    if(dwReturnMask & SCRIPTINFO_IUNKNOWN)
    {
    *ppUnknownItem = pUnk;
    pUnk->AddRef();
    } if(dwReturnMask & SCRIPTINFO_ITYPEINFO)
    {
    IProvideClassInfo *pci = NULL;
    hr = pUnk->QueryInterface(IID_IProvideClassInfo, (void**)&pci);
    if (SUCCEEDED(hr) && pci) {
    hr = pci->GetClassInfo(ppTypeInfo);
    pci->Release();
    }

    if (FAILED(hr))
    {
    pUnk->Release();
    return E_FAIL;
    }
    } pUnk->Release();
    }
    else
    {
    hr = E_NOINTERFACE;
    } return hr;
    }
      

  2.   

    非常感谢 krh2001(边城浪子)的思路,不过,不使用MFC怎么取得其他自动化接口的IUnKnow指针? pObject->GetIDispatch 好像是MFC才能使用。
      

  3.   

    嗯, 俺这个是用的MFC, 不使用 MFC 的话, 自然也不会是从 CCmdTarget 来派生了. 
    要创建一个支持 IDispatch 接口的对象
    在 ODL 文件 中定义 其dispatch 接口.生成一个ATL 对象,支持双接口. 选择实现你定义
      

  4.   

    其它的需要支持 Dispatch 接口的对象, 也跟其它ATL对象一样生成就行了, coclass也是要的. 没有就不好识别的. 因为脚本引擎需要加载对象的 类型库,才能调用它的方法,连接到对象的事件源.用向导生成 ATL 对象, 选择支持双接口,如果要发送事件到脚本引擎,就选择支持连接点. 然后就可以被加载到 脚本引擎内了
      

  5.   

    krh2001(边城浪子) 。 我已经实现了其他的Dispatch 接口,请问是不是必须从coclass中生成这些对象的实例对象才能取得他们的IDispatch 接口指针。 不生成对象能通过queryinterface或者createinstance得到其IDispatch 接口指针吗? 感谢回答。
      

  6.   

    没有对象实例怎么取接口啊?  而且,在脚本引擎中.需要对象的类型库, 脚本是通过类型库访问Dispatch接口的. 
    [
       uuid(...)   // 类的CLSID . 这些都是必需的
    ]
    coclass MyObject
    {
      [default] interface IMyObject; 
      [default, source] interface IMyObjectEvent;
    };