I have an application that utilizes this code to select entities
For x = 0 To SelectionSetEntitiesBindingSource.Count - 1 ObjectIDs(x) = ObjectIdFromHandle(myDocDB, SelectionSetEntitiesBindingSource(x)("ACADHandle").ToString) Next
Autodesk.AutoCAD.Internal.Utils.SelectObjects(ObjectIDs)
And then this code to build a selection set from those entities
Public Function GetSelectionSet() As SelectionSet Dim myDoc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument Dim myDocDB As Database = myDoc.Database Dim ed As Editor = myDoc.Editor Dim prObjectSelectionRes As PromptSelectionResult prObjectSelectionRes = ed.SelectImplied() If prObjectSelectionRes.Status = PromptStatus.OK Then GetSelectionSet = prObjectSelectionRes.Value Else MsgBox("An error occurred getting the selection set.", vbOKOnly, "Error") Exit Function End If End Function
This works fine for a while, but eventually the second part of the code failes at prOjectSelectionRes = ed.selectImplied...or rather not fails but returns error -5001.
This appears to be directly related to the number of times I call this function as though there is a limit to the number of sets you can create in an instance of Autocad...or something similar.
These entities are being retrieved from a database which is the reason for the loop in the first part. I execute the code and it will run for a while going through the different tables in the db.
Any help is greatly appreciated.
Thanks!
Solved! Go to Solution.
Just to add a bit more.
It appears when I get out of the command and I select something on screen I can not hit the esc key to cancel the selection...really weird behavior within model space until I change to a layout and back to model space does it fix itself.
This is the method I've used, it also lets me hit the space bar to repeat the command.
Private Sub btnSelectBlock_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSelectBlock.Click
If Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.Count = 0 Then
Exit Sub
End If
curDoc.SendStringToExecute(Chr(27), False, False, False)
curDoc.SendStringToExecute("MyCommand" & vbCr, False, False, False)
Autodesk.AutoCAD.Internal.Utils.SetFocusToDwgView()
End Sub
<CommandMethod("MyCommand")> _
Public Sub selectBlock()
....
End Sub
Thanks for the response but not sure how that would help me.
Workflow of the application:
I dont need to rexecute the command with the space bar..not a concern really.
Any other ideas?
Thanks
<CommandMethod("MyCommand", CommandFlags.Modal Or CommandFlags.UsePickSet Or CommandFlags.Redraw)> _
Public Sub MyCommand()
GetSelectionSet()
End Sub
This worked for getting the implied selection set.
There is a limit of 128 selection set open at one time.
if you meant I should include "CommandFlags.Modal Or CommandFlags.UsePickSet Or CommandFlags.Redraw" on the original entry...I just did that and it did not fix the issue.
Thanks,
Thank you! It appears this may be the problem. However I am still in the process of altering my code to explicitly dispose of all selectionsets that are created.
I will let you know.
Thanks again.
So I took the code in the link you provided and modified it a bit to use the general functionality that I am using and this replicates the error I am receiving exactly. Bombs out at 128 which I suppose makes sense. The problem is that I am not sure why. I am disposing my selection set with each run through the loop. Is there something else?
<CommandMethod("TestSelectionSetCountLimit2", CommandFlags.Modal Or CommandFlags.UsePickSet Or CommandFlags.Redraw)> _ Public Sub TestSElectionSetCountLimit2() Dim myDoc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument Dim db As Database = HostApplicationServices.WorkingDatabase Dim ed As Editor = myDoc.Editor Try For i = 0 To 130 Dim ObjectIDs(0) As ObjectId ObjectIDs(0) = ObjectIdFromHandle(db, "A33DC") Autodesk.AutoCAD.Internal.Utils.SelectObjects(ObjectIDs) Dim prObjectSelectionRes As PromptSelectionResult prObjectSelectionRes = ed.SelectImplied() If prObjectSelectionRes.Status = PromptStatus.OK Then Dim ss As SelectionSet ss = prObjectSelectionRes.Value If ss IsNot Nothing Then ed.WriteMessage(vbLf & "The #{0} SS is good and has {1} entities.", i + 1, ss.Count) ss.Dispose() Else ed.WriteMessage(vbLf & "The #{0} SS is bad!", i + 1) End If Else ed.WriteMessage(vbLf & "The #{0} SS is bad!", i + 1) End If Next Catch ex As System.Exception ed.WriteMessage(ex.ToString()) End Try End Sub
I should also add that you can easily duplicate the error by just replacing the handle with one from your drawing and using the below "ObjectIDfromHandle" function I forgot to include.
Public Shared Function ObjectIdFromHandle(db As Database, strHandle As String) As ObjectId Dim nHandle As Int32 = Int32.Parse(strHandle, Globalization.NumberStyles.AllowHexSpecifier) Dim handle As New Handle(nHandle) Dim ids(0) As ObjectId ids(0) = db.GetObjectId(False, handle, 0) Return ids(0) 'Return db.GetObjectId(False, handle, 0) End Function
Thanks,
First off by changing one line of code in last example and tested it with looping 300 times and no problems.
I have to get going but and I have seen other people have problems that are similiar so will type up a better explanation and concepts to show what is happening.
I probably should rephrase the first sentence that I changed one line and no problems. It still a bad approach for the task and there are better ways but understanding why it is not a good approach helps to see what a better one would be.
If you want to start taking a look at what is going on look at methods
with ILSPY or Reflector you see what they do, and notice calls to methods that are explained in docs - acedSSGet, acedSSAdd, acedSSSetFirst, acedSSFree as they all play a role in it.
In the .NET API you actully never will use an instance of a SelectionSet object, one reason would be it is impossible since it is an abstract class.
You actually are using a SelectionSetDelayMarshalled object and there use to be a SelectionSetFullyMarshalled object but was removed in 2010 or 2011 or earlier.
Except for the SelectionSetDelayMarshalled constuctors that take ObjectIds as a argument, the other constructors pass the selection set to a internal class UnmanagedResources method AddSelectionSet which adds it to a key value pair collection, which passes it into constructor of a DisposableSelectionSet object.
I know that is a little jumbled but will make a better explanation later tonight or tommorrow .
Anyway the only change made was commented out first line and added second.
'Autodesk.AutoCAD.Internal.Utils.SelectObjects(ObjectIDs) ed.SetImpliedSelection(ObjectIDs)
HI Jeff,
I greatly appreciate your time with your response. You have indeed fixed my issue with that little change. I am not sure I understand much in your message or why this one little change makes the difference but it does. Perhaps I can figure out why someday.
Have a great weekend,
I will do post will explanation but the Utils.SelectObjects calls acedSSAdd(null,null,...) which creates a new selection set in each loop without a matching acedSSFree().
Okay, That makes a bit of sense to me. Never would have thought about that when troubleshooting my code. I looked at that line numerous times while troubleshooting but just wasnt sure what else to use.
Thanks so much for your help! Greatly appreciated!
Can't find what you're looking for? Ask the community or share your knowledge.