0

VB6 プログラムからアクセスできる VC6 経由でオブジェクトのコレクションを実装しようとしています。私はそれをまとめることができませんでした。

_CopyVariantFromAdaptItf と _CopyItfFromAdaptItf (「ATL 内部」から) を定義しました。コレクション定義で使用する私の定義は次のとおりです。

#define CComEnumVariantOnListOfItemInterface(ItemInterface) \
    CComEnumOnSTL<IEnumVARIANT, &IID_IEnumVARIANT, VARIANT,_CopyVariantFromAdaptItf<ItemInterface>,vector< CAdapt< CComPtr<ItemInterface> > > >

#define ClassInterfaceCollImpl(ContainerInterface,ItemInterface) \
    ICollectionOnSTLImpl< IDispatchImpl< ContainerInterface, &__uuidof(ContainerInterface) >,\
    vector< CAdapt< CComPtr<ItemInterface> > >,ItemInterface*,_CopyItfFromAdaptItf<ItemInterface>,\
    CComEnumVariantOnListOfItemInterface(ItemInterface) >

#define ContainerInterface      IFields
#define ContainerClass          CFields
#define ContainerClsid          CLSID_Fields
#define ItemInterface           IField
#define DllRegID                IDR_FIELDS

typedef std::vector< CAdapt< CComPtr<ItemInterface> > > ContainerType;

そして、これはコンテナー クラスのプリアンブルです。

class ATL_NO_VTABLE ContainerClass : 
    public ClassInterfaceCollImpl(ContainerInterface,ItemInterface),
    public ISupportErrorInfo,
    public CComObjectRoot,
    public CComCoClass<ContainerClass,&ContainerClsid>
{
public:
    ContainerClass();
BEGIN_COM_MAP(ContainerClass)
    COM_INTERFACE_ENTRY(IDispatch)
    COM_INTERFACE_ENTRY(ContainerInterface)
    COM_INTERFACE_ENTRY(ISupportErrorInfo)
END_COM_MAP()
//DECLARE_NOT_AGGREGATABLE(CFields) 
// Remove the comment from the line above if you don't want your object to 
// support aggregation. 

DECLARE_REGISTRY_RESOURCEID(DllRegID)
// ISupportsErrorInfo
    STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);

// IFields
private:
    int GetIndex( BSTR name );

等....

私が試みた実装では、含まれているオブジェクトをスキャンして、オブジェクトの関数 pName() でアクセスされる一致する名前を探しています。私が試した2つの異なるアプローチを示していることに注意してください。

int CFields::GetIndex( BSTR name )
{

    long count = 0;
#if (1)
    Count(&count);
    for (unsigned int i=0; i<count; i++)
        if (wcscmp( name, m_coll.m_T->pName())
            return (i);
#else
    std::vector<CAdapt<CComPtr<IField> > >::iterator itr;
        for (itr = m_coll.begin(); itr != m_coll.end(); itr++)
            if (wcscmp( name, itr->m_T->pName()))
                count++;
            else
                return (count);

#endif
    throw E_INVALIDARG_13;
}

#if (1) を試すと、m_T が「vector<...」のメンバーではないというエラーが表示されます。m_coll->m_T を試すと、"vector<..." に -> がオーバーロードされていないというエラーが表示されます。#if (0) を試すと、pName() が '_NoAddRefReleaseOnCComPtr のメンバーではないというエラーが表示されます

あなたが私に与えることができる助けを前もって感謝します!

ヴァンス

4

1 に答える 1

0

私は自分自身に話していることを知っていますが、正しい答えに出くわした場合に備えて、他の誰かを助けたいと思っています.

OK、私は動作中のシステムを持っており、別の質問への回答に基づいていますオブジェクトのATLコレクションからオブジェクトポインターを取得する方法は? 、これが私が最終的に得たものです。次の行を追加しました。

COM_INTERFACE_ENTRY_IID(CLSID_Fields, CFields)

getItemObjectPtr が機能するように、BEGIN_COM_MAP(CFields) 行と END_COM_MAP() 行の間。

ItemInterface を IField に戻し、GetIndex メソッドを次のように変更しました。

    long count = 0;
    ContainerType::iterator itr;
for (itr = m_coll.begin(); itr != m_coll.end(); itr++)
    if (wcscmp( name, getItemObjectPtr( itr->m_T )->pName()) == 0)
        count++;
    else
        return (count);
    throw (HRESULT)E_INVALIDARG_13;

メソッド getItemObjectPtr は次のように定義されます。

CFields * CrecordSet::getItemObjectPtr( IFields *ppFields )
{
    CComQIPtr<CFields, &CLSID_Fields> pFields = ppFields;
    return (pFields);
}
于 2013-05-14T16:23:02.967 に答える