Sei sulla pagina 1di 16

.

NET Command School -- Making Your Custom


Commands Look and Feel Like AutoCAD
Doug Goforth National MultiTech LTD/CadPLUS Products

CP115-1
Learn to make your custom Visual Basic (VB) or C# .NET commands look and feel just like
AutoCAD. Create command prompts and LISP functions. Present the user with a choice of geometry and
keyword responses, perform various actions depending on the input, and then repeat the prompt for the next
input.

About the Speaker:


Doug has been involved in the evolution of CAD for the facilities market for more than 20 years. He has led
teams in converting and creating tens of millions of square feet of drawings among various CAD platforms.
Doug has created and implemented CAD and space standards and procedures for major international
companies working across sites and continents. He is a consultant and programmer for process managers
and CAD managers at IBM, BellSouth, and many familiar engineering firms in the U.S., Canada, Europe,
Latin America, and Australia. Doug has been a speaker at AU for 4 years.
doug.goforth@nationalmultitech.com

.Net Command School


Can the Average User Tell the Difference between Your Commands and
AutoCADs?
AutoCAD follows standard conventions when interacting with the user. Autodesk has many
years of observation and feedback that has helped in determining how to prompt for user
input. Novice and experienced users alike will expect to be presented with prompts and
dialogs in the conventions that they are accustomed to. You can gain a great advantage in
usability for your application by anticipating what the user will expect when prompted for
input while using AutoCAD.
Prompts and Dialog Parts You Should Emulate
Select objects:
Specify a point:
Specify first point:
Specify height <0.200>:
Specify base point or [Displacement] <Displacement>:
Enter block name or [?]:
Enter an option [Next/Previous/Go/eXit] <N>:

Anatomy of a Prompt
Prompts in AutoCAD follow a set format:

.NET Managed Code Reference Requirements


1.

acdbmdg.dll (ObjectDBX .NET Managed Wrapper)

2.

acmgd.dll (AutoCAD .NET Managed Wrapper)

Autodesk Namespaces You Will Want to Include


Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.DatabaseServices
Imports DbTransMan = Autodesk.AutoCAD.DatabaseServices.TransactionManager
Imports Autodesk.AutoCAD.Geometry
Defining your Command with CommandMethod
CommandMethod is a member of Autodesk.AutoCAD.Runtime. It makes your command
available from the AutoCAD Command: prompt.
<CommandMethod("AUSCHOOL")>Public Sub myAuschoolCommand()
Some lines of code
End Sub
Writing to the Command: Line
Use the editor to write messages to the Command: line and to display prompts:
Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor
ed.WriteMessage(Hello World!)
Setting up Prompt Options
Use this combination to set up a prompt and get the results:
Prompt Options + Prompt Results
Prompt Options - Prompting for a point with keywords
Dim prPtOpts As New PromptPointOptions(vbLf + _
"Please do something now + _
[First thing/Second thing] <F>:")
prPtOpts.Keywords.Add("First thing")
prPtOpts.Keywords.Add("Second thing")
prPtOpts.AllowNone = True 'Allow ENTER only
prPtOpts.AppendKeywordsToMessage = False
Prompt Results - Prompting for a number with keywords
and default value
Dim prIntOpts As New PromptIntegerOptions(vbLf + _
"Please type a number:")
prIntOpts.Keywords.Add("First thing")
prIntOpts.Keywords.Add("Second thing")
prIntOpts.AppendKeywordsToMessage = True
prIntOpts.DefaultValue = 1

Getting the<default> to
come at the end of the
prompt

Some objects have methods


defined for DefaultValue:
PromptAngleOptions
PromptDistanceOptions
PromptDoubleOptions
PromptIntegerOptions
PromptStringOptions
These objects allow you to use
AppendKeywordsToMessage
and DefaultValue to build the
prompt in the correct order.
For all other objects you will
have to build the entire prompt
yourself if you plan to use
keywords with a default value.

Displaying the Prompt


Use the Editor object to display the prompt. Each GETxxx method must be matched with its
corresponding Prompt Result Type. This will be displayed by VS2005s intellisense feature.
Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor
Dim prPtResult As PromptPointResult
prPtResult = ed.GetPoint(prPtOpts)
Getting the User Response
Four ways the user can respond to a command line prompt:

1. _____________________________________________
2. _____________________________________________
3. _____________________________________________
4. _____________________________________________
Select Case prPtResult.Status
Case PromptStatus.OK 'got expected response
Case PromptStatus.Keyword 'keyword was entered
Case PromptStatus.None 'user pressed ENTER
Case PromptStatus.Cancel 'user cancelled command
Case Else
End Select
Entity Prompting and Responding
GetEntity will return an ObjectID (Try/Catch blocks have been omitted for clarity):
Dim prEntOpts As New PromptEntityOptions("Pick an object: ")
Dim prEntResult As PromptEntityResult
prEntResult = ed.GetEntity(prEntOpts)
If prEntResult.Status <> PromptStatus.Error Then
Dim entid As ObjectId = prEntResult.ObjectId
Dim db As Database =
Application.DocumentManager.MdiActiveDocument.Database
Dim tm As _
Autodesk.AutoCAD.DatabaseServices.TransactionManager =
db.TransactionManager
Dim myT As Transaction = tm.StartTransaction()
Dim entity As _
Entity = CType(tm.GetObject(entid, OpenMode.ForRead, True), Entity)
ed.WriteMessage("You selected: " + entity.GetType().FullName)
myT.Commit()
End If

A Word about Using the Transaction Manager


The Transaction Manager provides a clean way to access the AutoCAD database and
manage the manipulation of AutoCAD objects in a drawing. The Transaction Manager
makes AutoCAD aware of your transaction, makes possible the Undoing of your
commands, and facilitates safe memory management.
Use the Transaction Manager in the following sequence:
1. Initialize the Transaction Manager
2. Use the TM to operate on the entity (query, create, modify)
3. Commit the Transaction
Using the Transaction Manager to get the selected object as an Entity type insures that a
proper object will be operated on without crashing the AutoCAD session.
Getting String Input from a Dialog
Use Modal dialogs to constrain user attention to the form:

Set form properties as shown below to eliminate confusion and erroneous navigation when
displayed. Modal dialogs should not be minimizable since this would prevent the user from
interacting with AutoCAD.

Also, set the DialogResult property of the OK button to DialogResult.OK


Dim strName As String = ""
Dim dlgName As New frmName
dlgname.StartPosition=Windows.Forms.FormStartPosition.CenterParent
Application.ShowModalDialog(dlgName)
If dlgName.DialogResult = Windows.Forms.DialogResult.OK Then
strName = dlgName.TextBox1.Text
End If
dlgName.Dispose()
ed.WriteMessage("You entered " + strName)
A StartPosition of CenterParent will automatically center the form in the center of the
AutoCAD window.

Getting Drawing Input from a Dialog


Use a Modal dialog for drawing selections. You must hide the form when interacting with
AutoCAD.

This dialog is designed to emulate the Pick Point feature on the Block Definition dialog in
AutoCAD.

Making the Prompt Loop until User Exit


Always exit looping on ESC, an error, or expected end of recurring prompt (Try/Catch blocks
and Case Else have been omitted for clarity and space).

Question: Why is prPtOpts.Message redefined inside the loop?


_________________________________________________________
_________________________________________________________

Launching by Prompt or Dialog


One AutoCAD convention you see a lot of is being able to launch a command with either a
prompt or a dialog depending on whether or not you use a dash in front of the command.
You can accomplish this by defining two commands in you application:
Start command with a dialog
<CommandMethod("MYCOMMAND")> Public Function myCommandDialog()
-andStart command with command line prompts
<CommandMethod("-MYCOMMAND")> Public Function myComand()
Each command method can be used to call common bits of code.
Making your Command Transparent (and other optional items)
Your command can be made transparent by specifying a command flag to the
CommandMethod function:
<CommandMethod("AUSCHOOL", CommandFlags.Transparent)> _
Public Sub myAuschoolCommand()

In addition to transparent commands, you can limit you application to SDI, only ModelSpace
and more.

A Command to Load a Custom Toolbar (CUI file)


This example shows how to load a CUI file from a command. The file path must be
explicitly specified, or it must exist in the search path.
This command does double duty:
1. If the CUI file is not loaded, it loads the CUI file
2. If the toolbar is loaded, but turned off, it turns it on.

A Listing of Getxxx Methods for AutoCAD acgmd.dll


Use the Object Browser (F2) in Visual Studio to display a listing of Editor Members defined
in acmgd.dll.

Defining LISP Functions


You can expose your command as a LISP function by using the LispFunction Class Attribute
when you define the function:
<LispFunction("AULISP")> _
Public Function auLispFunc(ByVal myLispArgs As ResultBuffer) As Boolean
Dim success as Boolean = False
Some lines of code
Return success Returns t or nil
End Function
Parsing LISP function arguments
Arguments enter the function as a ResultBuffer object. You can easily enumerate the Typed
Values in the Result Buffer:
Check for the correct number of arguments passed
If myLispArgs.AsArray.Length <> 1 Then
ed.WriteMessage(vbLf + "Incorrect number of arguments.")
Return False
End If
For Each tVal As TypedValue in myLispArgs
Operate or each argument
Next
Taking arguments in order
Arguments are often expected with specific types and in a specific order. Assign the Result
Buffer to an array to retrieve the arguments in sequential order:
Dim
Dim
Dim
Dim
Dim

myArgs As Array = myLispArgs.AsArray()


tVal As TypedValue
fileName As String = CType(myArgs(0), TypedValue).value
myPoint1 As Point3d = CType(myArgs(1), TypedValue).value
myPoint2 As Point3d = CType(myArgs(2), TypedValue).value

Determining argument type


Arguments to a LISP function can be of varying types; string, double, integer, point, etc..
The type of argument passes is revealed in the TypeCode of the TypedValue. Use the
TypeOf operator to determine the value. Place the constant value of all the codes in your
class and then use a function to return the type:
If TypeOf tVal.Value IsNot String Then
ed.WriteMessage(vbLf + " ; error: bad argument type:")
Exit Sub
Else
Dim fileName As String = tVal.value
End If

Demandloading the application


When you demandload your application, you are making AutoCAD aware of the command.
This allows the dll to be loaded into AutoCAD without using the NETLOAD command.
This is accomplished by entering the proper registry keys for demandloading. Here is an
example (the line numbers are for convenience and should not be in the registry):
01

Windows Registry Editor Version 5.00

02
03
04
05
06

[HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\AutoCAD\R17.1\ACAD-6001:409\Applications\AUNetLoad]
"DESCRIPTION"="AU 2008 Demandload Example"
"LOADER"="C:\\Program Files\\AU2007\\ComSchool.dll"
"LOADCTRLS"=dword:00000002
"MANAGED"=dword:00000001

07

[HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\AutoCAD\R17.1\
ACAD-6001:409\Applications\AUNetLoad\Commands]
"AUNetLoad"="AUText"

08
09
10

[HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\AutoCAD\R17.1\
ACAD-6001:409\Applications\AUNetLoad\Groups]
"AUNetMan"="AUNetMan"

Line 02: The last item AUNetLoad is a unique name for your application.
Line 03: Any Description for the assembly.
Line 04: The actual location of the assembly.
Line 05: Double word value of loadreasons. Here is a table of possible loadreasons from
the AutoCAD Managed Class Reference:
LoadReasons
Name
kOnProxyDetection

Value
0x01

kOnAutoCADStartup

0x02

kOnCommandInvocation

0x04

kOnLoadRequest

0x08

kLoadDisabled
0x10
kTransparentlyLoadable 0x20

Description
Load the ObjectARX application when objects of custom classes it
controls are loaded via drawing open, dxfin, insert, and so on
Load the ObjectARX application when AutoCAD starts up
Load the ObjectARX application whenever an unknown command is executed
for which it has a registry entry
Allow loading of the ObjectARX application via the
AcRxDynamicLinker::loadApp() method
Do not demand load the ObjectARX application for any reason
Load the ObjectARX application transparently

We are using 0x02 in this example to load the application when AutoCAD starts. 0x0e is
also very common. It uses 0x01 + 0x02 + 0x04 + 0x08.
Line 06: A double word declaring that this is a managed .NET assembly.
This should always be 1.
Line 07: Specifies a subkey for defining commands.
Line 08: Specifies the command name in the class. String1 is the global command, String
2 is the local command. You can add as many commands as are in your assembly.
Lines 09 & 10: Specify the command group name in the module.

AutoCAD 2006 English Product ID Registry Keys:


..\R17.1\ACAD-6001:409
..\R17.1\ACAD-6002:409
..\R17.1\ACAD-6003:409
..\R17.1\ACAD-6004:409
..\R17.1\ACAD-6005:409
..\R17.1\ACAD-6006:409
..\R17.1\ACAD-6007:409
..\R17.1\ACAD-6008:409
..\R17.1\ACAD-6009:409
..\R17.1\AOEM-6001:409
..\R17.1\ACAD-6013:409
..\R17.1\ACAD-6022:409
..\R17.1\ACAD-6000:409
..\R17.1\ACAD-6012:409

=
=
=
=
=
=
=
=
=
=
=
=
=
=

AutoCAD
Map
Mechanical Desktop for AIS
Architectural Desktop
AutoCAD Mechanical
Building Systems
AutoCAD Electrical
Land Desktop
AutoCAD LT
AutoCAD OEM
Mechanical Desktop for AIP
Autodesk Utility Design
Autodesk Civil 3D
Architectural Desktop w/Raster Design

The localid for English is 409. Other languages are indicated by other localid numbers. All
localids for AutoCAD start with the number 4. English is 409, German is 407, Chinese is
404, and so on. You can find a complete list on Microsofts MSDN website at:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/intl/nls_61df.asp

Here is an example of a completed registry entry in


HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\AutoCAD\R17.1\ACAD-6001:409\Applications\AUNetLoad\Commands

for demandloading the AUTEXT Command:

Creating an install
There are many tools available for creating installation of your program. The three most
important things you will have to accomplish in your install are:
1. Installing the files
2. Setting the registry keys for demandloading the application
3. Providing a way to uninstall the application.
A very simple install to meet all three needs is available in Visual Studio. We will use the VS
Setup and Deployment module as an example.
Create the installation project
Create a new deployment project by selecting File>New>Project. Then select Setup Project.
Then modify the Project Properties:

Add the assembly dll to the deployment:

Visual Studio will automatically create the dependency files for the installation.

Deploy Registry Keys


Right-click the project to add the tab for Registry entries:

Create the keys for the registry entries:

Create a Launch Condition for the Deployment


You may want to create a launch condition for your deployment to insure that the required
registry tree exists and that AutoCAD is installed.
To create a Launch Condition:

Add a registry search:

Add the Launch Condition:

Potrebbero piacerti anche