TheSwamp
Code Red => .NET => Topic started by: Jeff_M 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?
-
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?
-
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.
-
Did you try using the AcadObject or FromAcadObject methods from the DBObject class?
-
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:
ptGroup = grp;
Marshal.AddRef(Marshal.GetIUnknownForObject(ptGroup));
If that doesn't work, then you might also try:
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.
-
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:
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:
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.
-
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:
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:
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.
-
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!
-
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
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
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...." :-)
-
I was able to get it to work by doing exactly what it said to do:
ed.WriteMessage("\nThe style used by " + oGrp.Name + " = " + oGrp.get_PointStyle().Name);
:-)
-
Oh, and I should probably add that you also need to change the line before it:
AeccPoint oPoint = oPoints.Find(747);//hardcoded Point#