TheSwamp
Code Red => .NET => Topic started by: It's Alive! on June 09, 2009, 11:44:21 PM
-
This is is a continuation if this thread http://www.theswamp.org/index.php?topic=21601.0 , but since the changes are significant,
I thought I might start a new thread. RxNet is compiled against BRX instead of SDS/DRX, this means you will need Bricscad pro for
these modules to work. As of now the lisp functions only work with 9.3.10 or newer,
This project is not an attempt to wrap the BRX sdk, the goal is to provide an in process .NET interface to Bricscad's com API.
The ODA has already wrapped DWGDirect so I'm sure it wont be too long before there is a more complete .NET SDK to party with.
Instructions,
1. Run the installer
2. When Starting a New project, reference all three DLLs.
3. Also It is *very important* to set the property, 'Copy Local' to 'False' or your app could *fail*.
netload or (lspnetload "path") your dll
I have put a few sample functions/methods in a c# project.
note the name spaces
enjoy
This project is now dead
-
Hi Daniel,
I've been trying to NETLOAD your new stuff into Bricscad Pro 9.2.15, but it doesn't seem to like it.
I get folowing output on Netloading the RxNetSample.dll:
: netload
Failed RETLIST , 1000
Failed RETTV , 1001
Failed RETINT , 1002
Failed RETREAL , 1003
Failed RETSTR , 1004
Failed RETPT , 1005
Failed TOBASE64 , 1006
Failed FROMBASE64 , 1007
Failed LISPFORM , 1008
Any clues?
Helios
-
Right, that's the module trying to load functions with the [LispFunction] attribute, which only works with 9.3.5(currently in beta) or newer,
you can ignore those errors, or comment out those attributes.
The Command methods, should work. :-)
-
I finally figured out how to hide a .Net form and give control to the editor, a must for the getXXX functions like GetDistance
the form
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using BricscadApp;
namespace RxNetSample
{
public partial class FormHide : Form
{
//native methods we need to invoke
[DllImport("user32.dll")]
static extern IntPtr SetFocus(IntPtr hWnd);
[DllImport("user32.dll")]
static extern bool EnableWindow(IntPtr hWnd, bool bEnable);
[DllImport("Brx.DLL", CallingConvention = CallingConvention.Cdecl)]
private extern static IntPtr adsw_acadMainWnd();
//
AcadApplication application;
AcadDocument document;
public FormHide()
{
InitializeComponent();
application = RxNet.ApplicationServices.Application.AcadApplication as AcadApplication;
if (application == null) {throw new System.Exception("Could Not Get Application"); }
document = application.ActiveDocument;
}
private void button1_Click(object sender, EventArgs e)
{
//use this to hide your form and give control to Bricscad
IntPtr wndMain = adsw_acadMainWnd();
this.Hide();
EnableWindow(wndMain, true);
SetFocus(wndMain);
try
{
double[] pt1 = (double[])document.Utility.GetPoint(null, "\nGetPoint");
double dist = document.Utility.GetDistance(pt1, "\nGet Next Point");
System.Windows.Forms.MessageBox.Show(dist.ToString());
}
catch (System.Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.Message);
}
//show our form
EnableWindow(wndMain, false);
this.Show();
}
}
}
showing the form
[CommandMethod("doit")]
public static void doit()
{
try
{
// Note Application.ShowModalDialog(..)
// will set the owner, the Icon for you and the following to false
// ShowInTaskbar, MinimizeBox and MaximizeBox;
FormHide form = new FormHide();
Application.ShowModalDialog(form);
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.Message);
}
}
I updated dlls in the fisrt post
-
It seems that p/invoking the native getXXX functions give a little more control than the ActiveX versions. here is a sample
-
I posted updated DLL's, compiled with the latest release of Bricscad, the lisp function attribute ought to work now
-
Here is an installer that will Auto-load the required DLLs for RxNet ( for versions of Bricscad that support auto-loading via the registry)
-
:-o RxNet doesn't load in Bricscad V10-Beta. Wouldn't you know it, right after I decided to .Net some of old stuff from VBA & Lisp.
Hope your thinking of upgrading RxNet. What I did complete in V9 worked great!! (except radiobuttons on forms). I sure appreciate
all the effort you must have put into providing this program along with DocTabs.
-
Hi Jerry,
I'm working on getting all my goodies working with v10. shouldn't be too long :)
-
Ok I think I have this working. :laugh:
Since the Type Libraries have not been renamed between V9 and V10, it's a little hard to explicitly reference these with a side by side install.
I think the solution is to preload the assemblies that may have versioning problems. This may prevent the need for recompiling.
I changed the paths, the V9 DLLs are now installed in RxNet\v9 and V10 in RxNet\v10 so you must uninstall any old versions first.
Again since the com assemblies are preloaded, it should not matter which one you reference in your project unless you are referencing a new feature.
Remember Copy Local to False!!!
Please let me know if this works , doesn't work.... I gotsta know!!
Chime in if you are using this project, If I know people are using it then I will be more inclined to add stuff to it.
Bricsys has renamed the Brx DLL, so if your p/invoking you will need to change Brx to Brx10 and recompile
-
:-D It works!! Thanks much. Now back to trying to convert System.__ComObject to double or string, but that's another story.
-
:-D It works!! Thanks much.
good deal!
Now back to trying to convert System.__ComObject to double or string, but that's another story.
post your function, so I can have a look!
Thanks a ton
Daniel
-
Here is my function as it now exists. It has been in many forms, with somewhat the same results. As you see I'm using some data from
Excel to lookup values. The result comes back as an object, which I can easily put into other cells of excel, but can't seem to do
anything with it in this application. (Exception from HRESULT:0x800A03EC)
If I use object as the return type, then Convert.toString, I end up with "System.__Object" as my label text in Bricscad.
public class findbeam
{
[ComVisibleAttribute(true)]
public string FindBeam(double dist2, double w, double V, double M,double wthick)
{
object missing = System.Reflection.Missing.Value;
//object newTemplate = false;
//object docType = 0;
//object isVisible = true;
Excel._Application ExcelApp = new Excel.ApplicationClass();
ExcelApp.Visible = false;
Workbook objBook = ExcelApp.Workbooks._Open("C:\\Beam Data\\Wood.xls", Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing);
Worksheet objSheet = (Worksheet)objBook.Sheets["Sheet1"];
ExcelApp.Visible = true;
ExcelApp.WindowState = XlWindowState.xlMinimized;
objSheet.Cells[12, 15] = w;
Range rang;
int off;
if (wthick < 5.0)
{
rang = objSheet.get_Range("I5", "I10");
off = 5;
}
else
{
rang = objSheet.get_Range("I11", "I15");
off = 11;
}
int Vrow = (int) ExcelApp.WorksheetFunction.Match(V, rang, 1);
Range ranga = objSheet.get_Range(objSheet.Cells[Vrow + off, 3], missing);
//double b = (double)ranga.get_Value(missing);
double b = Convert.ToDouble(ranga.Value2);
objSheet.Cells[2, 1] = b;
ranga = objSheet.get_Range(objSheet.Cells[Vrow + off, 4], missing);
double d = Convert.ToDouble(ranga.Value2);
objSheet.Cells[3, 1] = d;
string dbeam = Convert.ToString(ranga.Value2);
objSheet.Cells[4, 1] = dbeam;
//dbeam = Convert.ToString(dbeam);
//objBook.Close("Save", "C:\\Beam Data\\Wood.xls", Type.Missing);
//-------------------------
//Form1 frm = new Form1();
//frm.txtbx1text = (dist2 / 12.0).ToString("F2");
//frm.ShowDialog(frm);
return dbeam;
}
}
Hope the code doesn't offend you too much. It's pieces from here and there.
Thanks for looking.
-
Ok I think I see what's going on, you need to iterate through the range (a 2D array of rows and columns )
and append the values to a string, I like to use the StringBuilder class.
see if this sample give you any hints
using System;
using System.Runtime.InteropServices;
using System.Text;
using BricscadApp;
using Microsoft.Office.Interop.Excel;
using RxNet.Runtime;
using Excel = Microsoft.Office.Interop.Excel;
namespace RxNetTemplate
{
public class ExecMethods
{
[CommandMethod("doit")]
public static void doit()
{
AcadApplication application =
RxNet.ApplicationServices.Application.AcadApplication as AcadApplication;
if (application == null)
throw new System.Exception("Could Not Get Application");
AcadDocument document = application.ActiveDocument;
object missing = System.Reflection.Missing.Value;
Excel._Application ExcelApp = new Excel.ApplicationClass();
ExcelApp.Visible = false;
Workbook objBook = ExcelApp.Workbooks._Open("C:\\Wood.xls", Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing);
Worksheet objSheet = objBook.Sheets["Sheet1"] as Worksheet;
try
{
ExcelApp.Visible = true;
ExcelApp.WindowState = XlWindowState.xlMinimized;
Range range = objSheet.get_Range("I1", "I5");
document.Utility.Prompt(string.Format("\n{0}", RangeToString(range)));
}
catch (System.Exception ex)
{
document.Utility.Prompt(ex.Message);
}
finally
{
ExcelApp.Quit();
Marshal.ReleaseComObject(objSheet);
Marshal.ReleaseComObject(objBook);
Marshal.ReleaseComObject(ExcelApp);
}
}
//
public static string RangeToString(Range range)
{
object[,] values = range.get_Value
(Excel.XlRangeValueDataType.xlRangeValueDefault) as object[,];
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= values.GetUpperBound(0); i++)
{
sb.Append("\n"); // new line for each row
for (int j = 1; j <= values.GetUpperBound(1); j++)
{
sb.Append(string.Format("{0} ", values[i, j]));
}
}
return sb.ToString();
}
}
}
-
Tne iteration is really not part of the problem. I am really using the Match function to return a single cell and then wanting to use the cell value
as a label (AcadMText.Text) later. I believe the problem is that Excel (V2002) returns a com.object (not System.Object)that .net does not support.
For example, the (string) dbeam = objSheet.Cells[1,2].toString yields - "Cannot convert method group 'ToString' to non-delegate type 'string'.
Did you intend to invoke the method?" This Excel cell object value, which is "4x8", refuses to be converted to a string and Mtext is expecting a string type.
In a nutshell:
//Tried this
//object dbeam = ranga.get_Value(Excel.XlRangeValueDataType.xlRangeValueDefault) as object;
//and this
object dbeam = ranga.Value2;
StringBuilder sb = new StringBuilder();
sb.Append(string.Format("{0} " ,dbeam));
yields--> HRESULT:0x800A03EC as before. Probably need to upgrade Excel to get good interop (don't have the same as your's), but think I'll look OpenOffice first.
Thanks for the help. I did pickup some ideas for further down the road.
-
Try the RangeToString function, just see what happens
string dbeam = RangeToString(ranga);
-
I don't have such a function (RangeToString)! I think the interop for MicrosoftOffice 10.0 is missing this item.
I might try using SQL or like I mentioned, OpenOffice. Discovered they have a C# library for connecting.
my using statements are:
using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Text; using System.Collections;
using System.ComponentModel; using Microsoft.Office.Interop.Excel; using RxNet.ApplicationServices; using RxNet.DatabaseServices;
using RxNet.Runtime; using RxNet.Geometry; using BricscadApp; using BricscadDb;
I'll let you know how OO goes. From what I see it passes cell contents as the type intended, rather than com object. Might do the trick.
-
This one
string dbeam = RangeToString(ranga);
I just want to see what happens :-)
public static string RangeToString(Range range)
{
object[,] values = range.get_Value
(Excel.XlRangeValueDataType.xlRangeValueDefault) as object[,];
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= values.GetUpperBound(0); i++)
{
sb.Append("\n"); // new line for each row
for (int j = 1; j <= values.GetUpperBound(1); j++)
{
sb.Append(string.Format("{0} ", values[i, j]));
}
}
return sb.ToString();
}
I would recommend using SQL too, maybe SQLite http://sqlite.phxsoftware.com/
-
That one doesn't exist in any of my references. That's what I mean by needing an
upgrade of Excel. The registered application library under com, nor the downloaded
interop for Excel 10 contains the function RangeToString. Did a search on the objects
in the using statements..nada!
Think I'll look into SQL, OO appears quite a undertaking for my rotten brain. First I thought
I'd watch a few tutorials on the SQLExpress databases as it comes with C# and runs in IDE.
-
Just add the function to your class just like this..
public class findbeam
{
public static string RangeToString(Range range)
{
object[,] values = range.get_Value
(Excel.XlRangeValueDataType.xlRangeValueDefault) as object[,];
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= values.GetUpperBound(0); i++)
{
sb.Append("\n"); // new line for each row
for (int j = 1; j <= values.GetUpperBound(1); j++)
{
sb.Append(string.Format("{0} ", values[i, j]));
}
}
return sb.ToString();
}
[ComVisibleAttribute(true)]
public string FindBeam(double dist2, double w, double V, double M, double wthick)
{
object missing = System.Reflection.Missing.Value;
//object newTemplate = false;
//object docType = 0;
//object isVisible = true;
Excel._Application ExcelApp = new Excel.ApplicationClass();
ExcelApp.Visible = false;
Workbook objBook = ExcelApp.Workbooks._Open("C:\\Beam Data\\Wood.xls", Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing);
Worksheet objSheet = (Worksheet)objBook.Sheets["Sheet1"];
ExcelApp.Visible = true;
ExcelApp.WindowState = XlWindowState.xlMinimized;
objSheet.Cells[12, 15] = w;
Range rang;
int off;
if (wthick < 5.0)
{
rang = objSheet.get_Range("I5", "I10");
off = 5;
}
else
{
rang = objSheet.get_Range("I11", "I15");
off = 11;
}
int Vrow = (int)ExcelApp.WorksheetFunction.Match(V, rang, 1);
Range ranga = objSheet.get_Range(objSheet.Cells[Vrow + off, 3], missing);
return RangeToString(ranga);
}
}
-
:cry: Same Exception From HRSESULT:0x800A03EC !
Since StringBuilder I assume is in the form of .append(object) and returning string, the conversion
from comobject to string is failing? Wonder if there is some sort of Delegate that could be contrived?
BTW Saw that SQLite works in C#Express version, maybe I'll give it a try.
-
Does mean anything to you http://edndoc.esri.com/arcobjects/9.0/ArcGISDevHelp/DevelopmentEnvs/DotNet/SystemComObject.htm (http://edndoc.esri.com/arcobjects/9.0/ArcGISDevHelp/DevelopmentEnvs/DotNet/SystemComObject.htm)
-
PM me your whole project and your excel doc, and I will test it :-)
-
BTW Saw that SQLite works in C#Express version, maybe I'll give it a try.
Jerry, do you have a link to the .NET library ?
or the article,
or where you saw that ?? :)
Regards
Kerry
-
this? http://sqlite.phxsoftware.com/
-
this? http://sqlite.phxsoftware.com/
Thanks Dan,
That looks interesting.
I'll have a good look on the weekend :)
ps:
I'd like to use your lispyLibrary, but need something (more)transparent and transportable ...
[ the old ARX life expectancy thingie has come into the equation] :)
-
Thanks Dan,
That looks interesting.
I'll have a good look on the weekend :)
I haven't used it myself but it looks cool.
ps:
I'd like to use your lispyLibrary, but need something (more)transparent and transportable ...
[ the old ARX life expectancy thingie has come into the equation] :)
No worries, I have made the tool as transparent as possible by posting the source. :wink:
-
........... I have made the tool as transparent as possible by posting the source. :wink:
Yes, I know, and I appeciate it :)
-
I have updated the installers and the sample in the first post in this thread, added a method to hide dialogs
during a getXXX function call, example.
private void button_Click(object sender, EventArgs e)
{
//use this to hide your form and give control to Bricscad
this.Hide();
RxNet.ApplicationServices.Application.MainWindowIsFocused = true;
your GetXXX function
//restore the form
RxNet.ApplicationServices.Application.MainWindowIsFocused = false;
this.Show();
}
See the included sample. I will be wrapping more in the Point, Vector, and Marix classes in the coming days as these are pretty handy to have
-
I made a couple of changes
if you put a file called RxLoader.txt in the same folder as RxNet.DLL, RxNet will try to run though and load the assemblies listed in the file.
here is the format
; comment
; put the full path of the dll you want to load with RxNet
C:\Dev\Projects\BrxNet\RxNetSample\RxNetSample\bin\Release\RxNetSample.dll
I hacked out wrappers for Vector2d, Point2d, Matrix2d , Vector3d, Point3d, Matrix3d.
I'm still working on testing each function, I sure could use a little help.... :evil:
Since ActiveX entities take a double[4][4] array as the parameter for transformby
I add a member functions To4x4Array() and static Matrix3d.From4x4Array to help with the conversions.
I.e
using System;
using BricscadApp;
using BricscadDb;
using RxNet.ApplicationServices;
using RxNet.Geometry;
using RxNet.Runtime;
namespace RxNetSample
{
public static class DBGCommands
{
[CommandMethod("tran")]
public static void DBGtran()
{
AcadApplication application = Application.AcadApplication as AcadApplication;
if (application == null)
throw new System.Exception("Could Not Get Application");
AcadDocument Doc = application.ActiveDocument;
AcadSelectionSet selection = Doc.SelectionSets.Add("MySel");
try
{
Vector3d vec = new Point3d(100, 100, 0).GetAsVector();
Matrix3d mat = Matrix3d.Displacement(vec);
int[] var = new int[] { 0 };
object[] val = new object[] { "POINT,LINE,CIRCLE" };
selection.SelectOnScreen(var, val);
foreach (AcadEntity e in selection)
e.TransformBy(mat.To4x4Array()); //<--------
}
catch (System.Exception ex)
{
PInvokeMethods.sds_printf(
String.Format("\n{0}:\n{1}",ex.Message, ex.StackTrace));
}
finally
{
selection.Delete();
}
}
}
}
-
Fixed a bug that could prevent commands from running,
added a new namespace RxNet.RxGlobal and added a few global functions :-)
-
I ran sandcastle on the runtime callable wrappers for Bricscad, I think it may be too big to attach to the installer as it 23mb. I may ask to post it at the Bricscad DEV site... if you need a copy, I can swamp-express it !?!
-
huh ?
Bricscad uses ACAD classes ??
-
huh ?
Bricscad uses ACAD classes ??
Those are aliases for code compatibility, I if I were to have scrolled down a bit before taking the snapshot they would have been prefixed with ODA
-
Thanks Daniel .. that makes sense now :)
-
made some changes for v1.0.0.6
Combined the V9 and V10 installers into a single installer that provides options on which version(s) to install.
Fixed a bug in the locating the RxLoader.txt file
wrapped a few more global functions
:-)
-
Added a few more global functions
Ecs2Ucs
Ecs2Wcs
Ucs2Ecs
Ucs2Wcs
Wcs2Ecs
Wcs2Ucs
Polar
DisplayPreviewFromDwg
etc.
Please uninstall, any previous versions before installing this version, This should be the last time we need to do this, after this new versions will overwrite the old, unless I goof
-
Added support for V10 release :-)
-
just a test adding a menu to the newly released Bricscad v10 :-)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using RxNet.ApplicationServices;
using RxNet.DatabaseServices;
using RxNet.Runtime;
using RxNet.Geometry;
using RxNet.RxGlobal;
using BricscadApp;
using BricscadDb;
namespace RxNet10Play
{
public static class ExecMethods
{
[CommandMethod("MyMenu")]
public static void mymenu()
{
try
{
AcadApplication app =
Application.AcadApplication as AcadApplication;
if (app == null)
throw new Exception("Could Not Get Application");
//a list of menu items and command names
List<KeyValuePair<String, String>> menuItems =
new List<KeyValuePair<string, string>>();
menuItems.Add(new KeyValuePair<String,String>("Menu1","cmd1"));
menuItems.Add(new KeyValuePair<String,String>("Menu2","cmd2"));
menuItems.Add(new KeyValuePair<String,String>("Menu3","cmd3"));
if (AddMenu("MyMenu", menuItems, app))
GlobalFunctions.Printf("\ndone");
}
catch (Exception ex)
{
GlobalFunctions.Alert(
String.Format("{0}\n{1}", ex.Message, ex.StackTrace));
}
}
public static bool AddMenu(String menuName,
List<KeyValuePair<String, String>> items,
AcadApplication app)
{
// ToDo add error checking for arguments
//get the index of the BRICSCAD menu group
int index = 0;
AcadMenuGroups currentGroups =
app.MenuGroups as AcadMenuGroups;
foreach (var item in currentGroups)
{
AcadMenuGroup grp = item as AcadMenuGroup;
if(grp.Name.Equals("BRICSCAD",
StringComparison.CurrentCultureIgnoreCase))
break;
index++;
}
//get the menu group
AcadMenuGroup currentGroup =
app.MenuGroups.Item(index) as AcadMenuGroup;
//run through the menu group to check if our group exists
foreach (AcadPopupMenu item in currentGroup.Menus)
{
if (item.NameNoMnemonic.Equals(menuName,
StringComparison.CurrentCultureIgnoreCase))
return false;
}
// add our menu
AcadPopupMenu menu =
currentGroup.Menus.Add(menuName);
// add the macros
foreach (var item in items)
menu.AddMenuItem(menu.Count, item.Key, item.Value);
// insert the menu
currentGroup.Menus.InsertMenuInMenuBar
(menuName, currentGroup.Menus.Count);
return true;
}
}
}
-
Fixed a few internal issues, no major changes, attached to the first post in this thread
-
Daniel,
I haven't tried your latest build, but I made a stupid mistake and downloaded C# 2010 Express and decided to try it in mid project.
Since I'm not a programmer, and sometimes I don't think ahead too far, I still should have known that C# 4.0 wasn't going to create
a dll that Bricscad could swallow. The bare bones was running ok using C# 2008 Express and it compiled without errors with 2010 but..
choked at netload of my assembly. My assembly is actually your sample with a couple added extensions, a commandmethod and some
tinkering with datagridview. So I was wondering if you can compile and run your sample using your VS 2010. Any comments are appreciated.
BTW I shelved the Excel project after finally getting it to run when I realized how slow the connection was. Thinking about SQL still.
-
Jerry,
You can 'try' using this version (attached) with VS 2010 projects. I have not done a lot of testing with this version, so let me know how it works for you
-
linq 8-)
[CommandMethod("test01")]
public static void test01()
{
var app = Application.AcadApplication as AcadApplication;
var ents = app.ActiveDocument.ModelSpace.
OfType<AcadLine>().Where(line => line.Length > 1.2);
foreach (var e in ents)
e.Layer = "0";
}
-
:-) :lol:
I was wondering when I'd be seeing something like that ;-)
-
Just having a bit of fun, goofing with the new dynamic keyword a little.
[CommandMethod("test02")]
public static void test02()
{
var application = Application.AcadApplication as AcadApplication;
var ents = application.ActiveDocument.ModelSpace.
OfType<AcadBlockReference>().Where(item =>
item.Name.Equals("*u31", StringComparison.CurrentCultureIgnoreCase)).ToList();
var attrefs = new List<dynamic>();
ents.ForEach(item => attrefs.AddRange((dynamic)item.GetAttributes()));
attrefs.ForEach(item => application.ActiveDocument.
Utility.Prompt(string.Format("\n{0}",item.TextString)));
}
-
netburst
using System;
using System.Collections.Generic;
using System.Threading;
using BricscadApp;
using BricscadDb;
using RxNet.Geometry;
using RxNet.ApplicationServices;
using RxNet.Runtime;
namespace RxNetTest
{
public static class Commands
{
[CommandMethod("netburst")]
public static void netburst()
{
AcadApplication app = Application.AcadApplication as AcadApplication;
AcadDocument document = app.ActiveDocument;
AcadDatabase database = document.database;
AcadSelectionSet selection = document.SelectionSets.Add("sset");
int[] var = new int[] { 0 ,66};
object[] val = new object[] { "INSERT" ,1 };
selection.SelectOnScreen(var, val);
foreach (IAcadBlockReference blk in selection)
{
if (blk.HasAttributes)
{
IAcadBlock space = database.ObjectIdToObject(blk.OwnerID) as IAcadBlock;
foreach (AcadEntity ent in (object[])blk.Explode())
{
AcadAttribute attribute = ent as AcadAttribute;
if (attribute != null)
{
AcadText txt = space.AddText(attribute.TextString,
attribute.InsertionPoint,
attribute.Height);
txt.Alignment = attribute.Alignment;
txt.Backward = attribute.Backward;
txt.color = attribute.color;
txt.HorizontalAlignment = attribute.HorizontalAlignment;
txt.Normal = attribute.Normal;
txt.ObliqueAngle = attribute.ObliqueAngle;
txt.Rotation = attribute.Rotation;
txt.ScaleFactor = attribute.ScaleFactor;
txt.StyleName = attribute.StyleName;
txt.TextAlignmentPoint = attribute.TextAlignmentPoint;
txt.VerticalAlignment = attribute.VerticalAlignment;
txt.UpsideDown = attribute.UpsideDown;
//add what you need
attribute.Erase();
}
}
blk.Erase();
}
}
selection.Delete();
}
}
}
-
Looks like it's coming along for you Dan.
Pity that it needs to be COM (untill they get the BRX stuff wrapped.)
-
Looks like it's coming along for you Dan.
Pity that it needs to be COM (untill they get the BRX stuff wrapped.)
Thanks!
COM isn't so bad when you can use C#, you don't have to deal with variants and all that carp...
I would rather write my own API then use VBA :laugh:
FYI, I'm in the source fixing a couple of bugs I found, lf anyone needs something fixed or added, let me know
-
Looks like it's coming along for you Dan.
Pity that it needs to be COM (untill they get the BRX stuff wrapped.)
Thanks!
COM isn't so bad when you can use C#, you don't have to deal with variants and all that carp...
I would rather write my own API then use VBA :laugh:
FYI, I'm in the source fixing a couple of bugs I found, lf anyone needs something fixed or added, let me know
I'd rather YOU write the API than me use VBA also. :)
-
Talking with lisp :kewl:
(defun thisisatest (a)
(reverse a)
)
(vl-acad-defun 'thisisatest)
[CommandMethod("doit2")]
static public void doit2()
{
ResultBuffer rbOut = new ResultBuffer();
rbOut.Add(new TypedValue((int)LispDataType.Text, "thisisatest"));
rbOut.Add(new TypedValue((int)LispDataType.ListBegin));//list
rbOut.Add(new TypedValue((int)LispDataType.Int32, 1));
rbOut.Add(new TypedValue((int)LispDataType.Int32, 2));
rbOut.Add(new TypedValue((int)LispDataType.Int32, 3));
rbOut.Add(new TypedValue((int)LispDataType.Int32, 4));
rbOut.Add(new TypedValue((int)LispDataType.ListEnd)); //endlist
GlobalFunctions.Printf(string.Format("\n{0}",rbOut));
ResultBuffer rbIn = GlobalFunctions.Invoke(rbOut); // acedinvoke
GlobalFunctions.Printf(string.Format("\n{0}",rbIn));
}
-
Dan,
so you're calling a Lisp Command from C# .... that has some potential !!
Where is the GlobalFunctions definition ?
-
I thought you might like that. ^-^
the namespace is RxNet.RxGlobal. GlobalFunctions.Invoke
but don't try it yet because I have not uploaded the latest version yet
-
here is how you would do it in acad
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
using AcAp = Autodesk.AutoCAD.ApplicationServices;
[assembly: CommandClass(typeof(ExecMethod.Commands))]
namespace ExecMethod
{
public static class Commands
{
[DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl)]
extern static int acedInvoke(IntPtr rbIn, out IntPtr rbOut);
public static ResultBuffer Invoke(ResultBuffer rbIn)
{
IntPtr pRb = IntPtr.Zero;
acedInvoke(rbIn.UnmanagedObject, out pRb);
return DisposableWrapper.Create(typeof(ResultBuffer), pRb, true) as ResultBuffer;
}
[CommandMethod("doit")]
public static void MyCommand()
{
ResultBuffer rbOut = new ResultBuffer();
rbOut.Add(new TypedValue((int)LispDataType.Text, "thisisatest"));
rbOut.Add(new TypedValue((int)LispDataType.ListBegin));
rbOut.Add(new TypedValue((int)LispDataType.Int32, 1));
rbOut.Add(new TypedValue((int)LispDataType.Int32, 2));
rbOut.Add(new TypedValue((int)LispDataType.Int32, 3));
rbOut.Add(new TypedValue((int)LispDataType.Int32, 4));
rbOut.Add(new TypedValue((int)LispDataType.ListEnd));
ResultBuffer rbIn = Invoke(rbOut);
List<TypedValue> list = new List<TypedValue>(rbIn.AsArray());
list.ForEach(X =>
AcAp.Application.DocumentManager.
MdiActiveDocument.Editor.WriteMessage(X.Value.ToString()));
}
}
}
-
A warning though, some arguments may be interpreted by lisp I.e. lisp might see a list of three doubles as a RT3DPOINT, so be careful :police:
-
arx version :lol:
static void arx_doit(void)
{
resbuf *pRbOut = acutBuildList(RTSTR,_T("thisisatest"),
RTLB,
RTSHORT, 1,
RTSHORT, 2,
RTSHORT, 3,
RTSHORT, 4,
RTLE,
NULL);
resbuf *pRbIn = NULL;
acedInvoke(pRbOut,&pRbIn);
for(resbuf*pTmp = pRbIn;pTmp!=NULL;pTmp = pTmp->rbnext)
{
acutPrintf(_T("%ld"),pTmp->resval.rint);
}
acutRelRb(pRbIn);
acutRelRb(pRbOut);
}
-
Updated,
removed some of the hacks and workarounds for items that were not implemented in BRX and now are. Fixed a few bugs, wrapped a few more items. :-)
I Also modified the installer to install for all users.
-
A really quick sample of how to make a table and how to edit a cell :laugh:
-
You've been reading my mail ??
I had planned on investigating that tonight ... you just keep on doing my homework !! :wink:
-
...
I'd rather YOU write the API than me use VBA also. :)
Maybe you won't have to write anything - http://www.opendwg.org/the_oda_platform/dwgdirect.net
I'm not sure if you can just mix the assemblies in with Bricscad or not but if you could that would save a fair chunk of the work :)
-
...
I'd rather YOU write the API than me use VBA also. :)
Maybe you won't have to write anything - http://www.opendwg.org/the_oda_platform/dwgdirect.net
I'm not sure if you can just mix the assemblies in with Bricscad or not but if you could that would save a fair chunk of the work :)
I've wondered what would happen if I netloaded those. I'm not an ODA member though :|
I'm sure Bricsys will be adding em at some point though
-
I'm pretty keen to work with Bricscad but without the hlr engine (the engine used for SOLPROF etc) it is a big draw back for what I need to do.
As soon as they implement that and have the .net api I'll be there in a flash :)
-
Update: I posted a version compiled with .NET 4 (Release), see the first post in this thread. :-)
Dan
-
Daniel I get this warning in C# Express.
Warning 1 A reference was created to embedded interop assembly 'c:\Program Files\RxNet\V10\Interop.BricscadDb.10.0.dll' because of an indirect reference to that assembly created by assembly 'c:\Program Files\RxNet\V10\RxNet.dll'. Consider changing the 'Embed Interop Types' property on either assembly.
Since I am ignorant as to compiler reference jargon I was wondering if I should do as recommended to RxNet by setting to True or the Interops to false? Just figured you'd know off the top of your head.
Jerry
-
... you can remove the references to the DLLs I provided and add your own though the com tab.. use the default settings
-
Daniel
Was looking thru some of your samples in NativeMethods.cs in RxNetSamples and have a question. I see you are now using dllimport of "brx10.dll" rather than "bricscad.exe". I could not get C# express to find the file, whereas bricscad.exe - no problem. I was just invoking grdraw as it appears missing in com. Did you go to brx10.dll because the future of calling sds_grdraw (for instance) may go away in the future? or .. The function would be acedGrDraw in brx10.dll.
Do I need to copy brx10.dll to the C# project folder? Was going to be invoking grread as well, but even in lisp the function is unclear to me. Is there a buffer that needs to be flushed when tracking coords? or it just taking a snapshot and assigning to my varriable?
The routine I'm playing with is to read objects Z value on mouse over and indicate %Grade from some given point. Used it for "pioneering" roadway layout and found it handy.
-
if it's a BRX function you would p/invoke from BRX10.dll, if it's a SDS function p/invoke from Bricscad.exe. I don't think the SDS version will go away anytime soon.
Let me see what it will take to wrap these functions for you, grread might be a little difficult.
-
Hi Jerry,
I've updated install attached to the first post in this thread..
heres a sample
using System;
//
using BricscadApp;
using BricscadDb;
using RxNet.ApplicationServices;
using RxNet.Runtime;
using RxNet.RxGlobal;
using RxNet.Geometry;
using RxNet.DatabaseServices;
using RxNet.Editor;
namespace Bricscad
{
public static class Commands
{
[CommandMethod("doit")]
public static void test01()
{
var app = Application.AcadApplication as AcadApplication;
var doc = app.ActiveDocument;
try
{
bool doloop = true;
Point3d last = Point3d.kOrigin;
while (doloop)
{
GrReadResult res = GlobalFunctions.GrRead(1);
if (res.Buffer.TypeCode == (short)LispDataType.Point3d)
{
Point3d next = (Point3d)res.Buffer.Value;
GlobalFunctions.GrDraw(last, next, 6, 0);
last = next;
}
//doc.Utility.Prompt(String.Format("\n{0},{1}", res.AnswerType , res.Buffer));
if (res.Status == PromptStatus.Cancel)
doloop = false;
}
}
catch (System.Exception ex)
{
doc.Utility.Prompt(String.Format("\n{0}", ex.Message));
}
}
}
}
-
Hi Dan, any chance of updating the 1.010 version as well? I am using Delphi prism for my .NET fun and don't have access to the V4 framework. Can't wait till Bricsys support a full .NET implementation but in the mean time your libraries make things far more accessible than COM alone can. I've said it before but great work!
-
Hi Dan, any chance of updating the 1.010 version as well?
Yep, I will post it in a couple of hours 8-)
-
Hey Daniel,
I've posted it, let me know of you run into any issues.
-
Thanks Dan, are you operating out of the Tardis? That couple of hours only seemed like 20 minutes :lol:
-
Thanks a bunch!
Still wondering why I could p\invoke "bricscad.exe" but said it coun't find "brx10.dll"? So I ran dependency walker which came up with all sorts of can't finds on brx10.dll and just two on bricscad.exe. A couple of the missing dependencies were MFC and ATL which don't come in the express versions so maybe thats why? Just curious, since I would think that brx10.dll was already loaded by the time I netload my app.
Anyway this will be fun. Now I can play with all that cool grread stuff that Andrea is doing in lisp.
-
Hi Dan, is there any chance you converted the 1.01-2 version to Net 4 as well? I have tried referencing it but it wont load as VS tells me it's created with a newer runtime than I have loaded. I believe I am using 3.5; but I am new to the .Net thing and I might be doing something else incorrectly?
-
Hi Dan, is there any chance you converted the 1.01-2 version to Net 4 as well? I have tried referencing it but it wont load as VS tells me it's created with a newer runtime than I have loaded. I believe I am using 3.5; but I am new to the .Net thing and I might be doing something else incorrectly?
try it now :-)
-
Thanks a bunch!
Still wondering why I could p\invoke "bricscad.exe" but said it coun't find "brx10.dll"? So I ran dependency walker which came up with all sorts of can't finds on brx10.dll and just two on bricscad.exe. A couple of the missing dependencies were MFC and ATL which don't come in the express versions so maybe thats why? Just curious, since I would think that brx10.dll was already loaded by the time I netload my app.
Anyway this will be fun. Now I can play with all that cool grread stuff that Andrea is doing in lisp.
My Pleasure :-)
Hard to say without seeing the code, it could be that you had a bad entry point or the signature was invalid.
It's really easy for me to add these in, just holler if you need something else
-
Thanks Dan, works like a charm. I can see I have lots of hours ahead squiggling with grdraw. But first for some sleep.
-
Daniel,
Well I finally got around to playing with grread in C#. I needed to use the grclear() function to delete the tracking lines, which I P/invoked per some of your samples and it worked fine... well not really. It doesn't exactly work like lisp code.
Here is the code from your sample that I was just playing with..
[CommandMethod("doit")]
public static void test03()
{
var app = Application.AcadApplication as AcadApplication;
var doc = app.ActiveDocument;
double[] pt1 = new double[] { 0.0, 0.0, 0.0 };
double[] pt2 = new double[] { 0.0, 0.0, 0.0 };
try
{
bool doloop = true;
Point3d last = Point3d.kOrigin;
while (doloop)
{
GrReadResult res = GlobalFunctions.GrRead(1);
if (res.AnswerType == 5)
{
Point3d next = (Point3d)res.Buffer.Value;
GlobalFunctions.GrDraw(last, next, 6, 0);
}
if (res.AnswerType == 3)
{
PInvokeMethods.sds_grclear();
Point3d next = (Point3d)res.Buffer.Value;
pt1[0] = last.X; pt1[1] = last.Y; pt1[2] = last.Z;
pt2[0] = next.X; pt2[1] = next.Y; pt2[2] = next.Z;
doc.ModelSpace.AddLine(pt1, pt2);
last = next;
}
//doc.Utility.Prompt(String.Format("\n{0},{1}", res.AnswerType , res.Buffer));
if (res.Status == PromptStatus.Cancel)
doloop = false;
PInvokeMethods.sds_grclear();
}
}
catch (System.Exception ex)
{
doc.Utility.Prompt(String.Format("\n{0}", ex.Message));
}
}
and this is the method invoking call
[DllImport("Bricscad.exe", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
static internal extern int sds_grclear();
This works except none of the lines (cad segments) are visible during the grread loop. The temp line is created and erased as expected from similar lisp codings, but the drawing is not visible. Not sure how to overcome this situation. Wonder if you have any thoughts on the matter.
On another issue, how do you use 3dPoint.toArray ie, pt1 = last.toArray says NG need a delegate or something?
Anyway having fun playing in net and appreciate your schooling.
Jerry
-
The problem is that grclear clears the whole graphics screen, if you try your routine on a drawing that's already has stuff in it, everything gets cleared.
Personally, I would take a different approach, example (shows how to use the Point3d.ToArray() as well)
[CommandMethod("doit")]
public static void test04()
{
var app = Application.AcadApplication as AcadApplication;
var doc = app.ActiveDocument;
try
{
bool doloop = true;
Point3d last = Point3d.kOrigin;
Point3d next = Point3d.kOrigin;
int res = GlobalFunctions.GetPoint("\nGet Point: ", out next);
if (res == 5100)
{
last = next;
while (doloop)
{
res = GlobalFunctions.GetPoint(last, "\nGet Next Point: ", out next);
if (res == 5100)
{
doc.ModelSpace.AddLine(last.ToArray(), next.ToArray());
last = next;
}
else
{
doloop = false;
}
}
}
}
catch (System.Exception ex)
{
doc.Utility.Prompt(String.Format("\n{0}", ex.Message));
}
}
-
Actually, what I am trying to do is replicate something I pieced together in lisp. As follows
(defun C:GradeLine()
(setvar "LASTPOINT" (getpoint "\nLocate beginning grade point: "))
(setq omod (getvar "OSMODE"))
(setvar "OSMODE" 0)
(grgrade)
(setvar "OSMODE" omod)
)
(defun grgrade()
(setq pt (getvar "LASTPOINT"))
(setq grd "0.00")
(setq txtht (* (getvar "VIEWSIZE") 0.013))
(setq ent
(entmakex (list '(0 . "MTEXT")
'(100 . "AcDbEntity")
'(100 . "AcDbMText")
'(8 . "0")
'(62 . 250)
'(90 . 2)
'(63 . 7)
'(441 . 0)
'(45 . 1.15)
'(1 . "0.0")
)
)
)
(setq x (entget (entlast)))
(setq objtxt (vlax-ename->vla-object ent))
(while (eq (car (setq input (grread t 4 4))) 5)
(setq snappoint (osnap (cadr input) "_near"))
(redraw)
(if snappoint
(progn
(grdraw pt snappoint -1 0)
(setq grd (* (/ (- (caddr snappoint) (caddr pt)) (distance snappoint pt)) 100.0))
(setq x (subst (cons 63 256) (assoc 63 x) x))
(setq x (subst (cons 90 1) (assoc 90 x) x))
(entmod x)
(setq grdtxt (rtos grd 2 1))
(vlax-put-property objtxt 'TextString grdtxt)
(vlax-put-property objtxt 'InsertionPoint snappoint)
(setq txtht (* (getvar "VIEWSIZE") 0.013))
(vlax-put-property objtxt 'Height txtht)
;(setvar "MODEMACRO" grdtxt)
)
(progn
(setq x (subst (cons 63 7) (assoc 63 x) x))
(setq x (subst (cons 90 2) (assoc 90 x) x))
(entmod x)
(setq grdtxt "*")
(vlax-put-property objtxt 'TextString grdtxt)
(vlax-put-property objtxt 'InsertionPoint (cadr input))
(setq txtht (* (getvar "VIEWSIZE") 0.013))
(vlax-put-property objtxt 'Height txtht)
)
)
)
(setq input nil)
(entmake
(list (cons 0 "TEXT") (cons 10 snappoint) (cons 40 3.0) (cons 1 (rtos grd 2 2)))
)
(entmake
(list (cons 0 "LINE") (cons 10 pt) (cons 11 snappoint))
)
(entdel ent)
;(setvar "MODEMACRO" "")
(setq ret (MsgBox "Continue Grades?" "Grading" 33 10))
(if (= ret 1)
(progn
(setvar "LASTPOINT" snappoint)
(gc)
(grgrade)
)
)
)
but now that I look at it, I was using (redraw) not (grclear). In com I only see regen or am I missing it somewhere.
Anyway thanks for the look.
I should mention that this routine is for displaying grades between contours on the fly so as to allow preliminary layout of structures in steep terrain.
-
try this
namespace ExEcModule
{
public static class Commands
{
[DllImport("Bricscad.exe", CallingConvention = CallingConvention.Cdecl)]
static internal extern int sds_redraw(IntPtr ptr, int mode);
[CommandMethod("doito")]
public static void test03()
{
var app = Application.AcadApplication as AcadApplication;
var doc = app.ActiveDocument;
try
{
bool doloop = true;
Point3d last = Point3d.kOrigin;
while (doloop)
{
GrReadResult res = GlobalFunctions.GrRead(1);
switch (res.AnswerType)
{
case 5:
{
sds_redraw(IntPtr.Zero,1);
Point3d next = (Point3d)res.Buffer.Value;
GlobalFunctions.GrDraw(last, next, 6, 0);
}
break;
case 3:
{
Point3d next = (Point3d)res.Buffer.Value;
doc.ModelSpace.AddLine(last.ToArray(), next.ToArray());
last = next;
}
break;
default:
break;
}
if (res.Status == PromptStatus.Cancel)
doloop = false;
sds_redraw(IntPtr.Zero, 1);
}
}
catch (System.Exception ex)
{
doc.Utility.Prompt(String.Format("\n{0}", ex.Message));
}
}
}
}
-
I wanted to give you an example using draggen, but I didn't wrap it. :-o
I will get in there and add some of these items this week.
-
Dan, with reference to this post http://www.theswamp.org/index.php?topic=33910.msg392471#msg392471 (http://www.theswamp.org/index.php?topic=33910.msg392471#msg392471). Can you suggest how I go about debugging? I have no idea what could be conflicting with my program as the method names I've used are quite obscure and so I don't believe this is the issue. However, all routines that I run come up with the same error. I have also uninstalled all addons except your doctabs and rxnet itself. The confounding thing is the code used to run! Any help would be appreciated.
-
I'm a little confused, by routine do you mean lisp routines or .net routines?
do you have a file in your Program files\RxNet\VX called RxLoader.txt?
is so is it loading anything?
Are you running the .NET4 version or .NET2 version?
-
I have uploaded new builds that should a give a tad more info if an exception is thrown.
A tip, put a try catch at "every" command function, if you don't your code will be harder to debug example
//gets the name of everything that loaded for .NET
[CommandMethod("GetNetItems")]
public static void GetNetItems(int i)
{
try
{
foreach (string assem in RxNet.ApplicationServices.ApplicationData.loadedAssemblies)
{
RxNet.RxGlobal.GlobalFunctions.Printf("\nAssembly name {0}", assem);
}
foreach (KeyValuePair<string,object> cmd in RxNet.ApplicationServices.ApplicationData.loadedCmdMethods)
{
RxNet.RxGlobal.GlobalFunctions.Printf("\ncommand name {0}", cmd.Key);
}
foreach (KeyValuePair<string, short> cmd in RxNet.ApplicationServices.ApplicationData.loadedLispMethods)
{
RxNet.RxGlobal.GlobalFunctions.Printf("\nLisp name {0}", cmd.Key);
}
}
catch (System.Exception ex)
{
RxNet.RxGlobal.GlobalFunctions.Printf("\n{0}\n{1}",ex.Message,ex.StackTrace);
}
}
-
See if you can follow this, look at the section for debugging and make the appropriate changes I.e path to Bricscad.exe
this will allow you to setp though the code
-
First of all thanks for the advice Daniel. Turned out to be a newbie mistake which I will elaborate on a bit later when I have more time. Seems I have become accustomed to my own infalibility :lol: Adding The try.. catch statements found the error quick smart --> really don't know why I didn't go there first without prompting doh!@##$
-
Awesome, glad you found the problem :-)
-
Daniel,
finally got the time to port a few of our existing routines to C# and use your RxNet wrapper to get the communications going.
I love the speed! :lol:
Tasks that used to take several minutes complete in seconds...
I wonder why so few have downloaded and tried this stuff so far.
One question:
I have put a reference to my DLL in RxLoader.Txt and actually expected V9 to load it automatically.
For some reason that does not hapen?
Cheers,
Arno
-
Hi Arno!
Whew! it's been a while since I've touched the V9 version, let me fire a copy up and see what's going on :-)
Daniel
-
Hi Arno
So we have the case where its working on my machine, but not yours :laugh:
Where are you putting the RxLoader.Txt file? It needs to be in the same folder as RxNet.dll.
If this isn't the issue, do a do a search on your computer for RxNet.dll.
The loader searches for this via find file, and will load the first one it finds, so it could be loading the incorrect one.
If this isn't the issue, let me know and I'll dig deeper.
-
Daniel,
I managed to track a few lost RxNet.Dll's but that didn't solve the problem, even after a restart.
This is my path:
D:\\VOSS.NET\\VOSS\\VOSS.CAD.Bricscad.RxNet\\bin\\Debug\\VOSS.CAD.Bricscad.RxNet.dll
I also tried
D:\VOSS.NET\VOSS\VOSS.CAD.Bricscad.RxNet\bin\Debug\VOSS.CAD.Bricscad.RxNet.dll
Manually it loads ok.
Any other sugestions on how to autoload the .NET dll?
Here's an other question:
I made a routine which optionally will prompt the user for a filename.
Now by specifying two entry points in the DLL I was hoping to make the call in two ways.
Command 'WriteArea' should produce a save dialog
Command '_WriteArea' should do an autosave without a save dialog.
It seems the '_' is ignored? Both calls show the flag is 'false'
Changing '_WriteArea' to 'WriteAreaAuto' does the trick, I just thought it was a nice shortcut.
Arno
[CommandMethod("_WriteArea")]
public static void _WriteArea()
{
DoWriteArea(true);
}
[CommandMethod("WriteArea")]
public static void WriteArea()
{
DoWriteArea(false);
}
private static void DoWriteArea(bool autoSave)
{
try
{
RxNet.RxGlobal.GlobalFunctions.Printf("\nThe flag passed is : {0}", autoSave);
//some work is done here....
}
catch (System.Exception ex)
{
RxNet.RxGlobal.GlobalFunctions.Printf("\n{0}\n{1}", ex.Message, ex.StackTrace);
}
}
-
Never mind the other question.
Changed the underscore to - (minus).
Works.... :kewl:
-
It's a path issue, it's looking for the loader file in "system drive\programs folder\RxNet\v9\"
Also, I it's probably not a good idea to rename\repath the module, this will cause demand-loading to fail
I will see what I can do to make finding the loader file a bit easier. Let me know if you need a custom version setup.
-
Hi Daniel,
keeping the 'path' issue for what it is at this moment, I think I've run into something more complex.
What I'm trying to do is incorporating some crude number crunching to a RxNet.dll, for example exporting a lot of entity information to a file.
Let's say I gave such a command [CommandMethod("DoIt")] :laugh: so after NetLoading the DLL I type DoIt at the command prompt and voila, magic happens.
Now I want to automate this as part of a larger process and use an ordinary COM link to the Application.ActiveDocument and call SendCommand("DoIt") to trigger the RxNet.dll.
Bad luck, bad luck, what I think is happening is this:
The COM SendCommand holds a reference (and locks?) the ActiveDocument.
When Rx tries to start the DoIt() it also tries to get a connection to the same ActiveDocument, but that fails since and external process is busy with it. ( That's at least how it feels)
Am I correct in my observation? And if so, how do I send a command or is there an other way to start the RxNet routine?
I was reviewing the presentation of Prodok at this years conference in Brugge, also mentioning DeadLocking COM calls.
Is that a way to go?
TIA,
Arno
-
IMO, sendcommand is probably not the best approach, its asynchronous and you may run into other issues down the road.
Ideas,
1, call the function directly from the other module
2, If you must use COM, you can expose your commands to COM by coding a interface, I think it's fairly simple.
3, use the [Lispfunction] attribute and call the function via lisp.
#1 is the best choice if the other modules are .NET.
Thoughts?
-
Hi Daniel,
I have tried to create a command using VB.NET but does not work. It seems that there is not the <CommandMethod("xxx")> attribute. Is there any solution for this?
Best regards
-
make sure the class is public and static, make sure the function is also public and static and it should work : )
-
Daniel,
I think I have to go through the COM option (2) since I want to call/start certain RxNet methods from an external process.
I have Bricscad running, along my own .Net application.
Do you have a few clues on how to approach this?
It's not typical Cad related, more a general .Net topic I realize.
I imagine something like the RxNet.Dll being loaded in Bricscad.
Through Marshal.GetActiveObject("Bricscad.RxNet") I get a reference to the RxNet DLL
It exposes funcionality through an interface (so the Rxnet class is no longer static?)
Anybody else out here who is familiar with building COM dll's?
Arno
-
Well I still can not find the <CommandMethod("xxx")> attribute for VB.NET :-(
Has anyone successfully created a custom command using VB.NET?
Thanks
-
Well I still can not find the <CommandMethod("xxx")> attribute for VB.NET :-(
Has anyone successfully created a custom command using VB.NET?
Thanks
works here :-)
Imports BricscadApp
Imports BricscadDb
Imports RxNet.ApplicationServices
Imports RxNet.Runtime
Public Class Class1
<CommandMethod("doit")> _
Public Shared Sub runit()
Try
RxNet.RxGlobal.GlobalFunctions.Alert("Hello From VB")
Catch ex As System.Exception
MsgBox(ex.Message)
Finally
End Try
End Sub
End Class
-
Daniel,
I think I have to go through the COM option (2) since I want to call/start certain RxNet methods from an external process.
I have Bricscad running, along my own .Net application.
Do you have a few clues on how to approach this?
It's not typical Cad related, more a general .Net topic I realize.
I imagine something like the RxNet.Dll being loaded in Bricscad.
Through Marshal.GetActiveObject("Bricscad.RxNet") I get a reference to the RxNet DLL
It exposes funcionality through an interface (so the Rxnet class is no longer static?)
Anybody else out here who is familiar with building COM dll's?
Arno
Arno, I will have to think about this a bit.
-
It's 'just' an entry point I need. :wink:
On the other hand, it would also be usefull to be able to pass a few variables tino a method.
I had begun putting data in USERR1, USERS1 etc and have them read by RxNet 'at the other side of the wall'.
Works, but maybe there's a much smoother way.
Awaiting your thoughts,
ttyl
-
I converted the example RxNetPlay to VB.NET
http://www.theswamp.org/index.php?topic=29100.msg351970#msg351970
But Nativemethods.entSel generates an exception.
Friend Shared Function entSel(ByVal message As String) As RxNet.DatabaseServices.ObjectId
Dim name(1) As Long
Dim pt(2) As Double
acedEntSel(message, name, pt)
' This generate System.OverflowException
Return New RxNet.DatabaseServices.ObjectId(CInt(name(0)))
End Function
(Using win xp, Bricscad v10.4.8. .Net 2.0.)
Can anyone help me?
Thanks.
-
maybe you need to allocate the memory? I.e
Friend Shared Function entSel(ByVal message As String) As RxNet.DatabaseServices.ObjectId
Dim name As Long() = New Long(1) {}
Dim pt As Double() = New Double(2) {}
acedEntSel(message, name, pt)
Return New RxNet.DatabaseServices.ObjectId(CInt(name(0)))
End Function
Dan
-
[off Topic]
Daniel, you win: my curiosity required a Bing of “Brugse Zot”.
[proceed as normal]
-
[off Topic]
Daniel, you win: my curiosity required a Bing of “Brugse Zot”.
[proceed as normal]
:-D I'm trying to locate a bottle or two locally
-
maybe you need to allocate the memory? I.e
Friend Shared Function entSel(ByVal message As String) As RxNet.DatabaseServices.ObjectId
Dim name As Long() = New Long(1) {}
Dim pt As Double() = New Double(2) {}
acedEntSel(message, name, pt)
Return New RxNet.DatabaseServices.ObjectId(CInt(name(0)))
End Function
It does not work.
But i changed Long by Integer, and now it works. ??
<DllImport("Brx10.DLL", CallingConvention:=CallingConvention.Cdecl, CharSet:=CharSet.Unicode)> _
Private Shared Function acedEntSel(ByVal msg As String, _
ByVal name() As Integer, _
ByVal point() As Double) As Integer
Friend Shared Function entSel(ByVal message As String) As RxNet.DatabaseServices.ObjectId
Dim name(1) As Integer
Dim pt(2) As Double
acedEntSel(message, name, pt)
Return New RxNet.DatabaseServices.ObjectId(name(0))
End Function
Thank you.
-
Sorry my bad, I guess long is an Int64 in VB :-o
-
InnoSetup script that helps the installation of applications that use Rxnet.
(Pascal Scripting)
Features
On Install:
- Check if Bricscad is installed. If Bricscad is not installed, does not allow the installation.
- Check if RxNet is installed. If RxNet is not installed, does not allow the installation.
- Add text to RxLoader.txt (auto loading assemblies)
On uninstall
- Remove the added text.
-
I don't know Arno, I've tried doing late binding but I keep getting an exception.
the module
namespace RxNetArno
{
[Guid("D6F88E95-8A27-4ae6-B6DE-0542A0FC7039")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface _ComCommands
{
[DispId(1)]
void test02();
}
[Guid("13FE32AD-4BF8-495f-AB4D-6C61BD463EA4")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("RxNetArno.Commands")]
public class ComCommands : _ComCommands
{
public ComCommands() { }
public void test02()
{
var app = Application.AcadApplication as AcadApplication;
var doc = app.ActiveDocument;
try
{
double[] pnt1 = new double[]{0,0,0};
double[] pnt2 = new double[]{100,100,0};
var line = doc.ModelSpace.AddLine(pnt1, pnt2);
}
catch (System.Exception ex)
{
doc.Utility.Prompt(String.Format("\n{0}", ex.Message));
}
}
}
}
and controller .exe
private void button1_Click(object sender, EventArgs e)
{
try
{
Type ComCommands = Type.GetTypeFromProgID("RxNetArno.Commands");
object ComCommandsObject = Activator.CreateInstance(ComCommands);
ComCommands.InvokeMember("test02", BindingFlags.Instance, null, ComCommandsObject, null);
}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message +"\n" + ex.Source);
}
}
-
I will try late binding with reflection
-
Hi,
I would like to run through all the custom properties in the drawing properties of a file and change their values. I do this in Acad using an enumerator:
Dim CustPops As System.Collections.IDictionaryEnumerator = SummaryInfo.CustomProperties
Do While CustPops.MoveNext = True
info.CustomPropertyTable.Item(CustPops.Key.ToString) = ReturnFeature(CustPops.Key.ToString)
Loop
where "ReturnFeature" is a custom function returning a value.
But I cannot find a way to have the same result with RxNet. Could yoy please give me an advice?
Thank you in advance.
Best regards,
Iraklis
-
Hi Daniel,
keeping the 'path' issue for what it is at this moment, I think I've run into something more complex.
What I'm trying to do is incorporating some crude number crunching to a RxNet.dll, for example exporting a lot of entity information to a file.
Let's say I gave such a command [CommandMethod("DoIt")] :laugh: so after NetLoading the DLL I type DoIt at the command prompt and voila, magic happens.
Now I want to automate this as part of a larger process and use an ordinary COM link to the Application.ActiveDocument and call SendCommand("DoIt") to trigger the RxNet.dll.
Bad luck, bad luck, what I think is happening is this:
The COM SendCommand holds a reference (and locks?) the ActiveDocument.
When Rx tries to start the DoIt() it also tries to get a connection to the same ActiveDocument, but that fails since and external process is busy with it. ( That's at least how it feels)
Am I correct in my observation? And if so, how do I send a command or is there an other way to start the RxNet routine?
I was reviewing the presentation of Prodok at this years conference in Brugge, also mentioning DeadLocking COM calls.
Is that a way to go?
TIA,
Arno
not having any luck.. have you tried application.RunCommand() instead of sendcommand?
-
Hi,
I would like to run through all the custom properties in the drawing properties of a file and change their values. I do this in Acad using an enumerator:
Dim CustPops As System.Collections.IDictionaryEnumerator = SummaryInfo.CustomProperties
Do While CustPops.MoveNext = True
info.CustomPropertyTable.Item(CustPops.Key.ToString) = ReturnFeature(CustPops.Key.ToString)
Loop
where "ReturnFeature" is a custom function returning a value.
But I cannot find a way to have the same result with RxNet. Could yoy please give me an advice?
Thank you in advance.
Best regards,
Iraklis
if you don't mind C#
public static class ComCommands
{
[CommandMethod("doit")]
static public void test02()
{
var app = Application.AcadApplication as AcadApplication;
var doc = app.ActiveDocument;
Dictionary<string, string> info = new Dictionary<string, string>();
string key;
string val;
for (int idx = 0; idx < doc.SummaryInfo.NumCustomInfo(); idx++)
{
doc.SummaryInfo.GetCustomByIndex(idx, out key, out val);
info.Add(key, val);
}
foreach (var item in info)
{
doc.Utility.Prompt(string.Format("\n{0}, {1}", item.Key, item.Value));
}
}
}
-
BTY, I have tool for this in here http://www.theswamp.org/index.php?topic=32990.0
-
Daniel,
thanks for all your efford so far.
I had not tried RunCommand but it gives the same problem. See attachment.
Are we running out of options here? :|
Arno
-
Put a try catch inside that method "Writearea" and post the results
[CommandMethod("WriteArea")]
public static void WriteArea()
{
var app = Application.AcadApplication as AcadApplication;
var doc = app.ActiveDocument;
try
{
//your code
}
catch (System.Exception ex)
{
doc.Utility.Prompt(String.Format("\n{0}", ex.Message));
}
}
-
FYI, you should always put a try catch inside command methods. If your code throws an exception, the exception unwinds the stack until a catch is found. If the exception is caught by my InvokeCmd() method, you lose the ability to handle / determine the cause of the exception
-
Hi,
I would like to run through all the custom properties in the drawing properties of a file and change their values. I do this in Acad using an enumerator:
Dim CustPops As System.Collections.IDictionaryEnumerator = SummaryInfo.CustomProperties
Do While CustPops.MoveNext = True
info.CustomPropertyTable.Item(CustPops.Key.ToString) = ReturnFeature(CustPops.Key.ToString)
Loop
where "ReturnFeature" is a custom function returning a value.
But I cannot find a way to have the same result with RxNet. Could yoy please give me an advice?
Thank you in advance.
Best regards,
Iraklis
if you don't mind C#
public static class ComCommands
{
[CommandMethod("doit")]
static public void test02()
{
var app = Application.AcadApplication as AcadApplication;
var doc = app.ActiveDocument;
Dictionary<string, string> info = new Dictionary<string, string>();
string key;
string val;
for (int idx = 0; idx < doc.SummaryInfo.NumCustomInfo(); idx++)
{
doc.SummaryInfo.GetCustomByIndex(idx, out key, out val);
info.Add(key, val);
}
foreach (var item in info)
{
doc.Utility.Prompt(string.Format("\n{0}, {1}", item.Key, item.Value));
}
}
}
\
Thanks Dan
This solved my problem :-)
-
:lol:
Found the problem.
First of all : the SendCommand approach works. See snippets below.
Very basic code, does what I want.
The problem was in my Bricscad wrapper class. (Wraps AcadApplication)
It got instantiated for a COM connection at the 'outside' of Bricscad to call SendCommand, and got instantiated inside the RxNet module as well.
My class holds some static objects and the second instatiation collided with the first one.
(Enough detail? :angel:)
Still a direct call would be nice, specially for passing parameters.
Below I use UserS1 to pass a message.
Anybody having a bright idea how to pass info?
Thanks,
Arno
From a simple form with a button:
private void button2_Click(object sender, EventArgs e)
{
AcadApplication app = (AcadApplication)Marshal.GetActiveObject("BricscadApp.AcadApplication.2.6");
AcadDocument doc = app.ActiveDocument;
//plug some information in the document
doc.SetVariable("USERS1", "Someone is knocking your door!");
doc.SendCommand("DoIt\n");
}
using System;
using System.Collections.Generic;
using System.Text;
using RxNet.Runtime;
using BricscadApp;
namespace RxNetTest
{
public static class Class1
{
[CommandMethod("DoIt")]
public static void DoIt()
{
AcadApplication app = RxNet.ApplicationServices.Application.AcadApplication as AcadApplication;
AcadDocument doc = app.ActiveDocument;
try
{
// read the variable at RxNet end
string message = doc.GetVariable("USERS1").ToString();
doc.Utility.Prompt(String.Format("\n {0} : {1}", message ,DateTime.Now.ToLongTimeString()));
}
catch (System.Exception ex)
{
doc.Utility.Prompt(String.Format("\n{0}", ex.Message));
}
}
}
}
-
Excellent 8-)
Kind of a kludge, but I might setup a couple of XRecords or Dictionaries (in/out) to pass data.
-
Hi ppl, I just did a application with .NET and it seams to work ok, now I have been wondering how can I tell briscad to load the .net assembly at the startup.
I am new to briscad and lisp but I saw in a lisp example the way they do it is they put the files "on_start.lsp" and "on_doc_load.lsp" at the root of Bricscad. Now I tried to modify those files and I added (load "bsx_netload.lsp"). And that file just has the code (command "netload [assembly-path]"). I tried with the full path and with just the name copying the assembly to the root Bricscad folder but it did not work.
Does any one know how can I load an assembly at the startup?
Thanks in advance.
-
Hi! I am new to BricsCAD. I am trying to write into the DWG database some XRecords. I want to write an integer and a string.
I wrote the following code. Is it correct?
<CommandMethod("chaos")> _
Public Shared Sub foit()
Dim acadapp As AcadApplication = RxNet.ApplicationServices.Application.AcadApplication
Dim doc As AcadDocument = acadapp.ActiveDocument
Dim db As AcadDatabase = doc.database
'get the dictionary collection
Dim dictCollection As AcadDictionaries = db.Dictionaries
'create a new dictionary for my data
Dim dicto As AcadDictionary = dictCollection.Add("myfirstdictionary")
'create an integer XRecord
Dim rec1 As AcadXRecord = dicto.AddXRecord("myinteger")
rec1.SetXRecordData(VariantType.Integer, 16)
'create a string XRecord
Dim rec2 As AcadXRecord = dicto.AddXRecord("mystring")
rec2.SetXRecordData(VariantType.String, "this is a very small string")
MsgBox("it worked re!! " & dictCollection.Count & " : " & dicto.Count)
'save the changes to the document
doc.Save()
End Sub
I wrote another command to read those XRecords but I cannot understand how to use GetXRecordData sub...
Could someone help me? The following code is the command that tries to read the integer and raises many exceptions when GetXRecordData is called..
<CommandMethod("maos")> _
Public Shared Sub doit()
Dim acadapp As AcadApplication = RxNet.ApplicationServices.Application.AcadApplication
Dim doc As AcadDocument = acadapp.ActiveDocument
'open the database
Dim db As AcadDatabase = doc.database
'get the dictionary collection
Dim dictCollection As AcadDictionaries = db.Dictionaries
'select my custom dictionary
Dim dicto As AcadDictionary = dictCollection.Item("myfirstdictionary")
'get my integer record
Dim rec As AcadXRecord = dicto.Item("myinteger")
Dim komos As Integer
rec.GetXRecordData(VariantType.Integer, komos)
MsgBox(komos)
End Sub
Thank you for your time,
Simon
-
Hi ppl, I just did a application with .NET and it seams to work ok, now I have been wondering how can I tell briscad to load the .net assembly at the startup.
I am new to briscad and lisp but I saw in a lisp example the way they do it is they put the files "on_start.lsp" and "on_doc_load.lsp" at the root of Bricscad. Now I tried to modify those files and I added (load "bsx_netload.lsp"). And that file just has the code (command "netload [assembly-path]"). I tried with the full path and with just the name copying the assembly to the root Bricscad folder but it did not work.
Does any one know how can I load an assembly at the startup?
Thanks in advance.
try putting a file called RxLoader.Txt in C:\Program Files\RxNet\V10, inside RxLoader.Txt, put the path to your module
-
Hi! I am new to BricsCAD. I am trying to write into the DWG database some XRecords. I want to write an integer and a string.
I wrote the following code. Is it correct?
...
Hi Simon,
I'll take a look after dinner. At first glance, I see you need to may replace VariantType.XXX with the DXF type
-
Hi ppl, I just did a application with .NET and it seams to work ok, now I have been wondering how can I tell briscad to load the .net assembly at the startup.
I am new to briscad and lisp but I saw in a lisp example the way they do it is they put the files "on_start.lsp" and "on_doc_load.lsp" at the root of Bricscad. Now I tried to modify those files and I added (load "bsx_netload.lsp"). And that file just has the code (command "netload [assembly-path]"). I tried with the full path and with just the name copying the assembly to the root Bricscad folder but it did not work.
Does any one know how can I load an assembly at the startup?
Thanks in advance.
try putting a file called RxLoader.Txt in C:\Program Files\RxNet\V10, inside RxLoader.Txt, put the path to your module
Hi, that worked just right thank you very much. I had been looking for that 2 days and now it working thanks.
-
FYI, There should be an anemic help file in there :-)
-
At first glance, I see you need to may replace VariantType.XXX with the DXF type
Hi Daniel,
There no DXF types in your libraries. AutoCAD has its DXF types in enumerators like DXFType.Text = 1.
I put the value 1 (dxftype text) in the SetXRecordData and GetXRecordData subs and it does not work..
-
see if this helps you
[CommandMethod("execa")]
public static void execa()
{
AcadApplication application = Application.AcadApplication as AcadApplication;
AcadDocument document = application.ActiveDocument;
AcadDatabase database = document.database;
try
{
AcadDictionaries dictionaries = database.Dictionaries;
AcadDictionary dictionary = dictionaries.Add("SWAMP");
AcadXRecord xRecord = dictionary.AddXRecord("SWAMPEXR");
List<Int16> types = new List<Int16>();
List<object> values = new List<object>();
types.Add(1);
values.Add("Hola");
types.Add(1);
values.Add("Swampers");
xRecord.SetXRecordData(types.ToArray(), values.ToArray());
}
catch (System.Exception ex)
{
document.Utility.Prompt(String.Format("\n{0}", ex.Message));
}
}
[CommandMethod("execb")]
public static void execb()
{
AcadApplication application = Application.AcadApplication as AcadApplication;
AcadDocument document = application.ActiveDocument;
AcadDatabase database = document.database;
try
{
AcadDictionaries dictionaries = database.Dictionaries;
AcadDictionary dictionary = dictionaries.Item("SWAMP") as AcadDictionary;
AcadXRecord xRecord = dictionary.Item("SWAMPEXR") as AcadXRecord;
object otypes;
object ovalues;
xRecord.GetXRecordData(out otypes, out ovalues);
Int16[] types = (Int16[])otypes;
object[] values = (object[])ovalues;
for (int i = 0; i < types.Length; i++)
{
document.Utility.Prompt(String.Format("({0} . {1})", types[i], values[i]));
}
}
catch (System.Exception ex)
{
document.Utility.Prompt(String.Format("\n{0}", ex.Message));
}
}
-
There any way to get a pointer to the database of the active document?
(database.UnmanagedObject of the AcadApplication.Activedocument? for PInvoke)
-
Possibly, but .NET would only see a IntPtr type. What are you needing to do?
-
Thanks for replying.
I would like to use acdbTextFind.
Thanks.
-
how about I add a global function getWorkingDatabase() as an IntPtr :-o
sounds dangerous :laugh:
-
Daniel thank you !
The code with the XRecords worked!
Is there a way set Visual Studio to debug with BricsCAD?
This is possible with AutoCAD and speeds up development process..
Thank you for your time,
Simon
-
Simon,
I netload my RxNet.DLL in Bricscad..
Set the break point(s) in the code and use Tools/Attach to proces in VS to select Bricscad from the list.
Then fire up the command....
Hope this helps,
Arno
-
Anyone still using .NET 2.0.. can I drop it?
-
how about I add a global function getWorkingDatabase() as an IntPtr :-o
sounds dangerous :laugh:
That's what I need. It is possible or not?
-
Its untested but here is the sig
GlobalFunctions::GetWorkingDatabasePtr();
-
Its untested but here is the sig
GlobalFunctions::GetWorkingDatabasePtr();
Thank you very much.
-
You're welcome, its attached to the first post in this thread : )
-
I tested GetWorkingDatabasePtr with acdbSaveAs2000, acdbDxfOutAs2004 and acdbGetCurVportId :
- acdbSaveAs2000, acdbDxfOutAs2004 retun eFileAccessErr
-adjustAlignment retun eNotHandled
- acdbGetCurVportId seems to work
And... acdbTextFind does not exist. I was wrong :oops:
And a question:
Is it possible to execute code when loading an assembly?, As in autocad with IExtensionApplication.Initialize (or delphi dll's with DLL_PROCESS_ATTACH), but without using IExtensionApplication.
If it is possible: how?
Thanks.
-
Hi !
Are there any equivalent events in BricsCAD to the following AutoCAD events?
Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.DocumentBecameCurrent
Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.DocumentDestroyed
Thanks,
Simon
-
I tested GetWorkingDatabasePtr with acdbSaveAs2000, acdbDxfOutAs2004 and acdbGetCurVportId :
- acdbSaveAs2000, acdbDxfOutAs2004 retun eFileAccessErr
-adjustAlignment retun eNotHandled
- acdbGetCurVportId seems to work
And... acdbTextFind does not exist. I was wrong :oops:
And a question:
Is it possible to execute code when loading an assembly?, As in autocad with IExtensionApplication.Initialize (or delphi dll's with DLL_PROCESS_ATTACH), but without using IExtensionApplication.
If it is possible: how?
Thanks.
No, IExtensionApplication.Initialize is not coded. I had planned to add something similar, but at this point I suspect a more official version is around the corner. There is probably an event you can capture from the framework, maybe AssemblyLoadEventHandler?
FYI acdbGetCurVportId is already wrapped @ RxNet.RxGlobal.GlobalFunctions.GetCurViewportObjectId()
If you need a simple static function wrapped. let me know, as some of these will be usable in the future
-
Hi !
Are there any equivalent events in BricsCAD to the following AutoCAD events?
Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.DocumentBecameCurrent
Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.DocumentDestroyed
Thanks,
Simon
Huh! I don't see those :-o hmmm let me think abou this.
-
Hi Daniel,
I use these events (DocumentBecameCurrent,DocumentDestroyed) in AutoCAD to update a Palette
when I select an other document or close the current document in the MDI interface.
In BricsCAD .NET are there any palette/paletteset classes? Ι think not.
So I want these events to update a modeless form with the current document's data when a user clicks another document or closes the
current doument in the MDI interface.
I hope that this info helps,
Simon
-
I use these events (DocumentBecameCurrent,DocumentDestroyed) in AutoCAD to update a Palette
when I select an other document or close the current document in the MDI interface.
You can subclass the MDIClient. (WM_MDIDESTROY, WM_MDICREATE ... messages).
-
you might be able to poll one of these
document.BeginClose;
document.BeginDocClose;
...
application.SysVarChanged;
application.SysVarChanged might be useful as I think there is a system var for the current document.
sorry, no wrappers for palettes
-
Anyone still using .NET 2.0.. can I drop it?
I still use it, but I can use 4.0.
FYI acdbGetCurVportId is already wrapped @ RxNet.RxGlobal.GlobalFunctions.GetCurViewportObjectId()
If you need a simple static function wrapped. let me know, as some of these will be usable in the future
Sorry.
Thank you very much.
-
Anyone still using .NET 2.0.. can I drop it?
I still use it, but I can use 4.0.
FYI acdbGetCurVportId is already wrapped @ RxNet.RxGlobal.GlobalFunctions.GetCurViewportObjectId()
If you need a simple static function wrapped. let me know, as some of these will be usable in the future
Sorry.
Thank you very much.
No problem, I will keep it updated as long as people are using it :-)
FYI, I have updated the modules to support Bricscad V11
-
Daniel,
I was just about to drop you line regarding V11, but it seems I was already way to late... :lmao:
Thanks,
Arno
(Leaves me more time to check out TST, LKF... greez from HKG)
-
Hi Daniel,
I've been trying to NETLOAD some Dll's from a network drive.
I get following output at the command prompt:
Die Datei oder Assembly "file:///P:\BRCAD\NET\BrxNet.dll" oder eine Abhängigkeit davon wurde nicht gefunden. Der Vorgang wird nicht unterstützt. (Ausnahme von HRESULT: 0x80131515)
How to load .Net Dlls from network ?
-
What version of .NET?
What version of Bricscad?
Have you adjusted your security settings to allow .NET modules to run from a network drive?
-
What version of .NET?
What version of Bricscad?
Have you adjusted your security settings to allow .NET modules to run from a network drive?
BricsCAD Version 10.5.6
I've tried all .Net Platforms (2.0, 3.5, 4.0), netload from local drive works well.
My security settings are adjusted with caspol... (AutoCAD loads the managed dll from the same network drive)
-
Sorry, I don't have a network drive to test with. I will try to set something up this weekend... HRESULT: 0x80131515 is a "NotSupportedException". I have no idea why this would happen. are you by any chance using WPF? have you tried loading an empty DLL with references RxNet only?
-
here is the source which i tried to load (no empty project).
I also tried to load the RxNet.DLL from a network drive with following output:
Laden von P:\BRCAD\NET\V10\RxNet.dll
: (arxload "P:/BRCAD/NET/V10/RxNet.dll")
Loading .NET 4.0
:Die Datei oder Assembly "file:///P:\BRCAD\NET\V10\Interop.BricscadApp.10.0.dll" oder eine Abhängigkeit davon wurde nicht gefunden. Der Vorgang wird nicht unterstützt. (Ausnahme von HRESULT: 0x80131515)
bei CRxNetApp.internalNetload(CRxNetApp* , CStringT<wchar_t\,StrTraitMFC_DLL<wchar_t\,ATL::ChTraitsCRT<wchar_t> > >* path)
:Die Datei oder Assembly "file:///P:\BRCAD\NET\V10\Interop.BricscadDb.10.0.dll" oder eine Abhängigkeit davon wurde nicht gefunden. Der Vorgang wird nicht unterstützt. (Ausnahme von HRESULT: 0x80131515)
bei CRxNetApp.internalNetload(CRxNetApp* , CStringT<wchar_t\,StrTraitMFC_DLL<wchar_t\,ATL::ChTraitsCRT<wchar_t> > >* path) "P:/BRCAD/NET/V10/RxNet.dll"
-
You cannot move the files RxNet.dll, BricscadDb.10.0.dll or BricscadApp.10.0.dll from where the installer installs them. Did you move them? They must reside in %systemdrive% %programfiles% \RxNet\V10
-
Why cannot move to other than installation directory ?
I moved the files RxNet.dll, BricscadDb.10.0.dll and BricscadApp.10.0.dll from %systemdrive% %programfiles% \RxNet\V10 to any other path and all works fine.
Put the files on a network path throws the described error.
-
Why cannot move to other than installation directory ?
I moved the files RxNet.dll, BricscadDb.10.0.dll and BricscadApp.10.0.dll from %systemdrive% %programfiles% \RxNet\V10 to any other path and all works fine.
Put the files on a network path throws the described error.
It's by design, the installer adds a registry entry for auto-loading and there is a bit of runtime configuring.
I will take a look at this and find out what this issue :-)
-
Daniel,
I had found the RxNet entries in the registry earlier.
When adjusting those, will that allow to move them to an other place?
I'm thinking of relocating those files as well.
Arno
-
Nope, But.. I will get in there this weekend and make a few changes so you can put it anywhere you like.
Are you working down there or visiting? Boy, I really miss that place! Did you make the dragon boat races down in Stanley this year?
-
I have made a few changes, probably breaking.
1, RxNet.DLL is no longer dependant on Bricscad's COM modules at all. This will not affect your code, but it will affect how you reference the COM DLLs in your project. You will need to explicitly reference Bricscad's COM DLLs in your project (using the com tab) and setting the copy local property true, Or, build your own COM metadata DLLs using TLBimp.exe. Visual Studio 2010 no longer needs these metadata DLLs, but you will still need to reference the COM entries if your app uses COM.
2, While the installer still installs the modules in the same location as before, and registers demand loading, you are free to stick the RxNet.DLL wherever you like. You can manually change the demand loading path as well. The RxLoader.txt file should be in the same folder as RxNet.DLL.
I didn't have time to do much testing, so let me know if you run into any issues
-
Don't forget about extension methods .
When working with .NET/COM & Bricscad, it can get a little tedious boxing/un-boxing and casting between .NET and COM types. Especially if you want to use the custom classes / structs that are in RxNet, such as Matrix3d,Point3d.... You may have rolled your own goodies to use as well. One way to making things a bit easier is to use Extension Methods 8-)
//System
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;
// our using statments
using BricscadApp;
using BricscadDb;
using RxNet.ApplicationServices;
using RxNet.Runtime;
using RxNet.RxGlobal;
using RxNet.Geometry;
using RxNet.DatabaseServices;
namespace RxNetTest
{
public static class AcadModelSpaceExtentions
{
public static AcadLine
_AddLine(this IAcadModelSpace space, Point3d startPoint, Point3d endPoint)
{
return space.AddLine(startPoint.ToArray(), endPoint.ToArray());
}
public static AcadCircle
_AddCircle(this IAcadModelSpace space, Point3d centerPoint, double radius)
{
return space.AddCircle(centerPoint.ToArray(), radius);
}
public static AcadLWPolyline
_AddLightWeightPolyline(this IAcadModelSpace space, Point2dCollection points)
{
List<double> verts = new List<double>(points.Count);
foreach (Point2d pt in points)
{
verts.Add(pt.X);
verts.Add(pt.Y);
}
return space.AddLightWeightPolyline(verts.ToArray());
}
public static AcadLWPolyline
_AddLightWeightPolyline(this IAcadModelSpace space, Point2dCollection points, bool isClosed)
{
AcadLWPolyline pline = space._AddLightWeightPolyline(points);
pline.Closed = isClosed;
return pline;
}
public static void _Rotate(this AcadLWPolyline entity, Point3d basePoint, double angle)
{
entity.Rotate(basePoint.ToArray(), angle);
}
public static void _TransformBy(this AcadLWPolyline entity, Matrix3d matrix)
{
entity.TransformBy(matrix.To4x4Array());
}
}
public static class Commands
{
[CommandMethod("test01")]
public static void test01()
{
AcadApplication application = Application.AcadApplication as AcadApplication;
AcadDocument document = application.ActiveDocument;
AcadDatabase database = document.database;
try
{
Point2dCollection pts = new Point2dCollection() {new Point2d(0, 0), new Point2d(0, 100),
new Point2d(100, 100),new Point2d(100, 0)};
AcadLWPolyline pline = database.ModelSpace._AddLightWeightPolyline(pts, true);
pline._Rotate(new Point3d(50, 50,0), 45);
Vector3d vec = (new Point3d(1000, 1000, 0)-new Point3d(91, 323, 0));
Matrix3d xfrm = Matrix3d.Displacement(vec);
pline._TransformBy(xfrm);
}
catch (System.Exception ex)
{
document.Utility.Prompt(String.Format("\n{0}", ex.Message));
}
}
}
}
-
Oh I almost forgot, if you're going to use Extension methods, be careful when overloading existing functions.
Example, if you have an existing function
AddLine(object startPoint,object endPoint);
and you try to overload it with
AddLine(this IAcadModelSpace space, Point3d startPoint, Point3d endPoint);
The framework will want to use the first, I guess it's because all objects in .NET derive from System.Object .?.
I just add a underscore at the beginning of the function name to avoid conflicts.
-
hi daniel,
i have download rxnet.dll from 26.10.2010 and and reanimated your early rxnetsample.
but i cant load rxnet.dll cant make a reference to rxnet.dll with this build.
interop.bricscadapp...dll and interop.bricscaddb...dll are ok.
i have tested for v10 and v11
regards
reinhard
-
Hi Reinhard, did you happen to get the .NET 4 version or .NET 2. ?
-
hi daniel,
thats it. i have proofed the .net 4 version but .net 4 is not installed on this pc!
thanks for your help
next time i will look more in deepth
best regards
reinhard
-
I have made a few changes, probably breaking.
1, RxNet.DLL is no longer dependant on Bricscad's COM modules at all. This will not affect your code, but it will affect how you reference the COM DLLs in your project. You will need to explicitly reference Bricscad's COM DLLs in your project (using the com tab) and setting the copy local property true, Or, build your own COM metadata DLLs using TLBimp.exe. Visual Studio 2010 no longer needs these metadata DLLs, but you will still need to reference the COM entries if your app uses COM.
2, While the installer still installs the modules in the same location as before, and registers demand loading, you are free to stick the RxNet.DLL wherever you like. You can manually change the demand loading path as well. The RxLoader.txt file should be in the same folder as RxNet.DLL.
I didn't have time to do much testing, so let me know if you run into any issues
hi daniel,
thanks for replying.
now i can load your rxnet.dll from any path (including network) and all works well.
by loading a managed dll from network drive there is still the error.
(lspnetload "Q:\\BRCAD\\NET\\TEST.DLL")
:Die Datei oder Assembly "file:///Q:\BRCAD\NET\TEST.Dll" oder eine Abhängigkeit davon wurde nicht gefunden. Der Vorgang wird nicht unterstützt. (Ausnahme von HRESULT: 0x80131515)
bei CRxNetApp.ads_lspnetload() Funktion abgebrochen
is there any chance to fix this prolem ?
-
Try unzipping this file in the Bricscad folder (where Bricscad.exe is located)
contents
<configuration>
<startup>
<supportedRuntime version="v4.0"/>
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<publisherPolicy apply="no" />
</assemblyBinding>
<loadFromRemoteSources enabled="true" />
</runtime>
</configuration>
-
hi daniel,
the problem was trying support .net 4.0 with vs2008.
that doesnt fit.
regards
reinhard
-
Try unzipping this file in the Bricscad folder (where Bricscad.exe is located)
contents
<configuration>
<startup>
<supportedRuntime version="v4.0"/>
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<publisherPolicy apply="no" />
</assemblyBinding>
<loadFromRemoteSources enabled="true" />
</runtime>
</configuration>
hi daniel,
thanks a lot - this solved my problems.
the issue is by using the RxNet-1.0.1.4-4.0 (.Net-Framework 4.0).
best regards
hans
-
Awesome, it seems that CASPOL is depreciated in .NET 4, this apparently is the "New and Improved" Way :-)
-
Hi Daniel,
got your latest stuff installed and all works ok.
I'm a little puzzled on moving the RxNet.dll to an other location.
If I move it from c:\program files\rxnet\v..\ to another folder, ok, it's not loaded on start of Bricscad.
Which file do I now edit to tell Bricscad where to 'demand load' it ?
Autoload.rx? On_start.lsp?
Arno
(HKG days are over, back to the real world.. :-()
-
hi daniel,
i'm still in trouble installing rxnet.dll and the related dlls.
i have installed reinstalled installed but now only rxnet.dll appears in rxnet\v10\ or other
interop.bricscaddb....dll and interop.bricscadapp....dll are gone.
i have seen them on 26.10.2010 now the never come back.
i tried older installations rxnet1,0,1,0-4.0.zip from 04.06.2010 works fine but only for v9, v10.
dont know whats going on .
im working on win7 professional 64bit
best regards
reinhard
-
Hi Daniel,
got your latest stuff installed and all works ok.
I'm a little puzzled on moving the RxNet.dll to an other location.
If I move it from c:\program files\rxnet\v..\ to another folder, ok, it's not loaded on start of Bricscad.
Which file do I now edit to tell Bricscad where to 'demand load' it ?
Autoload.rx? On_start.lsp?
Arno
(HKG days are over, back to the real world.. :-()
Hi Arno,
First, you can edit the path entry in the registry , example...
HKEY_LOCAL_MACHINE\SOFTWARE \Bricsys\Bricscad\V11\en_US\Applications\RxNet\Loader
On 64 bit machines the entry will be under
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\ ...
The next best spot is Autoload.rx
I will add the ability to choose another install location in the installer in the near future, But I really don't want to attempt to support auto loading (or loading) from a network drive. In this case, it would be best to use Autoload.rx
-
hi daniel,
i'm still in trouble installing rxnet.dll and the related dlls.
i have installed reinstalled installed but now only rxnet.dll appears in rxnet\v10\ or other
interop.bricscaddb....dll and interop.bricscadapp....dll are gone.
i have seen them on 26.10.2010 now the never come back.
i tried older installations rxnet1,0,1,0-4.0.zip from 04.06.2010 works fine but only for v9, v10.
dont know whats going on .
im working on win7 professional 64bit
best regards
reinhard
Right, as I noted in this post http://www.theswamp.org/index.php?topic=29100.msg406772#msg406772
The interop DLLs are no longer included. The reason is, .NET 4 no longer needs/uses interop DLLs, as the interop is now directly imbedded in. In Visual studio 2010, add a reference to Bricscad via the COM tab. (both DB && APP)
-
Daniel,
Have you heard any whispers as to when .NET support will be included officially ??
I don't really want to author net code addressed at COM then change it to suit the new API.
Regards
Kerry
-
Just a guess, but maybe the end of the year, or early next. :-)
-
Hi Daniel,
I still seem to strugle with autoloading RxNet stuff.
I have put:
D:\VOSS.NET\VOSS\VOSS.CAD.Bricscad.RxNet\bin\Debug\VOSS.CAD.Bricscad.RxNet.dll
in RxLoader.txt and have that txt file in the RxNet\V.. folder next to RxNet.dll.
(No fiddling with registry paths yet, just the default folder)
After starting Bricscad I still have to NetLoad my VOSS.CAD.Bricscad.RxNet.dll manually.
Any clues?
Arno
-
Any clues?
Nope, but what I will do is give you a version that prints what it's doing at the command line so we can track the issue, are you using .net 2 or 4 ?
-
We're planning to upgrade soon but for the time being still on .net 2...
cheers
-
Try this one, note the paths at the command line :-)
-
Ok Daniel,
I replaced RxNet 1.0.1.4 with your debug one.
When starting Bricscad I see in the command prompt:
Loading .NET runtime v2.0.50727
RxLoader.txt = C:\Program Files\RxNet\V9\RxLoader.txt
:? Shouldn't that be the path of the DLL I'm trying to load??
(D:\VOSS.NET\VOSS\VOSS.CAD.Bricscad.RxNet\bin\Debug\VOSS.CAD.Bricscad.RxNet.dll)??
Arno
-
what is the contents of RxLoader.txt?
D:\VOSS.NET\VOSS\VOSS.CAD.Bricscad.RxNet\bin\Debug\VOSS.CAD.Bricscad.RxNet.dll ?
-
Here is what I get when I run a sample
RxLoader.txt = C:\Program Files (x86)\RxNet\V11\RxLoader.txt
file = C:\Users\Daniel\Documents\Visual Studio 2010\Projects\RxNetTest\RxNetTest\bin\Debug\RxNetTest.dll
the file RxLoader.txt should reside in the same folder as RxNet.dll
the file RxLoader.txt should contain the paths to the DLLs you would like to load at startup.
Is this what you have?
-
Yep,
RxLoader.txt is in the same folder as RxNet.dll.
RxLoader.txt contains the full name of my DLL
Nope, I get no
file = D:\VOSS.NET\VOSS\VOSS.CAD.Bricscad.RxNet\bin\Debug\VOSS.CAD.Bricscad.RxNet.DLL
at the command prompt.
:-o
-
try this one
-
Starting Bricscad now reports:
Failed to find RxLoader.txt at c:\Program Files\RxNet\V9\RxLoader.txt
while it actually is there....
file is attached.....
-
Does the file you have, have double extensions like the one you posted?
RxLoader.txt.txt
-
:ugly:
How to keep each other occupied.....
Double extensions.... :realmad: what a waste of time.
Now it's working. :-)
Thanks a lot for your patience.
Hope this hasn't screwed up your S'hai night too much!
TTYL
-
No worries, glad it's working for you 8-)
-
Hallo,
I have recently upgrade to the Bricscad V11.1.14 build 20538 version and my RxNet commands do not work anymore.
the line:
Dim acad As AcadApplication = RxNet.ApplicationServices.Application.AcadApplication
seems to create problems because the next code works:
Public Shared Sub Test()
MsgBox("1111")
'Dim acad As AcadApplication = RxNet.ApplicationServices.Application.AcadApplication
MsgBox("1111")
End Sub
but when I uncomment the Dim line I get an error message (attached)
<CommandMethod("test")> _
Public Shared Sub Test()
MsgBox("1111")
Dim acad As AcadApplication = RxNet.ApplicationServices.Application.AcadApplication
MsgBox("1111")
End Sub
Best regards,
Iraklis
-
Hi again,
The problem seems to be caused because I have changed the Copy Local property of the RxNet dlls to be false. When I change this to true everything works OK.
-
I think there was a change in V11.1.14's COM settings. I will make a new build to fix this....
-
Hi, sorry to bother I would like to ask if the new build you said is ready.
Best regards.
-
just curious, what version are you using now? because I had removed the COM references in this latest version 1.0.1.4. If you're using 1.0.1.3, you can just replace the COM DLLs in the RxNet/V11 folder with the yours (the ones from copy local).. if that make sense
-
Also.. I would 'really' like to encourage the users of these DLLs to move to .NET 4.0 and VS2010. It's much better at handling COM : )
-
Thank you for the reply. I will try it.
Well considering the use of VS2010 I have not yet tried it so I would like to have your opinion. Does it worth to buy yet another VS and to use it in parallel with VS2005 (for BRX) , VS2008 (for Acad newer than V2009) and now VS2010?.
Best regards.
-
Depends on what you're doing I suppose, I have VC6-VC10 on my machine. Of course if your just doing C#, than the VS2010 express(free) ought to be enough .?.
If you plan on doing more native code, then have a look a VC10pro build targeting ..
http://blogs.msdn.com/b/vcblog/archive/2009/12/08/c-native-multi-targeting.aspx
Personally, I would like to drop support for .NET 2.0.. its ancient history in .NET years and its much easier for me to maintain a single version :wink:
-
I was wondering Daniel,
would it be possible to run (or make run) your RxNet installer in Silent mode, so no user interaction is required?
Like RxNetSetup /S11 to 'Silently' install for V11?
After that I can let my own installer move the dll and change the registered path...
Or:
Can I set registry keys myself to 'tell' Bricscad where I put the RxNet.dll?
Cheers,
Arno
-
All my installer does is copy the file to drive and create the demand loading entry in the registry, so you can roll your own if you wish.
I could probably create a msi or merge module if needed, INNO installer does not have the silent option.
-
Ok Daniel,
we'll give it a crack.
Will let you know how things work out.
ttyl
-
That was pretty painless.
Moved DLL and adjusted registry path (as you sugested in earlier message).
But just tackling the demandload entry is enough. Great.
I'm having lots of fun with this RxNet stuff, it's very usefull.
(Provided the correct RxLoader....... is used :lmao:)
Cheers
-
Hi Daniel, best wishes for 2011!
I'm starting off this year fresh with an upgrade to Bricscad V11.2.5 and adjusting to the V4 RxNet dll's for V11. (V4.0.30128)
We have also upgraded our source code to .NET V4.
My registry path is adjusted, so RxNet.Dll gets loaded on startup of V11.
The RxLoader takes care of loading my own VOSS.RxNet.Dll.
When I type a RxNet command in V11 , Bricscad responds ok.
However.... :-o
With the RxNet stuff loaded, trying a ThisDrawing.Application.Documents.open("c:\temp\somedrawing.dwg") in the VBA editor immediatly shuts down V11.
First I disabled the RxLoader so only (your)RxNet.dll gets loaded. (Not my VOSS.RxNet.DLL)
Still same shutdown behaviour.
Only when NO RxNet.Dll is loaded, the .Open method works in VBA.
Can you replicate this behaviour or have any other clue?
Arno
-
I will take a look :-o
-
Arno, try this...
Create a file called bricscad.exe.config, with these settings inside, and put it in the Bricscad folder.
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0.30128"/>
<supportedRuntime version="v4.0"/>
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<publisherPolicy apply="no" />
</assemblyBinding>
<loadFromRemoteSources enabled="true" />
</runtime>
</configuration>
-
Thanks Daniel,
that seems to have solved the problem. After adding bricscad.exe.config (no .txt at the end :lmao:) it all works.
Question:
Do I have to maintain this file with upcoming future updates?
Arno
-
Hi Arno,
I shouldn't need any changing in the near term.. but, At some point Bricsys will add support for managed wrappers , I'm not sure when, or whether or not it will be will be based .NET 2.0 or .NET 4.0. I hope it's 4.0, but more than likely it will be .net 2.0. You may have to do adjustments at that point. Until then, that should be your default bricscad.exe.config for .NET 4.0 :-)
-
Thanks again Daniel.
Your wrappers are doing a pretty good job for me at the moment, swapping to managed .Net wrappers will take some different mindsettings I guess.
Sniffed through a couple of books already, but did not have a chance to get some hands on experience yet.
Looking forward to Bricscad's implementation, will be interesting to see its performance.
TTYL,
Arno
-
How do i use DisposableWrapper? (Nor do i understand how it works in autocad)
Is it suitable for acedGetSym and acedEvaluateLISP?. I tried using it but it seems it is not possible.
(I used some of this code: http://www.theswamp.org/index.php?topic=33611.0)
Thanks, and forgiveness for my bad english
PD:
Needed this to emulate "VLAX" in bricscad, but it seems that can be done with AcadDocument.EvaluateLisp.
-
How do i use DisposableWrapper? (Nor do i understand how it works in autocad)
Is it suitable for acedGetSym and acedEvaluateLISP?. I tried using it but it seems it is not possible.
(I used some of this code: http://www.theswamp.org/index.php?topic=33611.0)
Thanks, and forgiveness for my bad english
PD:
Needed this to emulate "VLAX" in bricscad, but it seems that can be done with AcadDocument.EvaluateLisp.
DisposableWrapper looks to be a base class(it is marked as abstract so it meant to be used as base class) that implements the Idisposable interface.
I would guess it is inherited for all the classes in the managed API that need or want dispose to be called. For example entites in a using block.
Here is a link to Idisposable interface LINK (http://msdn.microsoft.com/en-us/library/system.idisposable.aspx)
-
DisposableWrapper looks to be a base class(it is marked as abstract so it meant to be used as base class) that
I would guess it is inherited for all the classes in the managed API that need or want dispose to be called. For example entites in a using block.
Here is a link to Idisposable interface LINK (http://msdn.microsoft.com/en-us/library/system.idisposable.aspx)
Thanks. I understand it:
DisposableWrapper implements (+-) the Idisposable interface for unmanaged objects.
But: how use rxnet DisposableWrapper (as resbuf)?
Thank you very much for replying.
-
I can wrap those functions for you if needed, provided they are available in BRX. but if you can do this via COM, even better. I.e AcadApplication.ActiveDocument.EvaluateLisp();
Also another way to exec lisp routines.
http://www.theswamp.org/index.php?topic=29100.msg373262#msg373262
-
I can wrap those functions for you if needed, provided they are available in BRX. but if you can do this via COM, even better. I.e AcadApplication.ActiveDocument.EvaluateLisp();
Thank you very much but it is not necessary. Works well with AcadApplication.ActiveDocument.EvaluateLisp
Dim a As AcadApplication = DirectCast(RxNet.ApplicationServices.Application.AcadApplication, AcadApplication)
Dim d As IAcadDocument = a.ActiveDocument
Dim o, op As Object
d.Utility.GetEntity(o, op)
Dim e As AcadEntity = DirectCast(o, AcadEntity)
Dim h As String = e.Handle
If IsNumeric(h) Then
d.EvaluateLisp ("(setq handle (itoa " & h & "))")
Else
d.EvaluateLisp ("(setq handle " & h & ")")
End If
d.EvaluateLisp ("(setq curve (handent handle))")
Dim r As System.Array
r = DirectCast(d.EvaluateLisp("(vlax-curve-getPointAtDist curve 100)"), Array)
d.EvaluateLisp ("(setq handle nil)")
d.EvaluateLisp ("(setq curve nil)")
-
As noted here,
http://www.theswamp.org/index.php?topic=37990.msg430062#new
Bricscad and .NET is on the way, therefore this project is now depreciated 8-)
-
Thanks for all your hard work Daniel. Your netload routine certainly piqued my interest for the topic!
-
my pleasure. Really a great learning experience.
BTY, I will keep it around for people using older versions of BCad.
And now off to play with the new API! :laugh: