Не-COM свойства со списком возможных значений
В Палитре свойств вы можете найти свойства, которые принимают только значения, которые перечислены для свойства. Если вы хотите создать такое свойство, тогда вам нужно создать новый перечисляемый тип и использовать его для создания нового AcRxValueType, который реализует интерфейс IAcRxEnumeration
Файл заголовка
C++ файл
- ////////////////////////////////////////////
- // MyEnumType
- ////////////////////////////////////////////
- void makeMyEnumTypeTemplateProperties(
- class AcRxMemberCollectionBuilder & collectionBuilder, void*);
- template<>
- int MyEnumTypeTemplate<MyEnum>::subToString(
- const void *instance, ACHAR *buffer, size_t sizeInACHARs,
- AcRxValueType::StringFormat format) const
- {
- const ACHAR* formatString = L"%d";
- MyEnum & value = *(MyEnum*)instance;
- if (buffer==NULL)
- return _scwprintf(formatString,value);
- return swprintf_s(buffer,sizeInACHARs,formatString,value);
- }
- template<>
- bool MyEnumTypeTemplate<MyEnum>::subEqualTo(
- const void *a, const void* b) const
- {
- MyEnum & v1 = *(MyEnum*)a;
- MyEnum & v2 = *(MyEnum*)b;
- return v1==v2;
- }
- template<>
- struct AcRxValueType::Desc< MyEnum >
- {
- __declspec(dllexport) static const AcRxValueType& value() throw();
- static void del();
- };
- MyEnumTypeTemplate<MyEnum>* s_pMyEnumTypeTemplate = NULL;
- const AcRxValueType& AcRxValueType::Desc< MyEnum >::value() throw()
- {
- if (s_pMyEnumTypeTemplate==NULL)
- {
- s_pMyEnumTypeTemplate = new MyEnumTypeTemplate<MyEnum>(
- L"MyEnumProperties",&makeMyEnumTypeTemplateProperties);
- AcRxEnumTag* pTag;
- pTag = new AcRxEnumTag (L"Один", (int)0);
- s_pMyEnumTypeTemplate->append(*pTag);
- pTag = new AcRxEnumTag (L"Два", (int)1);
- s_pMyEnumTypeTemplate->append(*pTag);
- pTag = new AcRxEnumTag (L"Три", (int)2);
- s_pMyEnumTypeTemplate->append(*pTag);
- pTag = new AcRxEnumTag (L"Четыре", (int)3);
- s_pMyEnumTypeTemplate->append(*pTag);
- }
- return *s_pMyEnumTypeTemplate;
- };
- // Это должно вызываться, когда тип значения больше не нужен
- // Лучшее место для вызова этого метода, когда модуль выгружается (On_kUnloadAppMsg)
- void AcRxValueType::Desc< MyEnum >::del()
- {
- if (s_pMyEnumTypeTemplate)
- {
- const ACHAR * name = s_pMyEnumTypeTemplate->name();
- if (acrxSysRegistry())
- acrxClassDictionary->remove(s_pMyEnumTypeTemplate->name());
- s_pMyEnumTypeTemplate = NULL;
- }
- };
- void makeMyEnumTypeTemplateProperties(
- class AcRxMemberCollectionBuilder & collectionBuilder, void*)
- {
- }
- ////////////////////////////////////////////
- // MyListProperty
- ////////////////////////////////////////////
- const ACHAR * MyListProperty::kCategoryName = _T("My Category");
- AcRxCategory * MyListProperty::category = NULL;
- MyListProperty::MyListProperty() :
- AcRxProperty(_T("My List Property"),
- AcRxValueType::Desc< MyEnum >::value())
- {
- if (category == NULL)
- {
- AcRxCategory * parent = AcRxCategory::rootCategory();
- category = parent->findDescendant(kCategoryName);
- if (category == NULL)
- category = new AcRxCategory(kCategoryName, parent);
- }
- // OPM = Object Property Manager / Property Palette (Палитра свойств)
- // Добавим атрибут в категорию OPM Положение, в которой он будет виден
- attributes().add(new AcRxUiPlacementAttribute(kCategoryName, 0));
- // Добавим этот атрибут так, чтобы AutoCAD автоматически создал
- // COM – обертку для этого свойства, т.е. он бы был виден в OPM
- attributes().add(new AcRxGenerateDynamicPropertiesAttribute());
- }
- MyListProperty::~MyListProperty()
- {
- }
- /// <summary>
- /// Этот метод вызывается системой для получения
- /// свойства для определенного объекта
- /// </summary>
- Acad::ErrorStatus MyListProperty::subGetValue(
- const AcRxObject* pO, AcRxValue& value) const
- {
- AcDbEntity * ent = AcDbEntity::cast(pO);
- if (ent == NULL)
- return Acad::eNotThatKindOfClass;
- // Получение значения собственного свойства
- // или там где мы хранили это значение
- AEN1MyCircle * pMyCircle = AEN1MyCircle::cast(pO);
- value = AcRxValue(static_cast<MyEnum>(pMyCircle->m_myEnum));
- return Acad::eOk;
- }
- /// <summary>
- /// Этот метод вызывается системой для получения
- /// свойства для определенного объекта
- /// </summary>
- Acad::ErrorStatus MyListProperty::subSetValue(
- AcRxObject* pO, const AcRxValue& value) const
- {
- AcDbEntity * ent = AcDbEntity::cast(pO);
- if (ent == NULL)
- return Acad::eNotThatKindOfClass;
- const MyEnum * val = rxvalue_cast<MyEnum>(&value);
- if (val == NULL)
- return Acad::eInvalidInput;
- // Установка свойства собственного примитива
- // или сохранение там, где мы хотим
- AEN1MyCircle * pMyCircle = AEN1MyCircle::cast(pO);
- pMyCircle->m_myEnum = *val;
- return Acad::eOk;
- }
- /// <summary>
- /// Функция вызывается для создания экземпляра нашего класса
- /// </summary>
- AcRxObject * MyListProperty::makeMyListProperty()
- {
- return new MyListProperty();
- }
Источник: http://adndevblog.typepad.com/autocad/2012/04/non-com-property-with-list-of-possible-values.html
Обсуждение: http://adn-cis.org/forum/index.php?topic=41.0
Отредактировано 06.06.2013 в 00:29:54