Как удалить компоненту из сборки?

Автор Akew, 03.06.15, 19:07:57

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

Akew

Добрый вечер!

Требуется программно удалить компоненту из сборки. Делаю, вроде, все по учебнику, но удаления не происходит.
Я формирую массив компонент, и к компоненту, который хочу удалить, обращаюсь по его индексу.
Сообщений об ошибках не возникает, но компонента не удаляется.

Помогите, пожалуйста! Фрагмент кода прилагаю.

Спасибо
void DeleteComponent() {
CString title_dialog; title_dialog.Format( _T( "Функция %s" ), _T( "SelectComponent" ) ); // Заголовок окна сообщений функции
CString tmpstr;

ksDocument3DPtr document_3D = MyKompasObject->ActiveDocument3D();
if ( !document_3D ) {
MessageBox(NULL, _bstr_t( _T("*** интерфейс document_3D не получен. Выход.") ), title_dialog, MB_OK); return;
}

IKompasDocument3DPtr doc3D( IUnknownPtr( ksTransferInterface( document_3D, ksAPI7Dual, 0), false) );
if ( !doc3D ) {
MessageBox(NULL, _bstr_t( _T("*** интерфейс doc3D не получен. Выход.") ), title_dialog, MB_OK); return;
}

IPart7Ptr topPart7 = doc3D->TopPart;
if ( !topPart7 ) {
MessageBox(NULL, _bstr_t( _T( "*** интерфейс IPart7Ptr не получен. Выход." ) ), title_dialog, MB_OK); return;
}

// Выйти на вставленные в сборку компоненты
_variant_t uniqueParts( topPart7->PartsEx[ ( long )ksAllParts ] );
if ( ! ( uniqueParts.vt == ( VT_ARRAY | VT_DISPATCH ) ) ) return;

int count = uniqueParts.parray->rgsabound[0].cElements - uniqueParts.parray->rgsabound[0].lLbound;

tmpstr.Format( _T("count = %ld"), count );
MessageBox(NULL, tmpstr, title_dialog, MB_OK);

if ( uniqueParts.parray->cDims != 1 ) return;

LPDISPATCH HUGEP *pvar;
HRESULT hr = ::SafeArrayAccessData( uniqueParts.parray, (void HUGEP* FAR*)&pvar);
if ( ! ( !FAILED( hr ) && pvar ) ) return;

long count_components = 0;

// Сосчитать компоненты
for ( int i = 0; i < count; i++ ) {
IPart7Ptr obj( pvar[i] );
if ( !( obj ) ) continue;
if( obj->GetDetail() ) continue;

++count_components;
}

tmpstr.Format( _T("Всего %ld компонент"), count_components );
MessageBox(NULL, tmpstr, title_dialog, MB_OK);

// Сохранить номера компонент
long *num_components = new long[ count_components ];
long i_c = 0;
for ( int i = 0; i < count; i++ ) {
IPart7Ptr obj( pvar[i] );
if ( !( obj ) ) continue;
if( obj->GetDetail() ) continue;

num_components[ i_c++ ] = i;
}

// Показать отобранные компоненты (индекс, название, имя файла)
for ( int i = 0; i < count_components; i++ ) {
IPart7Ptr obj( pvar[ num_components[i] ] );
if ( !( obj ) ) continue;
if( obj->GetDetail() ) continue;

tmpstr.Format( _T("%ld. Компонента № %ld:\nИмя: %s\nФайл: %s"),
i+1, num_components[ i ], (LPWSTR)obj->GetName(), (LPWSTR)obj->GetFileName()
);
MessageBox(NULL, tmpstr, title_dialog, MB_OK);
}

// Удалить компоненту с индексом num_components[ i ] - пока не работает...
i = 0; // Указываем индекс массива с номером компоненты, которую нужно удалить (для i=0 это первый компонент в сборке)
IPart7Ptr obj( pvar[ num_components[i] ] ); // Объект (компонент), который требуется удалить
if ( obj ) {
if( ! obj->GetDetail() ) { // Объект существует и не деталь

if( ! document_3D->DeleteObject( obj ) ) {
tmpstr.Format( _T("*** не удалось удалить компоненту № %ld (%s)"),
num_components[ i ], (LPWSTR)obj->GetName()
);
} else {
tmpstr.Format( _T("Компонента № %ld (%s) УДАЛЕНА"),
num_components[ i ], (LPWSTR)obj->GetName()
);
}
MessageBox(NULL, tmpstr, title_dialog, MB_OK);
}
}

return;
}

Попробуйте через интерфейс IFeature7, если работаете через API7.

У Вас - document_3D->DeleteObject( obj )
т.к. document_3D=ksDocument3D то obj должен быть = IDispatch полученный методом ksEntity.GetDefinition от удаляемого объекта, имеющего тип из перечисления - ksObj3dTypeEnum.

Akew

Понял, разобрался, - спасибо!

Работающий исходник здесь:http://forum.ascon.ru/index.php/topic,5841.new.html#new.