(изменено: Олег Бевз, 27 сентября 2010г. 09:24:01)

Тема: Работа с динамическими свойствами

Добрый день, только начал работать с динамическими свойствами в AutoCAD.
Возникло несколько вопросов:

1. Добавил к проекту DialogProperty. У класса есть функция:
STDMETHOD(GetCustomDialogProc)(OPMDIALOGPROC* pDialogProc) ;

Так и не понял что нужно возвращать. Порылся в хелпе, там сказано, что OPMDIALOGPROC используется для обозначения процедуры: typedef BOOL (*OPMDIALOGPROC)(void);

Хотел бы увидеть простенький пример возвращения процедуры с помощью OPMDIALOGPROC.

2.Никак не могу обратится к своим свойствам,через IPropertyManager. А хранить ссылки на свойства, как то не хочется.

Добавляю свойства к своему обьекту следующим образом:

//Получаем ссылку на мэнеджер динамических свойств данного макрообьекта
            CComPtr<IPropertyManager2> pPropManager = (IPropertyManager2*) GET_OPMPROPERTY_MANAGER(pMacro);
            //Инициализация библиотеки
            CoInitialize(NULL);
            //Создаем фабрику классов        
            CComPtr<IClassFactory> pClassFactory = NULL;
            CoGetClassObject(CLSID_EnumProperty,CLSCTX_INPROC_SERVER,NULL,IID_IClassFactory,(void **)&pClassFactory);
            //Если фабрика классов была создана
            if (pClassFactory)
            {
                //Получаем ссылку на необходимый интерфейс
                CComPtr<IEnumProperty> pEnumProperty = NULL;        
                pClassFactory->CreateInstance(NULL,IID_IEnumProperty,(void **)&pEnumProperty);
                //pEnumProperty->AddRef();
                //Если интерфейс был получен
                if (pEnumProperty)
                {                     _com_util::CheckError(pPropManager->AddProperty(pEnumProperty));
                }
            }
        }

Затем пытаюсь удалить их:

CComPtr<IPropertyManager2> pPropManager = (IPropertyManager2*)GET_OPMPROPERTY_MANAGER(pMacro);
            CComPtr<IUnknown> pDynamicProperty = NULL;
            BSTR s = SysAllocString((_bstr_t)_T("Сегменты"));
            pPropManager->GetDynamicPropertyByName(s,&pDynamicProperty);
            s = SysAllocString((_bstr_t)_T("Материал"));
            pPropManager->GetDynamicPropertyByName(s,&pDynamicProperty);
            long nPropertyCount = -1;
            pPropManager->GetDynamicPropertyCountEx(&nPropertyCount);
            for (long nPropertyIndex = 0;nPropertyIndex<nPropertyCount;nPropertyIndex++)
            {
                //CComPtr<IDynamicProperty> pDynamicProperty = NULL;
                pPropManager->GetDynamicProperty(nPropertyIndex,&pDynamicProperty);
                if (pDynamicProperty)
                {
                    pPropManager->RemoveProperty(pDynamicProperty);
                }
            }

При этом ни единого упоминания о существовании свойств функции класса IPropertyManager, не возвращают.
3.Возможно ли удалить стандартные свойства присвоенные макрообьекту ?

Re: Работа с динамическими свойствами

1. http://forums.autodesk.com/t5/Autodesk- … m-p/326487
3. Насколько мне известно этого сделать нельзя.

Re: Работа с динамическими свойствами

Большое спасибо, Александр.
Появился еще один вопрос.Динамическое свойство имеет следующие функции:
   
STDMETHOD(GetCurrentValueData)(IUnknown *pUnk, VARIANT* varData) ;
STDMETHOD(SetCurrentValueData)(IUnknown *pUnk, const VARIANT varData) ;

Использую ObjectARX 2010 и Visual Studio 2008.
Если ориентироватся на предыдущие версии Object Arx, то IUnknown *pUnk каким либо образом представляет AcDbObject или  AcDbObjectId.
Был бы благодарен за простенький пример извлечения из IUnkown  AcDbObjectId.
Или же здесь речь идет об интерфейсе выделенного обьекта? Как тогда из него можно получить AcDbObjectId?

(изменено: Александр Ривилис, 28 сентября 2010г. 13:07:36)

Re: Работа с динамическими свойствами

Где-то так:

STDMETHODIMP CMyProperty::GetCurrentValueData( LONG_PTR objectID, VARIANT* pVarData) 
{
    if (pVarData==NULL)
        return E_POINTER;
    AcDbObjectId id;  id.setFromOldId(objectID);
    // Тут твои действия
    return S_OK; 
}

(изменено: Олег Бевз, 28 сентября 2010г. 13:12:08)

Re: Работа с динамическими свойствами

Большое спасибо. Но в интерфейсе IDynamicProperty прописана команда:
STDMETHOD(GetCurrentValueData)(IUnknown *pUnk, VARIANT* varData) ;

То есть здесь речь идет о IUnknown *pUnk, а не LONG_PTR objectID.

Пробовал сделать нечто подобное и с IUnknown *pUnk  (id.setFromOldId(pUnk); ). Но безрезультатно...

Re: Работа с динамическими свойствами

Олег Бевз пишет:

Но в интерфейсе IDynamicProperty прописана команда

Не в IDynamicProperty, а в IDynamicProperty2
Попробуй так (не проверял):

STDMETHODIMP CMyProperty::GetCurrentValueData (IUnknown *pUnk, VARIANT *pVarData) {
  if ( pUnk == NULL )
    return (E_INVALIDARG) ;
  
  IAcadBaseObject *pObj = dynamic_cast<IAcadBaseObject *>(pUnk);
  if (NULL != pObj) {
    AcDbObjectId id;
    pObj->GetObjectId(&id);
    //
    // Тут твой код
    //
  }
}

Re: Работа с динамическими свойствами

Александр, большое спасибо за ваши ответы.
Возникла еще одна проблема...
При вызове диалога в методе
STDMETHOD(GetCustomDialogProc)(OPMDIALOGPROC* pDialogProc) ;
я вызываю MFC диалог, но функция DoModal() возвращает значение -1.

Во всех других случаях, когда диалог необходимо вызвать не на фоне окна свойств, все работает нормально.

Думаю, нужно каким либо образом инициализовать MFC при вызове функции GetCustomDialogProc().

Заранее спасибо.

(изменено: Александр Ривилис, 11 октября 2010г. 11:38:17)

Re: Работа с динамическими свойствами

Олег Бевз пишет:

я вызываю MFC диалог, но функция DoModal() возвращает значение -1.

Я правильно понял, что диалоговое окно даже не появляется? Если да, то с вероятностью 99% ты не переключил ресурсы на свое приложение.

HINSTANCE hInstPrev=AfxGetResourceHandle();
AfxSetResourceHandle(_hdllInstance);   
MyDialog dlg;
dlg.DoModal();   
AfxSetResourceHandle(hInstPrev);