// SW_COM.h: объявление CSW_COM
#pragma once
#include "resource.h" // основные символы
#include "ProjSwCOM_i.h"
#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
#error ""
#endif
// CSW_COM
class ATL_NO_VTABLE CSW_COM :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CSW_COM, &CLSID_SW_COM>,
public ISupportErrorInfo,
public IDispatchImpl<ISW_COM, &IID_ISW_COM, &LIBID_ProjSwCOMLib, /*wMajor =*/ 1, /*wMinor =*/ 0>
{
public:
CSW_COM()
:m_bstrValue(CComBSTR()), m_variantValue(CComVariant())
{
}
DECLARE_REGISTRY_RESOURCEID(IDR_SW_COM)
BEGIN_COM_MAP(CSW_COM)
COM_INTERFACE_ENTRY(ISW_COM)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(ISupportErrorInfo)
END_COM_MAP()
// ISupportsErrorInfo
STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
.......
protected:
CComPtr<ISldWorks> pSwApp;
CComPtr<IModelDoc2> pSwModel;
CComPtr<IConfigurationManager> pSwCfgMgr;
CComPtr<IConfiguration> pSwCfg;
CComPtr<IFeature> pSwFeature;
CComPtr<IComponent2> pSwComponent;
CComBSTR m_bstrValue;
CComVariant m_variantValue;
public:
typedef CComPtr<IComponent2> LPCOMPONENT2;
STDMETHOD(ConnectToSW)(long* lErrors);
STDMETHOD(DisconnectFromSW)(void);
STDMETHOD(OpenDoc)(BSTR sFileName, long iDocumentTypes, long* lErrors);
STDMETHOD(CloseDoc)(BSTR sFileName);
STDMETHOD(GetCustomInfoCount)(long* lCount);
STDMETHOD(IGetCustomInfoList)(BSTR* pVal);
STDMETHOD(GetCustomInfoList)(VARIANT* pVal);
STDMETHOD(get_CustomInfo)(BSTR FieldName, BSTR* pVal);
STDMETHOD(GetMassProperties)(VARIANT* pVal);
STDMETHOD(TEST)(BSTR* pVal);
STDMETHOD(GetCustomInfoType)(BSTR FieldName, BSTR* pVal);
STDMETHOD(Configuration_GetParameters)(VARIANT* pParams, VARIANT* pValues);
STDMETHOD(GetFeature)(BSTR* bFatName);
int TraverseChildren(long RecurseLevel, CString* MyString, LPCOMPONENT2 pComponent);
};
Невозможно преобразовать параметр из 'CSW_COM::LPCOMPONENT2 **' в 'SldWorks::ICompone
struct __declspec(uuid("655d6f2a-5441-45d1-8cba-d35fb26988e4"))
IComponent2 : IDispatch
{
//
// Raw methods provided by interface
//
virtual HRESULT __stdcall GetChildren (
/*[out,retval]*/ VARIANT * Retval ) = 0;
virtual HRESULT __stdcall IGetChildren (
/*[out,retval]*/ struct IComponent2 * * Retval ) = 0;
.........
.........
}
при использовании функции IGetChildren, которая возвращает указатель на этот интерфейс:
typedef CComPtr<IComponent2> LPCOMPONENT2;
CComPtr<IComponent2> pComponent;
LPCOMPONENT2* pChildren = new LPCOMPONENT2 [10];
pSwCfg->IGetRootComponent2(&pComponent);
pComponent->IGetChildren(&pChildren);
получаю ошибку:
error C2664: SldWorks::IComponent2::IGetChildren: невозможно преобразовать параметр 1 из 'CSW_COM::LPCOMPONENT2 **' в 'SldWorks::IComponent2 **'
наверное я неверно определил синоним. Подскажите пожадуйста, как исправить ошибку?
Большое спасибо!
Чет на конфликт имен похоже, что за CSW_COM?
Цитата: Phodopus
Чет на конфликт имен похоже, что за CSW_COM?
Это мой класс в ATL-проекте
Код:
Код:
// SW_COM.cpp: реализация CSW_COM
#include "stdafx.h"
#include "SW_COM.h"
// CSW_COM
STDMETHODIMP CSW_COM::InterfaceSupportsErrorInfo(REFIID riid)
{
.......
return S_FALSE;
}
STDMETHODIMP CSW_COM::GetFeature(BSTR* bFatName)
{
int i;
int nChildren;
BSTR Name;
CString Tmp;
CString MyString;
LPCOMPONENT2* pChildren;
pSwModel->IGetActiveConfiguration(&pSwCfg);
pSwModel->GetTitle(&Name);
MyString = ' ';
Tmp = Name;
MyString += Tmp;
pSwCfg->IGetRootComponent2(&pSwComponent);
pSwComponent->IGetChildrenCount(&nChildren);
//pChildren = new LPCOMPONENT2 [nChildren];
pSwComponent->IGetChildren(&pChildren);
for ( i=0; i < nChildren; i++)
{
MyString += '\n';
::SysFreeString(Name);
Name = (BSTR)NULL;
pChildren[1]->GetPathName(&Name);
Tmp = Name;
MyString += Tmp;
}
//pRootComponent->IGetChildren(&pSwComponent);
//pSwComponent->GetPathName(bFatName);
//long RecurseLevel = 0;
//TraverseChildren(RecurseLevel, &MyString, pSwComponent);
*bFatName = MyString.AllocSysString();
return S_OK;
}
int CSW_COM::TraverseChildren(long RecurseLevel, CString* MyString, LPCOMPONENT2 pComponent)
{
BSTR Name;
HRESULT hres = S_OK;
if (RecurseLevel == 0)
{
hres = pSwModel->GetTitle(&Name);
}
else
{
hres = pComponent->get_Name(&Name);
}
RecurseLevel++;
int i;
int nChildren;
hres = pComponent->IGetChildrenCount(&nChildren);
if (hres = S_OK && nChildren > 0)
{
LPCOMPONENT2 pChildren;
hres = pComponent->IGetChildren(&pChildren);
if (hres = S_OK)
{
for ( i=0; i<nChildren; i++)
{
//TraverseChildren(RecurseLevel, MyString, pChildren)
//pChildren.Release;
}
}
delete [] pChildren;
}
return 0;
}
#include "stdafx.h"
#include "SW_COM.h"
// CSW_COM
STDMETHODIMP CSW_COM::InterfaceSupportsErrorInfo(REFIID riid)
{
.......
return S_FALSE;
}
STDMETHODIMP CSW_COM::GetFeature(BSTR* bFatName)
{
int i;
int nChildren;
BSTR Name;
CString Tmp;
CString MyString;
LPCOMPONENT2* pChildren;
pSwModel->IGetActiveConfiguration(&pSwCfg);
pSwModel->GetTitle(&Name);
MyString = ' ';
Tmp = Name;
MyString += Tmp;
pSwCfg->IGetRootComponent2(&pSwComponent);
pSwComponent->IGetChildrenCount(&nChildren);
//pChildren = new LPCOMPONENT2 [nChildren];
pSwComponent->IGetChildren(&pChildren);
for ( i=0; i < nChildren; i++)
{
MyString += '\n';
::SysFreeString(Name);
Name = (BSTR)NULL;
pChildren[1]->GetPathName(&Name);
Tmp = Name;
MyString += Tmp;
}
//pRootComponent->IGetChildren(&pSwComponent);
//pSwComponent->GetPathName(bFatName);
//long RecurseLevel = 0;
//TraverseChildren(RecurseLevel, &MyString, pSwComponent);
*bFatName = MyString.AllocSysString();
return S_OK;
}
int CSW_COM::TraverseChildren(long RecurseLevel, CString* MyString, LPCOMPONENT2 pComponent)
{
BSTR Name;
HRESULT hres = S_OK;
if (RecurseLevel == 0)
{
hres = pSwModel->GetTitle(&Name);
}
else
{
hres = pComponent->get_Name(&Name);
}
RecurseLevel++;
int i;
int nChildren;
hres = pComponent->IGetChildrenCount(&nChildren);
if (hres = S_OK && nChildren > 0)
{
LPCOMPONENT2 pChildren;
hres = pComponent->IGetChildren(&pChildren);
if (hres = S_OK)
{
for ( i=0; i<nChildren; i++)
{
//TraverseChildren(RecurseLevel, MyString, pChildren)
//pChildren.Release;
}
}
delete [] pChildren;
}
return 0;
}
Код:
LPCOMPONENT2* pChildren = new LPCOMPONENT2 [10];
обьявить переменную как:
Код:
CComPtr<IComponent2> pChildren;
то дальнейшее использование:
Код:
pSwComponent->IGetChildren(&pChildren);
for ( i=0; i < 10; i++)
{
pChildren.GetPathName(&Name);
}
for ( i=0; i < 10; i++)
{
pChildren.GetPathName(&Name);
}
успешно выполняется только при i=0, при i=1 уже получаем ошибку.
дак один объект нужен а не массив
Цитата: oxotnik333
дак один объект нужен а не массив
из описания IGetChildren видно что возвращается указатель на масив:
Код:
Syntax (COM)
status = Component2->IGetChildren ( &retval )
Output:
(LPCOMPONENT2*) retval
Pointer to an array of Component2 objects
Return:
(HRESULT) status
S_OK if successful
status = Component2->IGetChildren ( &retval )
Output:
(LPCOMPONENT2*) retval
Pointer to an array of Component2 objects
Return:
(HRESULT) status
S_OK if successful
в документации есть пример использования IGetChildren:
Код:
int TraverseChildren(long RecurseLevel, CString* MyString, LPCOMPONENT pComponent)
{
LPCOMPONENT* pChildren = NULL;
int nChildren;
int i;
BSTR Name;
HRESULT hres = S_OK;
LPMODELDOC pModelDoc = NULL;
// Retrieve the component name
if(RecurseLevel==0)
{
// Special case of top-level components
hres = m_pSldWorks->get_IActiveDoc( &pModelDoc );
if( S_OK == hres || pModelDoc != NULL )
hres = pModelDoc->GetTitle(&Name);
}
else
{
// Get the component name
hres = pComponent->get_Name(&Name);
}
if( S_OK == hres && Name != NULL )
{
CString tempstr;
for( i=1; I<=RecurseLevel; i++)
{
tempstr += " ";
}
CString Tmp(Name);
tempstr += Tmp;
tempstr += "\r\n";
*MyString = *MyString + tempstr;
}
RecurseLevel++;
hres = pComponent->IGetChildrenCount(&nChildren);
// Check if this component has children
if ( S_OK == hres || nChildren > 0 )
{
pChildren = new LPCOMPONENT [nChildren];
hres = pComponent->IGetChildren((LPCOMPONENT**)&pChildren);
if(S_OK == hres)
{
// Recursively traverse the children
for ( i=0; i<nChildren; i++ )
{
TraverseChildren(RecurseLevel,MyString,pChildren);
pChildren->Release();
}
}
delete [] pChildren;
}
RecurseLevel--;
return nChildren;
}
{
LPCOMPONENT* pChildren = NULL;
int nChildren;
int i;
BSTR Name;
HRESULT hres = S_OK;
LPMODELDOC pModelDoc = NULL;
// Retrieve the component name
if(RecurseLevel==0)
{
// Special case of top-level components
hres = m_pSldWorks->get_IActiveDoc( &pModelDoc );
if( S_OK == hres || pModelDoc != NULL )
hres = pModelDoc->GetTitle(&Name);
}
else
{
// Get the component name
hres = pComponent->get_Name(&Name);
}
if( S_OK == hres && Name != NULL )
{
CString tempstr;
for( i=1; I<=RecurseLevel; i++)
{
tempstr += " ";
}
CString Tmp(Name);
tempstr += Tmp;
tempstr += "\r\n";
*MyString = *MyString + tempstr;
}
RecurseLevel++;
hres = pComponent->IGetChildrenCount(&nChildren);
// Check if this component has children
if ( S_OK == hres || nChildren > 0 )
{
pChildren = new LPCOMPONENT [nChildren];
hres = pComponent->IGetChildren((LPCOMPONENT**)&pChildren);
if(S_OK == hres)
{
// Recursively traverse the children
for ( i=0; i<nChildren; i++ )
{
TraverseChildren(RecurseLevel,MyString,pChildren);
pChildren->Release();
}
}
delete [] pChildren;
}
RecurseLevel--;
return nChildren;
}
здесь используется синоним LPCOMPONENT. Чтобы пример работал синоним надо обьявить, я это сделал так так:
Код:
typedef CComPtr<IComponent2> LPCOMPONENT2;
в результате при выполнении примера получаю вышуприведенную мною ошибку. Обойтись без синонима, пробовал, тоже не получается.
Тыц для начала, а дальше там самостоятельно.
Кстати пример и описание явно от разных версий, в первой версии метод IGetChildren() зачем-то требует адрес указателя на массив! Разве что он сам этот массив и выделяет, иначе не вижу оправдания такой глупости.
Прекращайте тунеядство!
Кстати пример и описание явно от разных версий, в первой версии метод IGetChildren() зачем-то требует адрес указателя на массив! Разве что он сам этот массив и выделяет, иначе не вижу оправдания такой глупости.