Author Topic: Get objectid through viewport  (Read 3699 times)

0 Members and 1 Guest are viewing this topic.

TJK44

  • Guest
Get objectid through viewport
« on: March 01, 2012, 10:44:11 AM »
I am creating a leader that has an annotation and the annotation is the attributes of the selected block. I am trying to allow the user to select a block through a viewport (in paperspace), but without actually opening the viewport. Is it possible to return the objectid this way?

Thanks,

Ted


I found this post here http://www.theswamp.org/index.php?topic=22963.msg345716#msg345716 and tried using Daniel's code, but getting an error saying - unable to find entry point name '?' in dll 'acad.exe'

Code: [Select]
Dim result As Integer = acedNEntSelPEx("Pick something:", adsname, picked, 0, xform, resbuf, _
             0, gsmarker)
« Last Edit: March 01, 2012, 07:49:40 PM by TJK44 »

TheMaster

  • Guest
Re: Get objectid through viewport
« Reply #1 on: March 01, 2012, 09:21:31 PM »
That code looks a lot like this code:

http://forums.autodesk.com/t5/NET/How-to-P-Invoke-acedNEntSelPEx/td-p/2252397

The error you get is probably because the entry points are not the same on 32 and 64 bit platforms, which makes using P/Invoke a PITA because you need to either branch to one of two functions that use the 32 and 64 bit entry point sigs in your code (depending on the result of IntPtr.Size), or you must use two different assemblies targeting 32 and 64 bit platforms respectively, each using the appropriate entry points for the targeted platform).

I gave up on P/Invoke from C# and isolate all my native calls into platform-specific mixed-mode assemblies written in C++/CLI, because it eliminates the need for platform-specific code (C++/CLI's 'implicit' P/Invoke is much easier to use than the DllImport attribute-based P/Invoke in C#, plus it supports virtual method resolution on calls to abstract instance methods on native C++ classes, using the ThisCall calling convention).

Edit: Other possible causes of the error are that the web page you got that from mangled the entry point signature, or it has changed since. You can use depends.exe (http://www.dependencywalker.com) to find it.

I am creating a leader that has an annotation and the annotation is the attributes of the selected block. I am trying to allow the user to select a block through a viewport (in paperspace), but without actually opening the viewport. Is it possible to return the objectid this way?

Thanks,

Ted


I found this post here http://www.theswamp.org/index.php?topic=22963.msg345716#msg345716 and tried using Daniel's code, but getting an error saying - unable to find entry point name '?' in dll 'acad.exe'

Code: [Select]
Dim result As Integer = acedNEntSelPEx("Pick something:", adsname, picked, 0, xform, resbuf, _
             0, gsmarker)
« Last Edit: March 02, 2012, 04:02:45 AM by TheMaster »

huangc

  • Guest
Re: Get objectid through viewport
« Reply #2 on: March 02, 2012, 02:35:40 AM »
Try to activate the current viewport

TJK44

  • Guest
Re: Get objectid through viewport
« Reply #3 on: March 02, 2012, 08:45:33 AM »
I'm sorry master, what do you mean by entry point signature. New to the P/Invoke thing. Are you referring to "?acedNEntSelPEx@@YAHPB_WQAJQANHQAY03NPAPAUresbuf@@IPAH@Z"

kaefer

  • Guest
Re: Get objectid through viewport
« Reply #4 on: March 02, 2012, 09:22:27 AM »
"?acedNEntSelPEx@@YAHPB_WQAJQANHQAY03NPAPAUresbuf@@IPAH@Z"

That's a 32-bit signature you have there. For 64-bit, try
Quote
"?acedNEntSelPEx@@YAHPEB_WQEA_JQEANHQEAY03NPEAPEAUresbuf@@IPEA_J@Z"

Do you see where this is going?

TJK44

  • Guest
Re: Get objectid through viewport
« Reply #5 on: March 02, 2012, 12:58:31 PM »
Thanks kaefer, that made it not error out and have been able to get the selected objects objectid. How do you know where to find the entry point and when to use which one? I eventually found the 64bit signature using the dependency walker opening acad.exe.

Jeff H

  • Needs a day job
  • Posts: 6150
Re: Get objectid through viewport
« Reply #6 on: March 02, 2012, 01:12:02 PM »
Thanks kaefer, that made it not error out and have been able to get the selected objects objectid. How do you know where to find the entry point and when to use which one? I eventually found the 64bit signature using the dependency walker opening acad.exe.

Using dumpbin.exe as an Aid for Declaring P/Invokes
 
 

TheMaster

  • Guest
Re: Get objectid through viewport
« Reply #7 on: March 02, 2012, 04:02:29 PM »
I'm sorry master, what do you mean by entry point signature. New to the P/Invoke thing. Are you referring to "?acedNEntSelPEx@@YAHPB_WQAJQANHQAY03NPAPAUresbuf@@IPAH@Z"

The entry point signature is what you pass to the EntryPoint =  parameter of the DllImport attribute. The one you show in the above quote is an example.

The real question (which is what I talked about in my reply) is, do you need your code to run on both 32 and 64 bit AutoCAD?.

If the answer is yes, getting the correct entry point to get your code working on whatever version of AutoCAD you're using to develop with, is the easy part. Getting your solution to work on both 32 and 64 bit versions of AutoCAD is the other problem I talked about earlier.

« Last Edit: March 02, 2012, 04:13:00 PM by TheMaster »

TJK44

  • Guest
Re: Get objectid through viewport
« Reply #8 on: March 02, 2012, 05:20:04 PM »
Only running 64bit installs, shouldn't be a problem.

TJK44

  • Guest
Re: Get objectid through viewport
« Reply #9 on: March 02, 2012, 05:24:36 PM »
This is a mixture of code from daniel's and tony's post's on autodesk forum and attribute extraction code. Thanks to all for the help.

Code - Visual Basic: [Select]
  1.         <CommandMethod("attleader")> _
  2.         Public Shared Sub acedNEntSelPExTest()
  3.             Dim partDesc As String = ""
  4.             Dim partNum As String = ""
  5.             Dim matDesc As String = ""
  6.             Dim designer As String = ""
  7.             Dim length As String = ""
  8.             Dim width As String = ""
  9.             Dim createDate As String = ""
  10.             Dim matNum As String = ""
  11.             Dim makeBuy As String = ""
  12.             Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor
  13.             Dim id As New ObjectId
  14.             Dim adsname As Int64 = 0
  15.             Dim picked As Point3d
  16.             Dim xform As Matrix3d
  17.             Dim resbuf As IntPtr = IntPtr.Zero
  18.             Dim gsmarker As Integer = -1
  19.             Dim transflag As Integer = 1
  20.             Dim result As Integer = acedNEntSelPEx("Select Block(1):", adsname, picked, 0, xform, resbuf, _
  21.             transflag, gsmarker)
  22.             Dim db As Database = HostApplicationServices.WorkingDatabase
  23.             Using trans As Transaction = db.TransactionManager.StartTransaction()
  24.                 If result = 5100 Then
  25.                     If resbuf <> IntPtr.Zero Then
  26.                         Dim buffer As ResultBuffer = DirectCast(DisposableWrapper.Create(GetType(ResultBuffer), resbuf, True), ResultBuffer)
  27.                         Dim i As Integer = 0
  28.                         For Each v As TypedValue In buffer
  29.                             Dim ent As Entity = trans.GetObject(v.Value, OpenMode.ForRead, False)
  30.                             If TypeOf ent Is BlockReference Then
  31.                                 Dim blkRef As BlockReference = TryCast(trans.GetObject(v.Value, OpenMode.ForRead, False), BlockReference)
  32.                                 Dim objId As ObjectId = blkRef.BlockTableRecord
  33.                                 Dim btr As BlockTableRecord = trans.GetObject(objId, OpenMode.ForRead)
  34.                                 If btr.IsFromExternalReference Then
  35.                                     Dim db2 As Database = New Database(False, False)
  36.                                     If File.Exists(btr.PathName) Then
  37.                                         db2.ReadDwgFile(btr.PathName, FileShare.ReadWrite, False, "")
  38.                                         Using trx2 As Transaction = db2.TransactionManager.StartTransaction()
  39.                                             Dim xrefBt As BlockTable = trx2.GetObject(db2.BlockTableId, OpenMode.ForWrite)
  40.                                             Dim btrMs2 As BlockTableRecord = trx2.GetObject(xrefBt(BlockTableRecord.ModelSpace), OpenMode.ForWrite)
  41.                                             For Each id2 As ObjectId In btrMs2
  42.                                                 Dim ent2 As Entity = trx2.GetObject(id2, OpenMode.ForRead, False)
  43.                                                 If TypeOf ent2 Is BlockReference Then
  44.                                                     Dim blkref2 As BlockReference = TryCast(trx2.GetObject(id2, OpenMode.ForWrite, False), BlockReference)
  45.                                                     Dim attrefIds As AttributeCollection = blkref2.AttributeCollection
  46.                                                     For Each attrefid As ObjectId In attrefIds
  47.                                                         Dim attref As AttributeReference = trx2.GetObject(attrefid, OpenMode.ForWrite, False)
  48.                                                         Select Case attref.Tag
  49.                                                             Case "PartDescription"
  50.                                                                 partDesc = attref.TextString
  51.                                                             Case "PartNumber"
  52.                                                                 partNum = attref.TextString
  53.                                                             Case "Designer"
  54.                                                                 designer = attref.TextString
  55.                                                             Case "CreateDate"
  56.                                                                 createDate = attref.TextString
  57.                                                             Case "MaterialNum"
  58.                                                                 matNum = attref.TextString
  59.                                                             Case "MaterialDesc"
  60.                                                                 matDesc = attref.TextString
  61.                                                             Case "Make-Buy"
  62.                                                                 makeBuy = attref.TextString
  63.                                                             Case "Length"
  64.                                                                 length = attref.TextString
  65.                                                             Case "Width"
  66.                                                                 width = attref.TextString
  67.                                                         End Select
  68.  
  69.                                                     Next
  70.  
  71.                                                 End If
  72.                                             Next
  73.  
  74.                                         End Using
  75.                                     End If
  76.                                     db2.Dispose()
  77.  
  78.                                     '' Open the Block table for read
  79.  
  80.                                     Dim acBlkTbl As BlockTable
  81.  
  82.                                     acBlkTbl = trans.GetObject(db.BlockTableId, OpenMode.ForRead)
  83.  
  84.                                     '' Open the Block table record Model space for write
  85.  
  86.                                     Dim acBlkTblRec As BlockTableRecord
  87.  
  88.                                     acBlkTblRec = trans.GetObject(acBlkTbl(BlockTableRecord.PaperSpace), OpenMode.ForWrite)
  89.  
  90.                                     ''Get start point of the leader
  91.                                    Dim pr As PromptPointResult = ed.GetPoint(vbLf & "Specify leader arrowhead location: ")
  92.  
  93.                                     If pr.Status <> PromptStatus.OK Then
  94.                                         Return
  95.                                     End If
  96.  
  97.                                     Dim startPt As Point3d = pr.Value
  98.  
  99.                                     ''Get end point of leader
  100.                                    Dim opts As New PromptPointOptions(vbLf & "Specify landing location: ")
  101.  
  102.  
  103.                                     opts.BasePoint = startPt
  104.                                     opts.UseBasePoint = True
  105.  
  106.                                     pr = ed.GetPoint(opts)
  107.  
  108.                                     If pr.Status <> PromptStatus.OK Then
  109.                                         Return
  110.                                     End If
  111.  
  112.                                     Dim endPt As Point3d = pr.Value
  113.  
  114.                                     '' Create the leader with annotation
  115.  
  116.                                     Dim acLdr As New MLeader()
  117.                                     Dim ldNum As Integer = acLdr.AddLeader()
  118.                                     Dim lnNum As Integer = acLdr.AddLeaderLine(ldNum)
  119.  
  120.                                     acLdr.AddFirstVertex(lnNum, startPt)
  121.                                     acLdr.AddLastVertex(lnNum, endPt)
  122.  
  123.                                     acLdr.LeaderLineType = LeaderType.StraightLeader
  124.  
  125.                                     ''Create the MText
  126.                                    Dim mt As New MText()
  127.                                     mt.Contents = "Part Number: " & partNum & vbLf & _
  128.                                                         "Part Description: " & partDesc & vbLf & _
  129.                                                         "Material Number: " & matNum & vbLf & _
  130.                                                         "Material Desc.: " & matDesc & vbLf & _
  131.                                                         "Make-Buy: " & makeBuy
  132.  
  133.                                     mt.Location = endPt
  134.                                     mt.TextHeight = 0.05
  135.                                     acLdr.ContentType = ContentType.MTextContent
  136.  
  137.                                     acLdr.MText = mt
  138.  
  139.                                     '' Add the new object to paper space and the transaction
  140.                                    acBlkTblRec.AppendEntity(acLdr)
  141.  
  142.                                     trans.AddNewlyCreatedDBObject(acLdr, True)
  143.  
  144.                                 End If
  145.  
  146.                             End If
  147.  
  148.                            
  149.                         Next
  150.  
  151.                         buffer.Dispose()
  152.                     End If
  153.                 End If
  154.  
  155.                 trans.Commit()
  156.             End Using
  157.         End Sub
  158.  
  159.         <DllImport("acad.exe", EntryPoint:="?acedNEntSelPEx@@YAHPEB_WQEA_JQEANHQEAY03NPEAPEAUresbuf@@IPEA_J@Z", CallingConvention:=CallingConvention.Cdecl, CharSet:=CharSet.Unicode)> _
  160.         Private Shared Function acedNEntSelPEx(ByVal prompt As String, ByRef adsname As Int64, ByRef picked As Point3d, ByVal pickflag As Integer, ByRef transform As Matrix3d, ByRef resbuf As IntPtr, ByVal transSpaceFlag As UInteger, ByRef gsMarker As Integer) As Integer
  161.         End Function
  162.  
« Last Edit: July 24, 2013, 03:16:17 PM by TJK44 »