Перейти к публикации

Компоненты сборки


hztp_serg

Рекомендованные сообщения

Пишу COM-обьект на MS VS2008 ATL-проект C++. Пытаюсь создать метод который возвращает имена всех компонентов сборки. Насколько я понимаю метод IGetChildren должен вернуть масив указателей на IComponent2, количество элементов которого должно быть равно GetChildrenCount, почему-то у меня количество элементов масива всегда равно 1.

Вот мой пример на основе Traverse Assembly Example (C++ COM):

STDMETHODIMP CSwApp::GetFeature(BSTR* bFatName)

{

	LPCONFIGURATION pConfiguration = NULL;

	LPCOMPONENT2 pRootComponent2 = NULL;



	pSwModel->IGetActiveConfiguration(&pConfiguration);

	pConfiguration->IGetRootComponent2(&pRootComponent2);

	

	CString MyString;

	long RecurseLevel = 0;

	TraverseChildren(RecurseLevel, &MyString, pRootComponent2);

	*bFatName = MyString.AllocSysString();



	return S_OK;

}

функция TraverseChildren:

int CSwApp::TraverseChildren(long RecurseLevel, CString* MyString, LPCOMPONENT2 pComponent)

{

int nChildren;

int i;

BSTR Name;

HRESULT hres = S_OK;

if (RecurseLevel == 0)

{

hres = pSwModel->GetTitle(&Name);

}

else

{

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);

if ( S_OK == hres && nChildren > 0)

{

LPCOMPONENT2* pChildren = new LPCOMPONENT2 [nChildren];

hres = pComponent->IGetChildren(pChildren);

if(S_OK == hres)

{

for ( i=0; i<nChildren; i++)

{

TraverseChildren(RecurseLevel, MyString, pChildren);

pChildren->Release();

}

}

delete [] pChildren;

}

RecurseLevel--;

return nChildren;

}

проект компилится нормально, проблема только вот в этом месте

hres = pComponent->IGetChildrenCount(&nChildren);

if ( S_OK == hres && nChildren > 0)

{

LPCOMPONENT2* pChildren = new LPCOMPONENT2 [nChildren];

hres = pComponent->IGetChildren(pChildren);

if(S_OK == hres)

{

for ( i=0; i<nChildren; i++)

{

TraverseChildren(RecurseLevel, MyString, pChildren);

pChildren->Release();

}

}

delete [] pChildren;

}

как мне получить масив указателей IComponent2 с количеством элементов равным nChildren?

Большое спасибо!

Ссылка на сообщение
Поделиться на других сайтах


как мне получить масив указателей IComponent2 с количеством элементов равным nChildren?

Большое спасибо!

По всей видимости, вы используете exe-файл. Похожая проблема у одного из участников форума была здесь: http://fsapr2000.ru/index.php?showtopic=2...st&p=247862
Ссылка на сообщение
Поделиться на других сайтах

По всей видимости, вы используете exe-файл

Что имеется в виду, использую exe-файл или dll? Я на VisualStudio2008 C++ создал ATL-проект с своими методами и функциями:

STDMETHODIMP CSwApp::ConnectToSW(long* lErrors)

{

// ConnectToSW - з’єднання з COM-об’єктом SW

HRESULT hr = pSwApp.CoCreateInstance(L"SldWorks.Application", NULL, CLSCTX_LOCAL_SERVER);

if (hr != S_OK)

{

*lErrors = -1L;

return hr;

}

else

{

*lErrors = 0L;

return S_OK;

}

}

STDMETHODIMP CSwApp::DisconnectFromSW(void)

{

// DisconnectFromSW - закріває COM-об’єкт SW

pSwApp->ExitApp();

return S_OK;

}

STDMETHODIMP CSwApp::OpenDoc(BSTR sFileName, long iDocumentTypes, long* lErrors)

{

// OpenDoc - відкриває документ SW

// sFileName - повний шлях до файла

// iDocumentTypes - тип документа SW

// lErrors - флаг помилки відкриття документа SW

CComBSTR sDefaultConfiguration(L"Default");

long lWarnings;

IModelDoc2* swModelAssembly;

HRESULT hr = S_FALSE;

hr = pSwApp->OpenDoc6(sFileName, iDocumentTypes, swOpenDocOptions_Silent,

sDefaultConfiguration, lErrors, &lWarnings, &swModelAssembly);

if (FAILED(hr))

{

return hr;

}

pSwModel = swModelAssembly;

return S_OK;

}

STDMETHODIMP CSwApp::CloseDoc(BSTR sFileName)

{

// CloseDoc - закриття документа SW

pSwApp->CloseDoc(sFileName);

return S_OK;

}

скомпилил этот проект получил COM-обьект в виде dll-файла. Потом этот COM-обьект я использую в VFP9.0 как прослойку между SolidWorks и VFP. Так что я использую exe-файл или dll?
Ссылка на сообщение
Поделиться на других сайтах

Сделал тестовый пример который должен определять имя каждой компоненты:

HRESULT hres;

CoInitialize(NULL);

CLSID clsid;

CLSIDFromProgID(L"SldWorks.Application", &clsid);

ISldWorks *swApp;

CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, __uuidof(ISldWorks), (void**)&swApp);

if(swApp == NULL)

{

::CoUninitialize();

return 1;

}

IModelDoc2 *swModel;

hres = swApp->get_IActiveDoc2(&swModel);

if(swModel == NULL)

return 1;

int nChildren;

BSTR Name;

IConfiguration *pConfiguration = NULL;

IComponent2 *pRootComponent2 = NULL;

swModel->IGetActiveConfiguration(&pConfiguration);

pConfiguration->IGetRootComponent2(&pRootComponent2);

pRootComponent2->IGetChildrenCount(&nChildren);

IComponent2 **swArrayChildren = new IComponent2*[nChildren];

ZeroMemory(swArrayChildren, nChildren * sizeof(Component2*));

pRootComponent2->IGetChildren(swArrayChildren);

for (int i = 0; i < nChildren; i++)

{

IComponent2 *swComponent = swArrayChildren;

swComponent->get_Name(&Name);

}

я использую dll, а не exe-файл, описание своего проекта я привёл выше, пример должен быть рабочий, но у меня в swArrayChildren только один элемент. Где собака зарыта? Как заставить его работать? Помогите пожалуйста. :surrender:
Ссылка на сообщение
Поделиться на других сайтах

Получить имена компонентов сборки мне удалось с помощью GetChildren :

STDMETHODIMP CSwApp::GetNames(BSTR* bFatName)

{

IConfiguration *pConfiguration = NULL;

IComponent2 *pRootComponent2 = NULL;

pSwModel->IGetActiveConfiguration(&pConfiguration);

pConfiguration->IGetRootComponent2(&pRootComponent2);

CString MyString;

long RecurseLevel = 0;

TraverseChildren(RecurseLevel, &MyString, pRootComponent2);

*bFatName = MyString.AllocSysString();

return S_OK;

}

функция TraverseChildren:

int CSwApp::TraverseChildren(long RecurseLevel, CString* MyString, IComponent2 *pComponent)

{

int nChildren;

int i;

BSTR Name;

HRESULT hres = S_OK;

if (RecurseLevel == 0)

{

hres = pSwModel->GetTitle(&Name);

}

else

{

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);

if ( S_OK == hres && nChildren > 0)

{

VARIANT vArrayChildren;

pComponent->GetChildren(&vArrayChildren);

SAFEARRAY *pSa = V_ARRAY(&vArrayChildren);

IDispatch **pChildren;

SafeArrayAccessData(pSa, (void**)&pChildren);

if(S_OK == hres)

{

for ( i=0; i<nChildren; i++)

{

IComponent2 *swComponent=NULL;

IDispatch *pDispatch = pChildren;

pDispatch->QueryInterface(&swComponent);

TraverseChildren(RecurseLevel, MyString, swComponent);

pChildren->Release();

}

}

SafeArrayUnaccessData(pSa);

SafeArrayDestroy(pSa);

}

RecurseLevel--;

return nChildren;

}

Так как задача стоит достать из сборки информацию для создания спецификации, то у меня есть ещё пару вопросов:

- как определить какое именно исполнение (детали или узла) должно заносится в спецификацию? SWR-спецификация показывает что в сборке 4 компоненты, а вышеприведеный пример даёт компонентов больше, я заметил что разница за счёт исполнений, тоесть среди множества исполнений мне нужно выбрать одно или может несколько, но те которые должны быть в спецификации;

- как определить количество конкретной детали или узла в сборке?

- свойства детали или узла как документа SW которые находятся в диалоговом окне Summary Information (Custom и Configuration Specific) я могу достать только после открытия документа или можtn просто имея указатель на IComponent2?

Большое спасибо!

Ссылка на сообщение
Поделиться на других сайтах

Может есть у кого опыт C++ получения информации из сборки для создания спецификации? Поделитесь пожалуйста, буду очень благодарен. Если есть реальный пример можно на e-mail hztp_serg ukr net. Зарание благодарен!

Ссылка на сообщение
Поделиться на других сайтах

Так как задача стоит достать из сборки информацию для создания спецификации, то у меня есть ещё пару вопросов:

- как определить какое именно исполнение (детали или узла) должно заносится в спецификацию? SWR-спецификация показывает что в сборке 4 компоненты, а вышеприведеный пример даёт компонентов больше, я заметил что разница за счёт исполнений, тоесть среди множества исполнений мне нужно выбрать одно или может несколько, но те которые должны быть в спецификации;

- как определить количество конкретной детали или узла в сборке?

- свойства детали или узла как документа SW которые находятся в диалоговом окне Summary Information (Custom и Configuration Specific) я могу достать только после открытия документа или можtn просто имея указатель на IComponent2?

Большое спасибо!

Все ниже сказанное, сугубо личное мнение. Я так работаю.

- Какая конфигурация детали должна быть в спецификации, определяет конструктор при создании сборки. Я придерживаюсь следующего. Если в сборке присутствуют детали разной конфигурации, то это отдельные компоненты спецификации. Есть правда исключения, например пружины с разными высотами. Я их включаю, в так называемый "список исключений". То есть разные конфигурации детали интерпретируются как, относящиеся к одной детали. Решаю это введением определенного свойства в свойства детали.

- Просто подсчитать програмно.

- Если открыта сборка, и компонент не погашен или не сокращенный то можно. Функцией status = Component2->IGetModelDoc ( &retval ) получаем указатель на объект ModelDoc2, а функцией status = ModelDocExtension->get_CustomPropertyManager ( ConfigName, &Retval ) получаем указатель на объект CustomPropertyManager и имеем доступ к свойствам и функциям для работы со свойствами модели.

И нескромный вопрос. А зачем VFP?

P.S. Указывайте версию SW. API разных версий SW отличаются (вводят новые интерфейсы, прекращают поддерживать функции и т.д.)

Ссылка на сообщение
Поделиться на других сайтах

И нескромный вопрос. А зачем VFP?

У нас есть свой софт, данные хранятся на сервере MS SQL, клиентские модули написаны на VFP. На сервре у нас хранится информация о составе изделий (что куда входит), маршрут, норма расхода материала и т.д. Руководство поставило задачу создать электронный архив конструкторско-технологической документации. Для конструкторский документов это как минимум:

-модель SW или документ AutoCAD

-документ СП

С документами AutoCAD проще один файл и всё. При сохранении модели SW, если это сборка, нужно сохранить в архиве не один файл а несколько, и не просто скопом, а последовательно что куда входит (таблица соответствий). Это мы уже получаем с помощью dll написаной на C++ которая обращается к API SW IComponent2.GetChildren() и передает данные софту VFP. Что касается СП, то было предложение что конструктора будут в полуручном режиме вбивать СП в нашем софте написаном на VFP. Часть конструкторов, которые работают с AutoCAD согласилась, конструктора которые работают с SW заявили что СП должна формироватся автоматом из модели, по принципу SWR-спецификации. По этому счас стоит задача из модели читать данные и формировать СП в нашем редакторе СП.

Заканчиваю написание обработки сохранения сборки SW, всех её компонентов и таблицы соответствий в заводском архиве. Дальше буду приступать к переносе данных о СП из модели в наш редакторе СП. В перспективе наверное придётся и обратную связ реализовывать.

Ссылка на сообщение
Поделиться на других сайтах

Присоединяйтесь к обсуждению

Вы можете опубликовать сообщение сейчас, а зарегистрироваться позже. Если у вас есть аккаунт, войдите в него для написания от своего имени.
Примечание: вашему сообщению потребуется утверждение модератора, прежде чем оно станет доступным.

Гость
Ответить в тему...

×   Вставлено в виде отформатированного текста.   Вставить в виде обычного текста

  Разрешено не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отобразить как ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставить изображения напрямую. Загрузите или вставьте изображения по ссылке.

  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу.

  • Сообщения

    • bubl leg
      Всем доброго, друзья! Может кто умного чего подскажет: надо в солиде сделать комплект из пары моделей и потом вывести так - чтобы они, при вставке в слайсер Cura (это я для FDM 3d печати заморачиваюсь) - вывелись строго в том же пространственном положении (например, как бутерброд, лежащие друг на друге, в том же положении, как и в солиде). Я как то так делал - но забыл...:-)   Зачем это надо: печатаю нижнюю модель, печать заканчивается. меняю цвет прутка, удаляю нижнюю деталь, загружаю верхнюю и печатаю её. У меня как то давно так получалось вывести, что модель можно было разгруппировать и удалить ненужное. Сейчас в .stl всегда экспортирую под печать - там не работает такое. Итак? ;-) Любым идеям буду рад!
    • Maik812
      чем открыл/сохронил? сделай сохранить копию.
    • gudstartup
    • Guhl
      Журнал "Огонёк" брать надо, у него бумага хорошая, плотная.
    • Viktor2004
      ну да. Поезд попался не реставрированный. Даже без биотуалета. До последнего момента думал что поеду один в купе. В последнюю секунду вбегает мужик с глазами как у рака. Бросил сумку и давай метаться от туалета к туалету. Но нет. Санитарная зона. А ему очень плохо. Говорю ему, Ладно. Давай этот журнал раскладывай на полу, закрывай дверь и делай свое дело. Потом свернешь в окно выкинешь. Его аж трясет бедного. Закрыли дверь, он расположился, я отвернулся, отошел к окну, открыл его и закурил. Вдруг слышу сзади грозный упрек "Вообще-то в купе не курят!"  
    • gudstartup
      @Viktor2004 согласен. но человек сам хочет попробовать фанук на зуб.. с фирмой или китайцами всегда успеет связаться
    • Viktor2004
      ему надо искать фирму которая продаст FROM модуль к его станку. И ехать покупать вместе с ЧПУ что бы на месте проверить
    • gudstartup
      @Viktor2004 у автора по от 35i работает на 32i а собственный модуль фром неисправен и в м\сх флэш небольшая каша в данных так что ему придется искать другой фром модуль от 32i чтобы считать  рабочий   образ с нормальными данными.  
    • Viktor2004
      Я пробовал считывать так. Выпаял микросхему памяти из модуля, затем купил CF карту с таким же контроллером. Выпаял оттуда микросхему на 128Mb она была на месте "0" и впаял вместо нее микросхему с модуля. https://market.yandex.ru/product--karta-pamiati-cfg8b51mkazws-zaveb-tdk-512-mb/109304488?sku=102980643607&uniqueId=45170721&do-waremd5=G3-wTXG-Bm2zCvteY2KyaA&resale_goods=resale_resale&resale_goods_condition=resale_excellent Так как контроллеры совпадают, GBDriver RA8 программой WINHEX я снял образ с карты. Там уже все блоки были на своих местах. Только вряд ли вам это поможет. На 31i-A такое бы еще прокатило, а на 31i-B в системе появился файл SYS CNTL. Он генерится как на основе загружаемого софта, так и на основе ID-номера контроллера GBDriver. Так что побитно скопированная микросхема у меня работать не стала.
    • gudstartup
      @ДмитрийКм образ с плохого фром модуля у вас явно поврежден так что его на работоспособность можете не рассчитывать. надо считывать системные файлы с хорошего станка @ДмитрийКм если с хорошего 32i фром модуль не дадут то надо искать  файлы вашего по отдельно. но учитывая сложности с бэкапом системы у современных вряд ли они имеются в чистом виде.
×
×
  • Создать...