ObjectARX
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Property palette and custom entities

18 REPLIES 18
SOLVED
Reply
Message 1 of 19
cadsindiaadn
5410 Views, 18 Replies

Property palette and custom entities

Hi,

I have a custom entity with some complex properties such as a dynamically populating list, enumerations etc. I tried the non-COM way of populating the property palette but couldnt find how to display the list of properties. I tried the Square sample provided in the ObjectARX 2015 SDK to see how the COM way of displaying the property palette works. Unfortunately I couldnt get it work.

Could you provide me with a sample of displaying the properties of a custom object in property palette please?

What I am trying to achieve is in my custom object I have a list. This list is populated at run time. for one instance of the custom object I might have 3 items in the list, for another instance of the custom object I might 5 items in the list. for example, the list has 3 items say A, B, and C, I should be able to see 3 individual properties A, B and C in the property palette in addition to my other properties.

So when I select my object, the property palette should display something like

A ----

B ----

C ----

other_properties_1 -----

other_properties_2 -----

 

I also would like to know if there is a simple way to display the properties of a custom object through C#.NET. I can wrap the custom entity to use in .NET but not sure how to display its properties in the palette. I have seen an article in the through_the_interface blog http://through-the-interface.typepad.com/through_the_interface/2009/03/exposing-autocads-properties-... , but it is more of dynamic properties.

 

Thanks,

Ram.

18 REPLIES 18
Message 2 of 19
Balaji_Ram
in reply to: cadsindiaadn

Hi Ram,

 

For OPM to recognize a static property as an enum property, override the "GetCustomPropertyCtrl" method and provide "CLSID_AcPePropertyEditorEnum" as the ActiveX control to use for this property. The values to be displayed in the combobox are to be provided by overiding the "GetPredefinedStrings" and "GetPredefinedValue" methods. These methods will let you change the values at runtime.

 

Here is a code snippet to do that :

 

// idl
[propget, id(3), helpstring("property myenum")] HRESULT myenum1([out, retval] long* pVal);
[propput, id(3), helpstring("property myenum")] HRESULT myenum1([in] long newVal);
 
// COM Wrapper header
STDMETHOD(GetPredefinedStrings)(
        /* [in] */ DISPID dispID,
        /* [out] */ CALPOLESTR *pCaStringsOut,
        /* [out] */ CADWORD *pCaCookiesOut);
STDMETHOD(GetPredefinedValue)(
        /* [in] */ DISPID dispID, 
        /* [out] */ DWORD dwCookie, 
        /* [out] */ VARIANT *pVarOut);
 
// COM Wrapper cpp
//- IAcPiPropertyDisplay
STDMETHODIMP CMyObject::GetCustomPropertyCtrl (VARIANT Id, LCID lcid, BSTR *pProgId) {
            if ( pProgId == NULL )
                        return (E_FAIL) ;
           
            if ( V_I4(&Id) == 3 ) {
                        LPOLESTR progId;
                        ProgIDFromCLSID (CLSID_AcPePropertyEditorEnum, &progId);
                        *pProgId =::SysAllocString (progId);
 
                        return (S_OK) ;
            }
 
            return (E_NOTIMPL) ;
}
 
STDMETHODIMP CMyObject::GetPredefinedStrings(DISPID dispID, CALPOLESTR *pCaStringsOut, CADWORD *pCaCookiesOut)
{
            USES_CONVERSION;
 
            if( (dispID == 0x3))
            {
                        pCaStringsOut->pElems = (LPOLESTR *)::CoTaskMemAlloc(sizeof(LPOLESTR) * 2);
                        pCaCookiesOut->pElems = (DWORD *)::CoTaskMemAlloc(sizeof(DWORD) * 2);
 
                        pCaStringsOut->pElems[0] = ::SysAllocString(L"First");
                        pCaCookiesOut->pElems[0] = 1;
                        pCaStringsOut->pElems[1] = ::SysAllocString(L"Second");
                        pCaCookiesOut->pElems[1] = 2;
 
                        pCaStringsOut->cElems = 2;
                        pCaCookiesOut->cElems = 2;
                        return S_OK;
            }
            return  IOPMPropertyExtensionImpl<CMyObject>::GetPredefinedStrings(dispID,pCaStringsOut,pCaCookiesOut);    
}
 
STDMETHODIMP CMyObject::GetPredefinedValue(DISPID dispID, DWORD dwCookie, VARIANT *pVarOut)
{
            if(dispID == 0x3)
            {
                        if(dwCookie == 1)
                        {
                                    ::VariantCopy(pVarOut, &CComVariant((long)1));
                        }
                        else if(dwCookie == 2)
                        {
                                    ::VariantCopy(pVarOut, &CComVariant((long)2));
                        }
            }
            else
                        return IOPMPropertyExtensionImpl<CMyObject>::GetPredefinedValue(dispID, dwCookie, pVarOut);
 
    return S_OK;
}

I have attached a sample project that should help get started.

 

If you are looking for the Non-COM property system, this blog post should help. But i do not think you can make the list change at runtime.

 

http://adndevblog.typepad.com/autocad/2012/04/non-com-property-with-list-of-possible-values.html

 

About using .Net, unfortunately there is no direct AutoCAD .Net API to do that. The blog post that you mentioned in your post is a way to workaround that. But, I would recommend going the C++ route as you already have the custom entity implemented in C++ and avoid the additional wrapper. 

 

Regards,

Balaji

 

 



Balaji
Developer Technical Services
Autodesk Developer Network

Message 3 of 19
cadsindiaadn
in reply to: Balaji_Ram

Thanks very much Balaji.

Could you attach the sample project please?

 

Thanks,

Ram.

Message 4 of 19
Balaji_Ram
in reply to: cadsindiaadn

Sorry, I missed the attachment.

 

Here it is. 

 

Regards,

Balaji



Balaji
Developer Technical Services
Autodesk Developer Network

Message 5 of 19
cadsindiaadn
in reply to: Balaji_Ram

Thanks very much Balaji.

The sample being a ATL COM based one, should I be registering this on the machine by copying it to the AutoCAD installation folder?

One of the concerns I have in registering a COM DLL is, this prevents me from having parallel versions of my product on a machine.

This was the basis of my question for an alternative in CSharp.

 

Thanks,

Ram.

 

 

Message 6 of 19
Balaji_Ram
in reply to: cadsindiaadn

Hi Ram,

 

Appload the .arx and the self-registration should take care of the registration provided you have admin rights to register it in the system.

You do not need to copy to AutoCAD's install folder.

For supporting multiple versions, you will need to provide new GUID for the COM wrapper if the interface changes.

 

The idl file in the project should provide the GUIDs that you may need to find and replace with new GUID, in case you want to do that.

 

Regards,

Balaji

 

 

 



Balaji
Developer Technical Services
Autodesk Developer Network

Message 7 of 19
cadsindiaadn
in reply to: Balaji_Ram

Hi Balaji,

Thanks. After running AutoCAD in administrator mode, I am able to see the properties for the line sample.

As I asked in my original question, my requirement is to add/remove the properties at runtime depending on the internal state of the object.

As an example, if I have a list of items which is populated at runtime inside my object, I should be able to add the properties according to the count of items in my list.

So, if I have two instances of MyTestEntityClass obj1 with 3 items in the list and obj2 with 2 items in the list, when I select Obj1 I should be able to add 3 properties and when I select Obj2 I should be able to add 2 properties in the palette.

 

I was assuming I could do something with the method

GetElementStrings(/* [in] */ DISPID dispID, /* [out] */ OPMLPOLESTR __RPC_FAR *pCaStringsOut, /* [out] */ OPMDWORD __RPC_FAR *pCaCookiesOut)

 

But this is called only once for a type? If I copy and make several instances of the line in the sample, this method wasnt called for all my instances?

 

Could you help me with achieving this please?

 

Thanks,

Ram.

 

 

 

Message 8 of 19
Balaji_Ram
in reply to: cadsindiaadn

Hi Ram,

 

From what i understand so far, you will need a dynamic per-instance property to do that.

But, before i can try and get a sample for it, can you clarify what your application needs to show and what you mean by "add 3 properties for one of the instances and 2 for the other instance" ?

Are you referring to the OPM property or enum values for a single OPM property ?

 

Possibly a screenshot showing the property palette for the two instances will help me understand.

 

Regards,

Balaji

 

 



Balaji
Developer Technical Services
Autodesk Developer Network

Message 9 of 19
cadsindiaadn
in reply to: Balaji_Ram

Hi Balaji,

I think yes, I need dynamic per instance property. but not sure about the terminologies.

I have attached two images. Assume I have a class Ring with a list as a member variable inside as shown below.

 

 

    struct Data
    {
        public string Name;
        public double Value;
    }

    class Ring
    {
        public IList<Data> MyProperties
        {
            get;
            set;
        }
    }

 

now I have two instances of Ring

 

 

	    Ring ring1 = new Ring();
            ring1.MyProperties = new List<Data>()
                                            {
                                                new Data(){Name = "A", Value = 200},
                                                new Data(){Name = "B", Value = 300},
                                                new Data(){Name = "C", Value = 400},
                                                new Data(){Name = "D", Value = 500},
                                            };

            Ring ring2 = new Ring();
            ring2.MyProperties = new List<Data>()
                                            {
                                                new Data(){Name = "A", Value = 200},
                                                new Data(){Name = "B", Value = 300},                                              
                                            };

 

 

Now when I select Ring1 entity, I should be able to see the property palette as in ring1.png and selecting ring2 should look similar to ring2.png.

 

Hope I am clear.

 

Thanks,

Ram.

Message 10 of 19
Balaji_Ram
in reply to: cadsindiaadn

There are two ways to approach this :

 

1) If you know already that there are only 4 properties out of which some of the instances will show two and some other instances might show all four - you can create all those four properties as static properties in your COM wrapper and have the instances show or hide using the IOPMProopertyExtensionImpl::ShowProperty method.

 

2) Create a dynamic property for each of those four properties and add any of those as a property to an instance using IPropertySource::GetProperties method. The attached sample project demonstrates this. After you appload the .arx, draw two lines. A line that is horizontal and another at an angle. The dynamic properties of these lines differ.

 

Regards,

Balaji

 

 

 



Balaji
Developer Technical Services
Autodesk Developer Network

Message 11 of 19
cadsindiaadn
in reply to: Balaji_Ram

Thanks very much Balaji.

I suppose this example is what I am looking for. I will give it a try.

Do you have the interface IPropertySource exposed to .NET as Kean Walmsley exposed the IDynamicProperties?

If that's available I think I can achieve this through.NET by following Kean's posts and the exposed IPropertySource.

Thanks again for this excellent sample.

By the way will this cause any performance issues?

 

Regards,

Ram.

Message 12 of 19
Balaji_Ram
in reply to: cadsindiaadn

I am not aware of a way to get the first approach working using the .Net API.

It is quite easy to do that using the C++ COM Wrapper.

 

You may need to give it a try to find out about the performance in your application.

 

I would use the static properties and show/hide them as that is simple approach to code as compared to adding dynamic properties.

 

Regards,

Balaji

 



Balaji
Developer Technical Services
Autodesk Developer Network

Message 13 of 19
cadsindiaadn
in reply to: Balaji_Ram

Hi Balaji,

I was able to expose the IPropertySource to C#.NET and was able to display the properties of my custom entity in the property palette using this mechanism.

One thing I got stuck at is the name of the custom entity is not displayed in the property palette. I am kinda trying to achieve a mechanism to create custom entities in .NET so that the development time can be saved and programmers can be freed of learning COM.

Is it possible to get the name of my custom entity to be displayed in the property palette without using the static property dispaly mechanism (the COM way) ?

Or is it possible to implement my own AcRxClass and associate it with my custom entity?

 

Thanks,

Ram.

Message 14 of 19
jwe03
in reply to: Balaji_Ram

@Balaji_Ram, thank you for the sample.

I'm using AutoCAD 2018 and for all the custom entities i tried (polysamp sample, square sample, in addition to the line project you attached), i cannot see the properties in the properties panel. It shows no selection always:

Any ideas why this might be occurring?No Selection in Properties Panel.PNG

 

 

 

Message 15 of 19
Alexander.Rivilis
in reply to: jwe03

@jwe03

Try those samples with admin rights. Without admin rights there is no self-registration of COM-wrappers.

Also you can create new user with admin rights and test with this user.

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

Message 16 of 19
jwe03
in reply to: Alexander.Rivilis

done ! finally i can see them 
Thank you !

Message 17 of 19
Anonymous
in reply to: Balaji_Ram

Hi,

 

I need to add spin control in ACAD property pallet. My property type is dynamic.

I tried with below link code information.

https://adndevblog.typepad.com/autocad/2012/12/how-to-create-a-polyline-like-vertex-edit-with-a-spin...

The Get element strings function does not invoke by system.

Please let me know to resolve this issue.

Can any one upload sample project? It may useful to understand it.

 

Thanks & Regards,

Jayaprakash

Message 18 of 19
Alexander.Rivilis
in reply to: Anonymous


@Anonymous wrote:

Hi,

 

I need to add spin control in ACAD property pallet. My property type is dynamic.

I tried with below link code information.

https://adndevblog.typepad.com/autocad/2012/12/how-to-create-a-polyline-like-vertex-edit-with-a-spin...

The Get element strings function does not invoke by system.

Please let me know to resolve this issue.

Can any one upload sample project? It may useful to understand it.

 

Thanks & Regards,

Jayaprakash


First of all please do not post one question to different topics. It does not help in solving your problem.

 

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

Message 19 of 19
Anonymous
in reply to: Alexander.Rivilis

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Technology Administrators


Autodesk Design & Make Report