Author Topic: try directly calling accessor methods ????  (Read 7399 times)

0 Members and 1 Guest are viewing this topic.

Jeff_M

  • King Gator
  • Posts: 4096
  • C3D user & customizer
try directly calling accessor methods ????
« on: April 22, 2007, 03:42:52 PM »
I've gotten a bit more comfortable using C# with C3D2007 & 2008, thanks to Sinc's C3D utilities, but now I've come across this little problem that I'm stuck on. I've got code that works, up until I try to access a point group's pointstyle.

string strStylName = ptGroup.PointStyle.Name;

or

IAeccPointStyle grpStyle = ptGroup.PointStyle;

these both raise errors in VS when I attempt to build the project. This is the error:

Property, indexer, or event 'PointStyle' is not supported by the language; try directly calling accessor methods 'Autodesk.AECC.Interop.Land.IAeccPointGroup.get_PointStyle()' or 'Autodesk.AECC.Interop.Land.IAeccPointGroup.set_PointStyle(object)'

then this, too, fails:

IAeccPointStyle grpStyle = Autodesk.AECC.Interop.Land.IAeccPointGroup.get_PointStyle(ptGroup);

as does

IAeccPointStyle grpStyle = Autodesk.AECC.Interop.Land.IAeccPointGroup.get_PointStyle();

Any ideas on how to proceed?

TonyT

  • Guest
Re: try directly calling accessor methods ????
« Reply #1 on: April 22, 2007, 06:35:07 PM »
IAeccPointStyle is a COM interface, which you generally
don't use directly in managed code. You usually use the
CCW (COM-Callable Wrapper) that wraps and implements
the COM interface.

Typecast it to an AeccPointStyle or AeccPointStyleClass

I've gotten a bit more comfortable using C# with C3D2007 & 2008, thanks to Sinc's C3D utilities, but now I've come across this little problem that I'm stuck on. I've got code that works, up until I try to access a point group's pointstyle.

string strStylName = ptGroup.PointStyle.Name;

or

IAeccPointStyle grpStyle = ptGroup.PointStyle;

these both raise errors in VS when I attempt to build the project. This is the error:

Property, indexer, or event 'PointStyle' is not supported by the language; try directly calling accessor methods 'Autodesk.AECC.Interop.Land.IAeccPointGroup.get_PointStyle()' or 'Autodesk.AECC.Interop.Land.IAeccPointGroup.set_PointStyle(object)'

then this, too, fails:

IAeccPointStyle grpStyle = Autodesk.AECC.Interop.Land.IAeccPointGroup.get_PointStyle(ptGroup);

as does

IAeccPointStyle grpStyle = Autodesk.AECC.Interop.Land.IAeccPointGroup.get_PointStyle();

Any ideas on how to proceed?


Jeff_M

  • King Gator
  • Posts: 4096
  • C3D user & customizer
Re: try directly calling accessor methods ????
« Reply #2 on: April 22, 2007, 08:50:06 PM »
Typecast it to an AeccPointStyle or AeccPointStyleClass
Thanks, Tony. I originally had my code that way. I get the same errors using either of those.

I'm starting to think that something wasn't included in the wrapper to allow access to the PointStyle objects. The Object Browser seems to say otherwise, but when I Inspect the returned object in Debug mode for a PointGroup it is shown as {System._ComObject} instead of the AeccPointGroup that I would've expected. Attached is screen shot showing how all the other Aecc objects are as expected, but the PointGroup is not. Since it is from this Object that I'm trying to get the PointStyle, could this be why I'm having problems with this? It didn't get in the pic, but the ptGroup variable is TypeCast as AeccPointGroup.

Of course, this all may be more due to my inexperience with the language.

sinc

  • Guest
Re: try directly calling accessor methods ????
« Reply #3 on: April 23, 2007, 12:05:59 AM »
Did you try using the AcadObject or FromAcadObject methods from the DBObject class?

TonyT

  • Guest
Re: try directly calling accessor methods ????
« Reply #4 on: April 23, 2007, 09:13:38 AM »
Your code doesn't show what the ptGroup variable is declared as.

Also, there may be an issue with COM reference counting since
the scope of the PointGroup objects is the foreach() block, and
it may be that Release() is being called on each grp (the foreach
variable), which invalidates the reference to the object.

So just guessing here, you might try something like this:

   Within your foreach() loop where you assign ptGroup:

Code: [Select]

         ptGroup = grp;
         Marshal.AddRef(Marshal.GetIUnknownForObject(ptGroup));


If that doesn't work, then you might also try:

Code: [Select]

         AeccPointGroupClass group =
           (AeccPointGroupClass) = Marshal.CreateWrapperOfType( grp,
                 typeof(AeccPointGroupClass));


Typecast it to an AeccPointStyle or AeccPointStyleClass
Thanks, Tony. I originally had my code that way. I get the same errors using either of those.

I'm starting to think that something wasn't included in the wrapper to allow access to the PointStyle objects. The Object Browser seems to say otherwise, but when I Inspect the returned object in Debug mode for a PointGroup it is shown as {System._ComObject} instead of the AeccPointGroup that I would've expected. Attached is screen shot showing how all the other Aecc objects are as expected, but the PointGroup is not. Since it is from this Object that I'm trying to get the PointStyle, could this be why I'm having problems with this? It didn't get in the pic, but the ptGroup variable is TypeCast as AeccPointGroup.

Of course, this all may be more due to my inexperience with the language.

Jeff_M

  • King Gator
  • Posts: 4096
  • C3D user & customizer
Re: try directly calling accessor methods ????
« Reply #5 on: April 23, 2007, 08:05:52 PM »
OK, I got a bit further based on the suggestion that the object may be getting a Release() call.
First, the ptGroup is defined outside the foreach() by:
AeccPointGroup ptGroup;

I changed the code within the foreach() loop to this:
Code: [Select]
if (grp.DrawPriority < i)
{
   i = grp.DrawPriority;
   grpName = grp.Name;
   ptGroup = ptGroups.Item(grpName);
}
then outside the foreach() I can now see this in the locals window:
Quote
      PlotStyleName   "ByLayer"   string
      PointCount   2405   int
+      Points   {Dimensions:[2405]}   object {int[]}
+      QueryBuilder   '((Autodesk.AECC.Interop.Land.AeccPointGroupClass)(ptGroup)).QueryBuilder' threw an exception of type 'System.UnauthorizedAccessException'   Autodesk.AECC.Interop.Land.AeccPointGroupQueryBuilder {System.UnauthorizedAccessException}
which shows that at least now the AeccPointGroupClass is being used instead of a System_ComObject. However, you can see that there is no property in the list for the PointStyle. I'm guessing that this is why the Build Error occurs. The docs, Oject Browser and Intellisense all say that there should be a PointStyle property available here.

TonyT

  • Guest
Re: try directly calling accessor methods ????
« Reply #6 on: April 23, 2007, 09:15:41 PM »
An exception is being thrown by the QueryBuilder property
when it is queried by the debugger.

But, what is the error you get at runtime when you try
to access the style property?

OK, I got a bit further based on the suggestion that the object may be getting a Release() call.
First, the ptGroup is defined outside the foreach() by:
AeccPointGroup ptGroup;

I changed the code within the foreach() loop to this:
Code: [Select]
if (grp.DrawPriority < i)
{
   i = grp.DrawPriority;
   grpName = grp.Name;
   ptGroup = ptGroups.Item(grpName);
}
then outside the foreach() I can now see this in the locals window:
Quote
      PlotStyleName   "ByLayer"   string
      PointCount   2405   int
+      Points   {Dimensions:[2405]}   object {int[]}
+      QueryBuilder   '((Autodesk.AECC.Interop.Land.AeccPointGroupClass)(ptGroup)).QueryBuilder' threw an exception of type 'System.UnauthorizedAccessException'   Autodesk.AECC.Interop.Land.AeccPointGroupQueryBuilder {System.UnauthorizedAccessException}
which shows that at least now the AeccPointGroupClass is being used instead of a System_ComObject. However, you can see that there is no property in the list for the PointStyle. I'm guessing that this is why the Build Error occurs. The docs, Oject Browser and Intellisense all say that there should be a PointStyle property available here.


Jeff_M

  • King Gator
  • Posts: 4096
  • C3D user & customizer
Re: try directly calling accessor methods ????
« Reply #7 on: April 24, 2007, 01:00:29 AM »
I don't have access to the code right now, but I'm pretty sure the error is the same message that started this thread.

Property, indexer, or event 'PointStyle' is not supported by the language; try directly calling accessor methods 'Autodesk.AECC.Interop.Land.IAeccPointGroup.get_PointStyle()' or 'Autodesk.AECC.Interop.Land.IAeccPointGroup.set_PointStyle(object)'

by this line:
AeccPointStyle grpStyle = ptGroup.PointStyle;

And this is a build error.

The exceptions are for properties that aren't available in the current context. There are others, such as selectedPoint, that appear the same way. Other properties, like the Points, show up fine.

I was in the field most of the day so I wasn't able to try the Marshal options you suggested. Should get a chance tomorrow.

Thanks!

Jeff_M

  • King Gator
  • Posts: 4096
  • C3D user & customizer
Re: try directly calling accessor methods ????
« Reply #8 on: May 07, 2007, 07:09:49 PM »
I decided to try this in VBA...it worked :-/ (I'll post that code if anyone cares to see it)

I then said, well let's see what happens in VB.NET... it WORKED! I'm using nearly identical code for the VB & C# versions, yet the C# version throws that stupid build error.

Here's a stripped down test, both the Vb & C# references (as shown in the pic) are the same:
VB.NET
Code: [Select]
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.Interop
Imports Autodesk.AutoCAD.Interop.Common
Imports System.Runtime.InteropServices
Imports System.Runtime.InteropServices.Marshal

Imports Autodesk.AECC.Interop.Land
Imports Autodesk.AECC.Interop.UiLand

Public Class Class1
    Public WithEvents m_AcadApp As AcadApplication
    Public oCivilApp As AeccApplication
    <CommandMethod("TestStyle")> _
     Public Sub TestStyle()

        Try
            m_AcadApp = GetActiveObject("AutoCAD.Application.17.1")
            oCivilApp = m_AcadApp.GetInterfaceObject("AeccXUiLand.AeccApplication.5.0")
            If oCivilApp Is Nothing Then
                MsgBox("Error creating " & "AeccXUiLandLib.AeccApplication" & ", exit.")
                GoTo exit_here
            Else
                ''MsgBox("Civil 3D instance connected" & m_AcadApp.ActiveDocument.Name.ToString)
                Dim oCivilDoc As AeccDocument
                oCivilDoc = oCivilApp.ActiveDocument
                Dim oPtGroups As AeccPointGroups
                Dim oPoint As AeccPoint
                oPoint = oCivilDoc.Points.Item(747)
                Dim oGrp As AeccPointGroup
                oPtGroups = oCivilDoc.PointGroups
                For Each oGrp In oPtGroups
                    If oGrp.ContainsPoint(oPoint.Number) Then
                        MsgBox("Point 747 is in PtGroup: " & oGrp.Name & vbCrLf & _
                               "The Pointstyle for the group is: " & oGrp.PointStyle.Name)
                    End If
                Next
            End If

        Catch
            MsgBox(Err.Description() & Err.Number)
        End Try
exit_here:

    End Sub
End Class
And the C# counterpart
Code: [Select]
using System;
using System.Collections.Generic;
using System.Text;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Interop;
using Autodesk.AECC.Interop.Land;
using Autodesk.AECC.Interop.UiLand;

using acadApp = Autodesk.AutoCAD.ApplicationServices.Application;

namespace PointGroupDataTest
{
    public class Class1
    {
        public Class1()
        {
        }
        #region Command
        [CommandMethod("PtGrp")]
        static public void PtGrptCode()
        {
            Document doc = acadApp.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;
            string m_sAeccAppProgId = "AeccXUiLand.AeccApplication.5.0";
            AcadApplication m_oAcadApp = (Autodesk.AutoCAD.Interop.AcadApplication)Application.AcadApplication;
            AeccApplication m_oAeccApp = (AeccApplication)m_oAcadApp.GetInterfaceObject(m_sAeccAppProgId);
            AeccDocument m_oAeccDoc = (AeccDocument)m_oAeccApp.ActiveDocument;
            AeccDatabase m_oAeccDb = (AeccDatabase)m_oAeccDoc.GetType().GetProperty("Database").GetValue(m_oAeccDoc, null);
            AeccPoints oPoints = (AeccPoints)m_oAeccDoc.Points;
            AeccPoint oPoint = oPoints.Item(747);//hardcoded Point#
            AeccPointGroups oGroups = m_oAeccDoc.PointGroups;
            foreach (AeccPointGroup oGrp in oGroups)
            {
                if (oGrp.ContainsPoint(oPoint.Number))
                {
                    ed.WriteMessage("\nPoint 747 is in PointGroup: " + oGrp.Name);
                    ed.WriteMessage("\nThe style used by " + oGrp.Name + " = " + oGrp.PointStyle.Name);
                }
            }
        }
        #endregion
    }
}
The C# version will error when building, pointing to the oGrp.Pointstyle in this line:
ed.WriteMessage("\nThe style used by " + oGrp.Name + " = " + oGrp.PointStyle.Name);

I sure can't tell any difference in the use of this property, or how I obtain the Objects. Can anyone enlighten me?

Please don't say "Well just do it in VB.NET or VBA...." :-)
« Last Edit: May 07, 2007, 07:11:22 PM by Jeff_M »

sinc

  • Guest
Re: try directly calling accessor methods ????
« Reply #9 on: May 07, 2007, 08:52:54 PM »
I was able to get it to work by doing exactly what it said to do:

Code: [Select]
ed.WriteMessage("\nThe style used by " + oGrp.Name + " = " + oGrp.get_PointStyle().Name);
 :-)

sinc

  • Guest
Re: try directly calling accessor methods ????
« Reply #10 on: May 07, 2007, 08:58:41 PM »
Oh, and I should probably add that you also need to change the line before it:

Code: [Select]
AeccPoint oPoint = oPoints.Find(747);//hardcoded Point#