Using C # For secondary development of AutoCAD (1)
As we all know, the main tools used for secondary development of AutoCAD are ObjectARX, VBA, and vlisp. But their advantages and disadvantages are obvious: ObjectARX has powerful functions and high programming efficiency, but its disadvantage is that programmers must master VC ++, which is very difficult to learn; although VBA and vlisp are simple and easy to useProgramIt seems powerless. Is there a language that can combine their advantages to avoid their shortcomings? The answer is yes, that is, the new world 21 launched by Microsoft.Programming LanguageC #. For more information about C #, seeArticle.
C # communicates with AutoCAD through the bridge of AutoCAD ActiveX. AutoCAD ActiveX allows you to operate AutoCAD programmatically from inside or outside AutoCAD. It does this by displaying the AutoCAD Object to the "external world. Once these objects are displayed, they can be accessed by many different programming languages and environments. For information about AutoCAD ActiveX, refer to the help provided by AutoCAD.
Well, let's use a specific example to illustrate how to use C # For secondary development of AutoCAD. Before introducing the example, let's talk about the related Configuration:
(1) Visual Studio. NET (both 2003 and 2002 are supported. I use 2002)
(2) AutoCAD2000 or a later version (I used 2004)
This example is very simple. It is to start AutoCAD and draw a straight line through a form created by C. The following describes the specific programming steps:
(1) create a C # windows application through Visual Studio. NET.
(2) in Solution Explorer, right-click the reference tab and choose add reference from the shortcut menu ", in the "add reference" dialog box, select the "AutoCAD 2004 Type Library" item in the drop-down list box under the "com" tab (Note: different versions of CAD have different numbers ), click the "select" button on the right and then click the "OK" button below.
(3) add two text boxes and a button to the C # form to enter the coordinates of the start and end points of the line and draw a line in CAD. The following describes the added Code .
(a) add using AutoCAD at the beginning of the program; // import the AutoCAD reference space
(B) add private acadapplication A to the variable declaration part of the form; // declare an AutoCAD Object
(c) Add a = new acadapplicationclass () in the constructor section of the form; // create an AutoCAD Object
. visible = true; // make AutoCAD visible
(d) add the following to the message processing function of the button:
double [] startpoint = new double [3]; // declare the start coordinate of a straight line
double [] endpoint = new double [3]; // declare the end coordinate of a straight line
string [] STR = textbox1.text. split (',');
// Extract the value of the text box from the coordinate of the starting line. The input mode of the text box is "x, y, z"
For (INT I = 0; I <3; I ++)
Startpoint [I] = convert. todouble (STR [I]); // convert the STR array to the Double Type
STR = textbox2.text. Split (','); // retrieves the value of the input text box from the end coordinate of the line.
For (INT I = 0; I <3; I ++)
Endpoint [I] = convert. todouble (STR [I]);
A. activedocument. modelspace. addline (startpoint, endpoint); // draw a straight line in AutoCAD
A. application. Update (); // update display
Well, it's easy. You can compile it. I will introduce the usage of some of the above statements in detail in the next lecture.
Using C # For secondary development of AutoCAD (2)
Using C # For secondary development of AutoCAD (2)
C # Talent
Hello everyone, today I will continue to introduce you to the secondary development of AutoCAD using C. This section describes the problems in the previous example.
In the previous example, I used to reference the AutoCAD 2004 Type Library for communication between C # and AutoCAD, but this method has two fatal disadvantages. The first drawback is that C # needs to restart AutoCAD every time the program is debugged. If there are many times of debugging (such as tracking errors and debugging), the programming efficiency is very low, it takes a long time to start CAD once. Compared with the first disadvantage, the second one is even worse. Because. net, InterOP. autoCAD. there are some bugs in DLL files (that is, the communication between C # and AutoCAD is realized through it). Although sometimes your code is completely correct, but the C # compiler still throws an inexplicable error. Isn't it finished? At one stage, I almost gave up C # And wanted to change to ObjectARX because of these two terrible things, I occasionally read an article written by a foreigner on the Internet. He specifically introduced the solutions to these two problems. Here we will solve these two problems.
First, let's take a look at the second problem by taking the following steps:
1. Use Visual Studio. NET to create a C # application, add the AutoCAD 2004 Type Library according to the settings in the previous article, and then compile your program without adding any code.
2. use ildasm.exe in the Visual Studio .netcommand line tool (this tool can be used in Visual Studio.. autoCAD. DLL file (this file is in the bin \ release folder of the project generated in step 1) compiled into the intermediate language InterOP. autoCAD. il. Note: The project compilation created in step 1 is set to the release mode.
Ildasm.exe/source InterOP. AutoCAD. dll/output = InterOP. AutoCAD. Il
Note: Put ildasm.exe and InterOP. AutoCAD. dll in the same directory.
3. open InterOP in notepad. autoCAD. il file, and then find "sinkhelper" and start ". class private auto ANSI sealed _ dacad statement, change the private in the statement to public, and save InterOP. autoCAD. il file.
4.use ilasm.exe to compile the InterOP. AutoCAD. Il file into an InterOP. AutoCAD. dll file, which is also carried out in Visual Studio. NET command line tool.
Ilasm.exe/resource = InterOP. AutoCAD. Res/DLL InterOP. AutoCAD. il/output = InterOP. AutoCAD. dll
The InterOP. AutoCAD. Res file is generated in step 1.
5. Obviously, it is too troublesome for you to add InterOP. AutoCAD. dll every time you write an application. You can use the following method to automatically add the program to the file: Find the c: \ Program Files \ Microsoft. NET \ primary InterOP assemblies folder, and then
Copy the InterOP. AutoCAD. dll file.
Okay. The second problem is solved. Next, let's take a look at the first one.
In VBA, programmers can use the GetObject function to obtain the currently active AutoCAD Object, but it does not exist in C #. I almost gave msdn to this function, then I went to various C # forums and asked you experts. The results were not solved. Haha, there may be fewer people using C # in China. I still saw an article on a foreign Forum about this problem to solve this problem. Use the following statement to obtain the active AutoCAD Object:
(Acadapplication) Marshal. getactiveobject ("AutoCAD. application.16 ")
(For cad2000 and cad2002, change 16 to 15)
Of course, the preceding statements can be used only when AutoCAD is opened. Otherwise, an error may occur. If AutoCAD is not opened, you can use the method of the previous article to handle it. The complete source code for connecting AutoCAD and C # is as follows:
Using system;
USING AutoCAD;
Using system. runtime. interopservices;
Namespace acadexample
{
Public class autocadconnector: idisposable
{
Private acadapplication _ application;
Private bool _ initialized;
Private bool _ disposed;
Public autocadconne ()
{
Try
{
// Upon creation, attempt to retrieve running instance
_ Application = (acadapplication) Marshal. getactiveobject ("AutoCAD. application.16 ");
}
Catch
{
Try
{
// Create an instance and set flag to indicate this
_ Application = new acadapplicationclass ();
_ Initialized = true;
}
Catch
{
Throw;
}
}
}
// If the user doesn't call dispose,
// Garbage collector will upon destruction
~ Autocadconne ()
{
Dispose (false );
}
Public acadapplication
{
Get
{
// Return our internal instance of AutoCAD
Return _ application;
}
}
// This is the user-callable version of dispose.
// It callour internal version and removes
// Object from the garbage collector's queue.
Public void dispose ()
{
Dispose (true );
GC. suppressfinalize (this );
}
// This version of dispose gets called by our
// Destructor.
Protected virtual void dispose (bool disposing)
{
// If we created our AutoCAD instance, call its
// Quit method to avoid leaking memory.
If (! This. _ disposed & _ initialized)
_ Application. Quit ();
_ Disposed = true;
}
}
}
Use Visual studio.net to compile the above program into a class library, and you can use it in future programs. The following example illustrates its usage. (First, include the acadexample class library in the Project)
Using system;
Using acadexample;
USING AutoCAD;
Namespace consoleapplication6
{
Class class1
{
[Stathread]
Static void main (string [] ARGs)
{
Using (autocadconnector conne= new autocadconne ())
{
Console. writeline (connector. application. activedocument. Name );
}
Console. Readline ();
}
}
}
This example shows the title of the current document in AutoCAD in the C # window.
Using objectdbx Technology in C # Never open a graph to obtain the information of the graph block.
Using objectdbx Technology in C # Never open a graph to obtain the information of the graph block.
Can I obtain block information from a graph without opening it? The answer is yes. The following describes the specific implementation methods.
Requirements:
N will be programmed in C #
N read the "using C # For secondary development of AutoCAD" I wrote"
Start:
N create a C # console program in visual studio.net
N Add the following class libraries to the reference tab:
L InterOP. AutoCAD. dll
L acadexample. dll
L objectdbx16 (in Solution Explorer, right-click the reference tab and select "add reference" in the pop-up menu ", in the "add reference" dialog box, select "AutoCAD/objectdbx common 16.0 Type Library" in the drop-down list box under the "com" tab)
Enter the following code:
1: using system;
2: using AutoCAD;
3: Using DBX = axdblib;
4: Using acadexample;
5:
6: namespace consoleapplication1
7 :{
8: // <summary>
9: // summary description for class1.
10: // </Summary>
11: Class class1
12 :{
13: // <summary>
14: // the main entry point for the application.
15: // </Summary>
16: [stathread]
17: static void main (string [] ARGs)
18 :{
19: Using (autocadconnector conne= new autocadconne ())
20 :{
21: String progid = "objectdbx. axdbdocument.16"
// Note that this is the autocad2004 statement,
// If AutoCAD2002 and autocad2000i are "objectdbx. axdbdocument.1"
22: acadapplication acadapp = connector. Application;
23: DBX. axdbdocument dbxdoc;
24: dbxdoc = (DBX. axdbdocument) acadapp. getinterfaceobject (progid );
25: dbxdoc. Open (@ "F: \ test. DWG ");
26: foreach (DBX. acadentity entity in dbxdoc. modelspace)
27 :{
28: If (entity. entityname = "acdbblockreference ")
// Determine whether the object is a block reference
29 :{
30: DBX. acadblockreference blkref;
31: blkref = (DBX. acadblockreference) entity;
// Forcibly convert the entity that is a block reference to the block reference type
32: object [] ATTS = (object []) blkref. getattributes ();
// Obtain the attributes in the block reference (object type)
33: For (INT I = 0; I <ATTS. length; I ++) // traverse block reference attributes
34 :{
35: DBX. acadattributereference ATT;
36: ATT = (DBX. acadattributereference) ATTS [I];
// Forcibly convert the block reference property (Object Type) to the block reference property type
37: console. writeline ("tag: {0} \ tvalue: {1} \ n ",
38: ATT. tagstring,
39: ATT. textstring); // display the tag and text values of the block reference attribute.
40 :}
41 :}
42 :}
43: console. Readline ();
44 :}
45 :}
46 :}
47 :}
The first line should be noted that the third line uses an alias. Because the namespaces of AutoCAD and objectdbx have many identical class names, you must use the full name instead of the short name, but it is troublesome to write objectdbx, therefore, use the alias DBX to make the input easier.
For the code in front of the program, you can refer to the article "using C # For secondary development of AutoCAD" I wrote. Let's take a look at row 21st. The program defines a string progid, which is used to generate an axdbdocument object as the parameter of the 24th-sentence function getinterfaceobject. However, you must note that the type returned by the getinterfaceobject function is object, so you must change it to the axdbdocument class using forced conversion. Then, use the axdbdocument object generated in line 24 in row 25th to "open" A. DWG file (which is not actually opened). Note that the file path must be correct. This file is the file where the block information we want to obtain is located.
Because objectdbx does not select a set, you can retrieve block information (lines 26-28) only by traversing the model space of the file ).
The description of the remaining statements has been written in the program comments.
You can find that the working principle of objectdbx is similar to that of VBA in C #, but necessary type conversion is required.
Certificate ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Blue Force note:
For the InterOP. AutoCAD. dll decompilation, modification, and re-compilation processes mentioned in the article, this operation is not required in vs2005. vs2005 has changed private to public.