Author Topic: P/Invoke acedNEntSelPEx, ie select modelspace entity from paperspace  (Read 13114 times)

0 Members and 1 Guest are viewing this topic.

Chumplybum

  • Newt
  • Posts: 97
Hi all,

i know i'm in way over my head, but it seems to be the best way for me to learn anything... anyway, i'm trying to select a modelspace entity from paperspace (without being inside a floating viewport) similar to the way that the linear dimension routine and object selection in the fields dialog works.

so far i've tracked down acedNEntSelPEx, which is apparently an undocumented function that does exactly what i'm after (see http://through-the-interface.typepad.com/through_the_interface/2006/08/selecting_the_e.html, http://discussion.autodesk.com/thread.jspa?messageID=399784). The next thing i found was the entrypoint "?acedNEntSelPEx@@YAHPB_WQAJQANHQAY03NPAPAUresbuf@@IPAH@Z" via Dependency walker... which brings me to the following code, that unfortunately doesn't work :|

'start code

    Public Class PInvoke
        <CommandMethod("Test")> _
        Public Sub Test()

            Dim temp As Object

            ' int     gsmarker = -1;
            Dim gsmarker As Integer = -1
            ' ads_name  ename;
            Dim ename As Object
            ' struct resbuf *rbChain;
            Dim rbChain As ResultBuffer
            ' ads_point  selPt;
            Dim selPt As Object
            ' ads_matrix tranMat;
            Dim tranMat As Object

            temp = acedNEntSelPEx("test", ename, selPt, 0, tranMat, rbChain, 1, -1)

        End Sub


        ''' <summary>
        ''' extern int acedNEntSelPEx (const char *str, ads_name entres, ads_point ptres, int pickflag, ads_matrix xformres, struct resbuf **refstkres, unsigned int uTransSpaceFlag, int* gsmarker);
        '''
        ''' </summary>
        ''' <returns></returns>
        ''' <remarks></remarks>
        <System.Security.SuppressUnmanagedCodeSecurity()> _
        <Runtime.InteropServices.DllImport("acad.exe", CallingConvention:=Runtime.InteropServices.CallingConvention.Cdecl, CharSet:=Runtime.InteropServices.CharSet.Unicode, EntryPoint:="?acedNEntSelPEx@@YAHPB_WQAJQANHQAY03NPAPAUresbuf@@IPAH@Z")> _
        Public Shared Function acedNEntSelPEx(ByVal msg As String, ByRef entres As Object, ByRef ptres As Object, ByVal pickflag As Integer, ByVal xformres As Object, ByVal resbuf As Object, ByVal TransSpaceFlag As Integer, ByVal gsmarker As Integer) As Integer
        End Function

    End Class

'endcode


for a while i had the routine prompting to select an object (which crashed, but atleast i was getting somewhere) but now thats not even happening.
can anyone point me in the right direction as to what i'm doing wrong, or have any suggestions of what to try next???

any help would be great


cheers

Mark

Glenn R

  • Guest
Hmmm...from memory, an ads_name is represented in .NET p/invoke stuff as:
Code: [Select]
long [] yourVarNameHere;

However, I would not have thought declaring it as Object would have mattered.
What I suspect is wrong is your translation of this:

resbuf **refstkres

Unfortunately, I don't even have acad installed on this work box, let alone an IDE, so I can't check at this point in time.

Someone else might chime in before I can get to a properly configured box.

Cheers,
Glenn.

Chumplybum

  • Newt
  • Posts: 97
thanks glenn, my conversion from c++ to .net was a guess at best

i have changed some of the arguments to be ByRef and this atleast is now asking me to pick an object (or in case of my previous code 'test' is entered at the command line and ACAD is waiting for me to pick an object) but this crashes autocad as mention in the original post

'start new code
        <System.Security.SuppressUnmanagedCodeSecurity()> _
        <Runtime.InteropServices.DllImport("acad.exe", CallingConvention:=Runtime.InteropServices.CallingConvention.Cdecl, CharSet:=Runtime.InteropServices.CharSet.Unicode, EntryPoint:="?acedNEntSelPEx@@YAHPB_WQAJQANHQAY03NPAPAUresbuf@@IPAH@Z")> _
        Public Shared Function acedNEntSelPEx(ByVal msg As String, ByRef entres As Object, ByRef ptres As Object, ByVal pickflag As Integer, ByRef xformres As Object, ByRef resbuf As ResultBuffer, ByVal TransSpaceFlag As Integer, ByVal gsmarker As Integer) As Integer
        End Function

'end new code


i'll keep plugging away and see what i can come up, who knows, might even learn c++ in the process :-)


cheers

Mark


MickD

  • King Gator
  • Posts: 3636
  • (x-in)->[process]->(y-out) ... simples!
Just a guess but in this function declaration -

<System.Security.SuppressUnmanagedCodeSecurity()> _
        <Runtime.InteropServices.DllImport("acad.exe", CallingConvention:=Runtime.InteropServices.CallingConvention.Cdecl, CharSet:=Runtime.InteropServices.CharSet.Unicode, EntryPoint:="?acedNEntSelPEx@@YAHPB_WQAJQANHQAY03NPAPAUresbuf@@IPAH@Z")> _
        Public Shared Function acedNEntSelPEx(ByVal msg As String, ByRef entres As Object, ByRef ptres As Object, ByVal pickflag As Integer, ByVal xformres As Object, ByVal resbuf As Object, ByVal TransSpaceFlag As Integer, ByVal gsmarker As Integer) As Integer

the items in bold you might want to try ByRef.
ByVal will probably only work with built in types such as ints etc, even the string may need changing to ByRef as a string is not a built in type in C

Might be worth a shot.
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8702
  • AKA Daniel
I tried it a couple of times and it didn’t work, It seems to be blowing up when filling the resultbuffer.

Chumplybum

  • Newt
  • Posts: 97
ok, so i'm a little closer to disassembling the acedNEntSelPEx function... as previous posts have mentioned, its this 'ByRef resbuf As ResultBuffer' thats more than likely causing the crashes, and after reading up on double asterics in c++ (http://bytes.com/forum/thread435304.html), the double asterics is a double pointer, ie a pointer to a memory location which in turn is a pointer to another memory location.

this doesn't really get me much closer to a solution, but i was wondering if anyone knows of a .net (c# or vb) equivalent to a double pointer


cheers

Mark

MickD

  • King Gator
  • Posts: 3636
  • (x-in)->[process]->(y-out) ... simples!
ByRef resbuf As IntPtr??? (if IntPtr's are available to VB)
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

Chumplybum

  • Newt
  • Posts: 97
thanks mick, vb.net does have the intPtr's but still with the same result, ie ACAD crashes...

i have a feeling that i need to use the system.runtime.interopservices.marshal class but as i know little about c++ and the marshal class i'm just throwing darts in the dark at the moment, although i could be wrong as well.

or it may be the case, that i need to switch to c#... the following is taken from http://dnjonline.com/article.aspx?ID=mar05_vbvscsharp

Better Safe Than Sorry?
More significantly, C# gives programmers the option of using pointers. Pointers are variables which refer or ‘point’ to specific locations in memory. They are so widely used in C and C++ that many programmers may find it difficult to conceive of programming without them.
      The trouble with pointers is that they are inherently unsafe. They make it easy to corrupt memory, overwrite data and crash your applications. C# discourages the use of pointers but does permit their use within blocks of code marked with the unsafe directive.
      Code marked with the unsafe directive is ‘unmanaged’. This means that it is run as native machine code without benefiting from the services of the CLR. The use of pointers may be useful for certain special programming tasks that require the direct manipulation of memory or interaction with COM. In most cases, however, the .NET Framework provides all the services your program requires without having to resort to the hazards of unmanaged code. VB.NET is more restrictive than C# in this respect. It does not permit the use of unsafe code under any circumstances.
      Even so, it is not quite true to say that pointers can never be used. VB.NET provides access to pointers using the IntPtr type. This allows a limited range of pointer operations. For example, an IntPtr variable can be used to store a handle to a file or a window.
      If you prefer to program in VB.NET but have an occasional need to use pointers, you can, of course, add a C# or even a C++ project to your solution in order to do all the ‘dirty work’.




MickD

  • King Gator
  • Posts: 3636
  • (x-in)->[process]->(y-out) ... simples!
The easiest option (unless you work out the marshaling) is to write a managed wrapper in C++, I don't have time at present - maybe next week though.

So, do you just want the object id of the ent? That would be the easiest to pass back, from there you can get other data as required. If you want the pick point also, that's a bit harder.
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

Glenn R

  • Guest
Don't know if this will help any, but DisposableWrapper.Create for the resultbuffer?

Search on this forum - I think Dan has posted some examples of it.

Cheers,
Glenn.

Chumplybum

  • Newt
  • Posts: 97
Re: P/Invoke acedNEntSelPEx, ie select modelspace entity from paperspace
« Reply #10 on: May 08, 2008, 02:25:43 AM »
at this stage just i was just looking at getting ObjectID back, i can't see any need for the point picked, at this stage...

i have a few other ideas of how to get the objectID, but wouldn't mind getting acedNEntSelPEx sorted for future reference.
idea1: if in paperspace change to a floating viewport, select the object, then return to paperspace
idea2: pick a modelspace entity from paperspace, if nothing is selected, transform the point picked (possibly even the apperture box size) to modelspace and perform a selection based on either the point or the apperture size.

but to me, these ideas seem like a fudge at best



It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8702
  • AKA Daniel
Re: P/Invoke acedNEntSelPEx, ie select modelspace entity from paperspace
« Reply #11 on: May 08, 2008, 09:32:48 AM »

I’ll wrap acedNEntSelPEx for you this weekend, if you can wait.  :-)

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8702
  • AKA Daniel
Re: P/Invoke acedNEntSelPEx, ie select modelspace entity from paperspace
« Reply #12 on: May 08, 2008, 12:48:53 PM »
Had a little free time, the Resultbuffer was still being a pain in the arse, so I nixed it.
Anyway here is the C++ code, followed by C# code, then a little picky, then attached is the solution
and compiled dll (in the release folder) let me know if it works

Code: [Select]
   bool Utilities::NEntSelPEx
    (
    String^ prompt,
    [Out]ObjectId %objectid,
    Point3d %point,
    int pickflag,
    [Out]Matrix3d %matrix,
    [Out]ResultBuffer ^%buffer,
    unsigned int transSpaceFlag,
    int %gsmarker
    )
  {
    CString _prompt(prompt);
    ads_name _name;
    ads_point _point = {point.X,point.Y,point.Z};
    ads_matrix _matrix;
    resbuf *_buffer = NULL;
    int *_gsmarker;

    if(acedNEntSelPEx(_prompt,_name,_point,pickflag,_matrix,&_buffer,transSpaceFlag,_gsmarker) == RTNORM)
    {

      objectid = ObjectId(_name[0]);
      point = Point3d(_point[0],_point[1],_point[2]);

      array<double> ^_tmparray = gcnew array<double>(16)
      {
        _matrix[0][0],_matrix[0][1],_matrix[0][2],_matrix[0][3],
        _matrix[1][0],_matrix[1][1],_matrix[1][2],_matrix[1][3],
        _matrix[2][0],_matrix[2][1],_matrix[2][2],_matrix[2][3],
        _matrix[3][0],_matrix[3][1],_matrix[3][2],_matrix[3][3]
      };

      matrix = Matrix3d(_tmparray);

      if(_buffer != NULL)
      {
        {
          //stupid prick resbuf !@#@!#$%!#%
          //IntPtr ptr(_buffer);
          //buffer = (ResultBuffer^)DisposableWrapper::Create(ResultBuffer::typeid, ptr, true);
        }
        acutRelRb(_buffer);
      }
      gsmarker = *_gsmarker;
      return true;
    }
    else
    {
      return false;
    }
  }
.
Code: [Select]
   [CommandMethod("doit")]
    public void doit()
    {
      Editor ed = AcAp.Application.DocumentManager.MdiActiveDocument.Editor;


      string prompt = "select object";
      ObjectId id;
      Point3d point;
      int pickflag = 0;
      Matrix3d matrix;
      ResultBuffer buff;
      uint transSpaceFlag = Convert.ToUInt32(AcAp.Application.GetSystemVariable("CVPORT"));
      int marker = -1;

      try
      {
        AcMgdWrprs.Utilities.NEntSelPEx(prompt,
                                        out id,
                                        ref point,
                                        pickflag,
                                        out matrix,
                                        out buff,
                                        transSpaceFlag,
                                        ref marker);
        //
        ed.WriteMessage("\nObjectId: " + id.ToString());
        ed.WriteMessage("\nPoint3d:  " + point.ToString());
        ed.WriteMessage("\nMatrix3d: " + matrix.ToString());
        ed.WriteMessage("\nmarker:   " + marker.ToString());
      }
      catch (System.Exception ex)
      {
        ed.WriteMessage(ex.Message);
        ed.WriteMessage(ex.StackTrace);
      }
    }


MickD

  • King Gator
  • Posts: 3636
  • (x-in)->[process]->(y-out) ... simples!
Re: P/Invoke acedNEntSelPEx, ie select modelspace entity from paperspace
« Reply #13 on: May 08, 2008, 06:11:28 PM »
resbuf **_buffer perhaps???

Nice work as always Daniel.

<edit> or even IntPtr ptr(*_buffer);??
« Last Edit: May 08, 2008, 07:26:33 PM by MickD »
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

Chumplybum

  • Newt
  • Posts: 97
Re: P/Invoke acedNEntSelPEx, ie select modelspace entity from paperspace
« Reply #14 on: May 08, 2008, 07:08:02 PM »
thanks a million Daniel... and to think that i was going to try and do that :-)

for anyone who is interested in the vb code...
Code: [Select]

        Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor


        Dim prompt As String = "select object"
        Dim id As AADS.ObjectId
        Dim point As AAG.Point3d
        Dim pickflag As Integer = 0
        Dim matrix As AAG.Matrix3d
        Dim buff As AADS.ResultBuffer
        Dim transSpaceFlag As UInteger = Convert.ToUInt32(Application.GetSystemVariable("CVPORT"))
        Dim marker As Integer = -1

        Try
            AcMgdWrprs.Utilities.NEntSelPEx(prompt, id, point, pickflag, matrix, buff, _
            transSpaceFlag, marker)
            '
            ed.WriteMessage("" & Chr(10) & "ObjectId: " + id.ToString())
            ed.WriteMessage("" & Chr(10) & "Point3d: " + point.ToString())
            ed.WriteMessage("" & Chr(10) & "Matrix3d: " + matrix.ToString())
            ed.WriteMessage("" & Chr(10) & "marker: " + marker.ToString())
        Catch ex As System.Exception
            ed.WriteMessage(ex.Message)
            ed.WriteMessage(ex.StackTrace)
        End Try



every now and then i get the following error:
Attempted to read or write protected memory. This is
often an indication that other memory is corrupt.   at acedNEntSelPEx(Char* ,
Int32* , Double* , Int32 , $ArrayType$$$BY03N* , resbuf** , UInt32 , Int32* )
   at AcMgdWrprs.Utilities.NEntSelPEx(String prompt, ObjectId& objectid,
Point3d& point, Int32 pickflag, Matrix3d& matrix, ResultBuffer& buffer, UInt32
transSpaceFlag, Int32& gsmarker)


i tried giving the byref values (objectid, matrix, buffer, gsmarker) a value of nothing (null), but that hasn't fixed the error


It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8702
  • AKA Daniel
Re: P/Invoke acedNEntSelPEx, ie select modelspace entity from paperspace
« Reply #15 on: May 08, 2008, 08:36:59 PM »
resbuf **_buffer perhaps???

Nice work as always Daniel.

<edit> or even IntPtr ptr(*_buffer);??

Tried them, even tried &*_buffer, but it would throw an exception.  Probably why it’s undocumented  :mrgreen:

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8702
  • AKA Daniel
Re: P/Invoke acedNEntSelPEx, ie select modelspace entity from paperspace
« Reply #16 on: May 08, 2008, 08:40:29 PM »
thanks a million Daniel... and to think that i was going to try and do that :-)
...
every now and then i get the following error:

You’re Welcome.
I got that exception too,  I’ll goof around with it a little more and see if I can’t find out why    :-o

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8702
  • AKA Daniel
Re: P/Invoke acedNEntSelPEx, ie select modelspace entity from paperspace
« Reply #17 on: May 08, 2008, 09:59:09 PM »
give this a try

Code: [Select]
   bool Utilities::NEntSelPEx
    (
    String^ prompt,
    [Out]ObjectId %objectid,
    Point3d %point,
    int pickflag,
    [Out]Matrix3d %matrix,
    [Out]ResultBuffer ^%buffer,
    unsigned int transSpaceFlag,
    int %gsmarker
    )
  {
    CString _prompt(prompt);
    ads_name _name;
    ads_point _point = {point.X,point.Y,point.Z};
    ads_matrix _matrix;
    resbuf *_buffer = NULL;
    int _gsmarker = gsmarker;

    if(acedNEntSelPEx(_prompt,_name,_point,pickflag,_matrix,&_buffer,transSpaceFlag,&_gsmarker) == RTNORM)
    {

      objectid = ObjectId(_name[0]);
      point = Point3d(_point[0],_point[1],_point[2]);

      array<double> ^_tmparray = gcnew array<double>(16)
      {
        _matrix[0][0],_matrix[0][1],_matrix[0][2],_matrix[0][3],
        _matrix[1][0],_matrix[1][1],_matrix[1][2],_matrix[1][3],
        _matrix[2][0],_matrix[2][1],_matrix[2][2],_matrix[2][3],
        _matrix[3][0],_matrix[3][1],_matrix[3][2],_matrix[3][3]
      };

      matrix = Matrix3d(_tmparray);

      if(_buffer != NULL)
      {
        IntPtr ptr(_buffer);
        buffer = (ResultBuffer^)DisposableWrapper::Create(ResultBuffer::typeid, ptr, true);
      }
      gsmarker = _gsmarker;
      return true;
    }
    else
    {
      return false;
    }
  }

Code: [Select]
   [CommandMethod("doit")]
    public void doit()
    {
      Editor ed = AcAp.Application.DocumentManager.MdiActiveDocument.Editor;

      string prompt = "select object";
      ObjectId id;
      Point3d point;
      int pickflag = 0;
      Matrix3d matrix;
      ResultBuffer buff;
      uint transSpaceFlag = Convert.ToUInt32(AcAp.Application.GetSystemVariable("CVPORT"));
      int marker = -1;

      try
      {
        if (AcMgdWrprs.Utilities.NEntSelPEx(prompt,
                                         out id,
                                         ref point,
                                         pickflag,
                                         out matrix,
                                         out buff,
                                         transSpaceFlag,
                                         ref marker) == true)
        {
          //
          ed.WriteMessage("\nObjectId: " + id.ToString());
          ed.WriteMessage("\nPoint3d:  " + point.ToString());
          ed.WriteMessage("\nMatrix3d: " + matrix.ToString());
          ed.WriteMessage("\nmarker:   " + marker.ToString());

          if (buff != null)
          {
            ed.WriteMessage("\nBuffer:   " + marker.ToString());
            foreach (TypedValue e in buff)
            {
              ed.WriteMessage(e.ToString());
            }
          }
        }
      }
      catch(System.Exception ex)
      {
        ed.WriteMessage(ex.Message);
        ed.WriteMessage(ex.StackTrace);
      }
    }


Chumplybum

  • Newt
  • Posts: 97
Re: P/Invoke acedNEntSelPEx, ie select modelspace entity from paperspace
« Reply #18 on: May 08, 2008, 11:53:22 PM »
tried it, and it works a treat

thanks heaps


Cheers

Mark

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8702
  • AKA Daniel
Re: P/Invoke acedNEntSelPEx, ie select modelspace entity from paperspace
« Reply #19 on: May 09, 2008, 12:00:45 AM »
tried it, and it works a treat

thanks heaps


Cheers

Mark

Great, Glad it works  :laugh:

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8702
  • AKA Daniel
Re: P/Invoke acedNEntSelPEx, ie select modelspace entity from paperspace
« Reply #20 on: May 11, 2008, 09:17:14 AM »
FYI, Tony posted how to p/invoke acedNEntSelPEx here
http://discussion.autodesk.com/thread.jspa?messageID=5928092&#5928092

ahlzl

  • Guest
Re: P/Invoke acedNEntSelPEx, ie select modelspace entity from paperspace
« Reply #21 on: June 02, 2009, 08:02:17 AM »
FYI, Tony posted how to p/invoke acedNEntSelPEx here
http://discussion.autodesk.com/thread.jspa?messageID=5928092&#5928092


Daniel, I run the code, but fail.
are you OK?

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8702
  • AKA Daniel
Re: P/Invoke acedNEntSelPEx, ie select modelspace entity from paperspace
« Reply #22 on: June 02, 2009, 08:10:05 AM »
I'm doing just dandy, I had a nice Ribeye of Yak and a baked patato for dinner.  :-)
What code are you having problems with, Mine or Tony's? What cad version are you using? Are you getting an error message?

ahlzl

  • Guest
Re: P/Invoke acedNEntSelPEx, ie select modelspace entity from paperspace
« Reply #23 on: June 02, 2009, 08:45:13 AM »
thanks,Daniel.

I run this code, fail! VS2008 + AutoCAD 2009
Code: [Select]
using System;
using System.Runtime.InteropServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;

namespace Namespace1
{
    public static class NestedPickSample
    {
        [CommandMethod("NESTEDPICKTEST")]
        public static void acedNEntSelPExTest()
        {
            Int64 adsname = 0;
            Point3d picked;
            Matrix3d xform;
            IntPtr resbuf = IntPtr.Zero;
            int gsmarker = 0;
            int result = acedNEntSelPEx("Pick something:", out adsname,
            out picked, 0, out xform, out resbuf, 0, out gsmarker);

            if (result == 5100)
            {
                Prompt("Success: ");

                // Dump contents of resultbuffer:

                ResultBuffer buffer = (ResultBuffer)DisposableWrapper.Create(
                typeof(ResultBuffer), resbuf, true);
                int i = 0;
                foreach (TypedValue v in buffer)
                    Prompt("element[{0}]: ({1} {2})",
                    i++, v.TypeCode, v.Value.ToString());

                buffer.Dispose();
            }
            Console.Write(0);
        }

        private static void Prompt(string msg, params object[] args)
        {
            Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager
            .MdiActiveDocument.Editor.WriteMessage(msg, args);
        }

        // This may get mangled by this crappy news server:
        [DllImport("acad.exe",
        EntryPoint = "?acedNEntSelPEx@@YAHPB_WQAJQANHQAY03NPAPAUresbuf@@IPAH@Z",
        CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]

        extern static int acedNEntSelPEx(string prompt,  
        out Int64 adsname,
        out Point3d picked,
        int pickflag,
        out Matrix3d transform,
        out IntPtr resbuf,
        uint transSpaceFlag,
        out int gsMarker);
    }
}

« Last Edit: June 02, 2009, 10:30:37 AM by ahlzl »

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8702
  • AKA Daniel
Re: P/Invoke acedNEntSelPEx, ie select modelspace entity from paperspace
« Reply #24 on: June 02, 2009, 10:06:07 AM »
Just a guess, you might need to test to see if resbuf == IntPtr.Zero before creating ResultBuffer buffer

ahlzl

  • Guest
Re: P/Invoke acedNEntSelPEx, ie select modelspace entity from paperspace
« Reply #25 on: June 02, 2009, 10:26:50 AM »
Just a guess, you might need to test to see if resbuf == IntPtr.Zero before creating ResultBuffer buffer
success!
thanks Daniel again!

ahlzl

  • Guest
new question for acedNEntSelPEx
« Reply #26 on: June 02, 2009, 09:35:50 PM »
I run Daniel's code for acedNEntSelPEx, OK.
I run Tony's code for acedNEntSelPEx, OK.

but how to get objectid?

Daniel's code:
ed.WriteMessage("\nObjectId: " + id.ToString());  OK!


Tony's code:
int result = acedNEntSelPEx("\nPick something:", out adsname, out picked, 0, out xform, out resbuf, 0, out gsmarker);

adsname is Int64, is not Int64[], how get objectid from the adsname?  thanks!

« Last Edit: June 02, 2009, 09:40:13 PM by ahlzl »

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8702
  • AKA Daniel
Re: P/Invoke acedNEntSelPEx, ie select modelspace entity from paperspace
« Reply #27 on: June 03, 2009, 01:38:42 AM »
Try this code, I did not have a chance to test it

Code: [Select]
using System;
using System.Runtime.InteropServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;

namespace Namespace1
{
    public static class NestedPickSample
    {
        [CommandMethod("doit")]
        public static void acedNEntSelPExTest()
        {
            ObjectId id = new ObjectId();
            long[] adsname = {0,0};
            Point3d picked;
            Matrix3d xform;
            IntPtr resbuf = IntPtr.Zero;
            int gsmarker = 0;
            int result = acedNEntSelPEx("Pick something:",adsname,
            out picked, 0, out xform, out resbuf, 0, out gsmarker);

            if (result == 5100)
            {
                if (resbuf != IntPtr.Zero)
                {
                    ResultBuffer buffer = (ResultBuffer)DisposableWrapper.Create(
                    typeof(ResultBuffer), resbuf, true);
                    int i = 0;
                    foreach (TypedValue v in buffer)
                        Prompt("element[{0}]: ({1} {2})",
                        i++, v.TypeCode, v.Value.ToString());

                    buffer.Dispose();
                }
                acdbGetObjectId(ref id, adsname);
                Prompt("\nId{0}",id);
            }
        }

        private static void Prompt(string msg, params object[] args)
        {
            Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager
            .MdiActiveDocument.Editor.WriteMessage(msg, args);
        }

        [DllImport("acdb17.dll", CallingConvention = CallingConvention.Cdecl)]
        private static extern int acdbGetObjectId(ref ObjectId objId, long[] name);   

        [DllImport("acad.exe",
        EntryPoint = "?acedNEntSelPEx@@YAHPB_WQAJQANHQAY03NPAPAUresbuf@@IPAH@Z",
        CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]

        extern static int acedNEntSelPEx(string prompt,
        long[] adsname,
        out Point3d picked,
        int pickflag,
        out Matrix3d transform,
        out IntPtr resbuf,
        uint transSpaceFlag,
        out int gsMarker);
    }
}


ahlzl

  • Guest
Re: P/Invoke acedNEntSelPEx, ie select modelspace entity from paperspace
« Reply #28 on: June 03, 2009, 02:31:24 AM »
thank you, great Daniel!

I bethink of acdbGetObjectId, but I hidebound to long[] adsname and out Int64 adsname. :x

thanks again!