Leveraging ActiveX® Libraries with Autolisp® Lee Ambrosius – Autodesk, Inc. Cp417-7


Monitoring Activity in AutoCAD with Reactors



Download 216.55 Kb.
Page3/3
Date05.05.2018
Size216.55 Kb.
#47994
1   2   3

3 Monitoring Activity in AutoCAD with Reactors


AutoCAD monitors a lot of actions that take place in the application, while a drawing is open, and when objects are added to or modified in the drawing. Visual LISP allows you to step in and catch many of these actions through what is known as a reactor.

Reactors come in a variety of types, some of the more common reactor types are listed in the following table.



Reactor

Description

:VLR-AcDb-Reactor

Database reactor

:VLR-Command-Reactor

Command reactor

:VLR-DeepClone-Reactor

Deep clone reactor

:VLR-DocManager-Reactor

Document management reactor

:VLR-DWG-Reactor

Drawing reactor (opening or closing a drawing file)

:VLR-DXF-Reactor

DXF file handling reactor (reading and writing)

:VLR-Editor-Reactor

General editor reactor (available for backwards compatibility)

:VLR-Insert-Reactor

Block insertion reactor

:VLR-Linker-Reactor

Linker reactor

:VLR-Lisp-Reactor

LISP reactor

:VLR-Miscellaneous-Reactor

Reactors that are not part of other reactor types (pick first changes and layout switching)

:VLR-Mouse-Reactor

Mouse reactor (right-click and double-click)

:VLR-Object-Reactor

Object reactor (appending and modifying objects)

:VLR-SysVar-Reactor

System variable reactor

:VLR-Toolbar-Reactor

Toolbar reactor (toolbar images change size)

:VLR-Undo-Reactor

Undo reactor

:VLR-Wblock-Reactor

Writing a block reactor

:VLR-Window-Reactor

AutoCAD or drawing window reactor (window is moved or resized)

:VLR-XREF-Reactor

XREF reactor (attaching, reloading, or detaching)

For more information about reactors, take a look at the “AutoLISP Reference Guide” in the AutoCAD online help.

Important: When using reactors you cannot call a command using the Command function; this is due to the way reactors are designed. You must use the Visual LISP functions and the COM API to mimic the behavior of the commands that you need.

Command Reactor


Command reactors are one of the most commonly used reactors. They allow you to be notified when a command is started, ends, gets cancelled, or fails for some reason. The following sample code shows how to watch for a specific command, in this case the Hatch, and perform a task before the command even begins.

;; Check to see if our custom command reactors

;; have been loaded into the current drawing

(if (= hyp-rctCmds nil)

(setq hyp-rctCmds (vlr-command-reactor nil

'((:vlr-commandCancelled . hyp-cmdAbort)

(:vlr-commandEnded . hyp-cmdAbort)

(:vlr-commandFailed . hyp-cmdAbort)

(:vlr-commandWillStart . hyp-cmdStart)

)

)

)

)
;; Callback used when the user presses ESCape

;; or when the command ends by itself or due to

;; a problem

(defun hyp-cmdAbort (param1 param2)

(if (/= hyp-gClayer nil)

(setvar "clayer" hyp-gClayer)

)
(setq hyp-gClayer nil)

)
;; Callback used when a command is started

(defun hyp-cmdStart (param1 param2)
(setq hyp-gClayer (getvar "clayer"))
(cond

((= (car param2) "QDIM")(prompt "\nQDIM started"))
((or (= (car param2) "HATCH")

(= (car param2) "BHATCH")

(= (car param2) "GRADIENT")

)

(progn

(if (= (tblsearch "layer" "Hatch") nil)

(progn

(setq acadObj (vlax-get-acad-object))
(setq docObj (vla-get-activedocument acadObj))
(setq layerObj (vla-add (vla-get-layers docObj) "Hatch"))
(vla-put-color layerObj acRed)

)

)

(setvar "clayer" "Hatch")

)

)

)

)

4 Working with Windows


Microsoft creates many different APIs (Application Programming Interfaces) for themselves and other developers to take advantage of features found in Windows and the applications they develop. Since Visual LISP allows you to tap into COM libraries outside of AutoCAD, you can manipulate the features of Windows such as the file system and to collect information about the current user that is currently logged into the system and even the computer that the user is using.

Create Desktop Shortcut for AutoCAD


Below is an example of using the Windows Host Scripting Object to create a shortcut on the Desktop that allows you to use the /w command line switch to start AutoCAD with a specific workspace. Desktop shortcuts are one of many different ways to help enforce CAD standards and help to make the users life just a little bit easier, but since it can take time to setup icons on each computer they are often not used. The amount of configuration time is not a factor with the sample code, and it can be run at startup using a file like Acaddoc.lsp.

;; Create shortcut on desktop

(defun c:CreateDesktopShortcut ( / wshShell desktopFldr myDocsFldr shrtObj)
(if (= wshLibImport nil)

(progn

(vlax-import-type-library

:tlb-filename "c:\\windows\\system32\\wshom.ocx"

:methods-prefix "wshm-"

:properties-prefix "wshp-"

:constants-prefix "wshk-"

)

(setq wshLibImport T)

)

)
(setq wshShell (vlax-create-object "WScript.Shell"))
(setq desktopFldr (wshm-Item

(wshp-get-SpecialFolders wshShell) "Desktop"))
(setq myDocsFldr (wshm-Item

(wshp-get-SpecialFolders wshShell) "MyDocuments"))
(setq shrtObj (wshm-CreateShortcut

wshShell (strcat desktopFldr "\\My AutoCAD.lnk")))
(wshp-put-TargetPath shrtObj

"\"C:\\Program Files\\Autodesk\\AutoCAD 2012 - English\\acad.exe\"")
(wshp-put-Arguments shrtObj "/w \"3D Modeling\"")
(wshp-put-Description shrtObj "Custom AutoCAD Desktop Shortcut")
(wshp-put-WindowStyle shrtObj wshk-WshNormalFocus)
(wshp-put-HotKey shrtObj "Ctrl+Alt+A")
(wshp-put-WorkingDirectory shrtObj myDocsFldr)
(wshp-put-IconLocation shrtObj

"C:\\Program Files\\Autodesk\\AutoCAD 2012 - English\\acad.exe, 0")
(wshm-save shrtObj)
(vlax-release-object wshShell)

(princ)

)

AutoCAD offers a number of different command line switches that can be used to control its start up behavior. Other popular and useful command line switches are /t to specify a drawing template for the default drawing that is created when AutoCAD first starts up and /p to specify the user profile that AutoCAD should use.

To find out about these and other command line options in AutoCAD look up the topic “Customize Startup” in the AutoCAD online Help system. For additional information on the Windows Host Script Object, visit Microsoft’s website and do a search on Windows Script Documentation to download the help file for Windows scripting.

Working with Environment Variables


Environment variables are used to store information and settings about the current user logged into the machine, computer specific settings, or application specific settings. Some environment variables can be set or retrieved using AutoLISP with the Setenv and Getenv, but these functions are mainly limited to accessing some settings in the Windows Registry for AutoCAD and a few of the common Windows environment variables.

By using the Windows Host Scripting Object, you can access all of the Windows environment variables and use strings with expandable variables contained in a string. By having access to the Windows environment variables, you can access and store custom settings outside of the Windows Registry. Environment variables are stored in two different ways; user or system. You use the keyword “USER” when you want to work with variables that are specific to the user that is currently logged in or “SYSTEM” to work with variables that are machine specific and are not user specific.

To see which variables are available to you, launch a DOS prompt and enter the command SET.

To see which variables are specific to you as a user, or the system go to Start (menu) >> Control Panel and double-click System. You might have to switch to the Classic View based on your current version of Windows operating system. For Windows Vista or Windows 7, click the Advanced System Settings link on the left. In the System Properties dialog box, click the Advanced tab and then Environment Variables. In the Environment Variables dialog box, add, edit or remove the variables as desired.



;; Shows how to use expanding environment strings

;; Usage: (ExpEnvStr "%TEMP%\\MYDATA")

;; Results of sample: "C:\\DOCUME~1\\Lee\\LOCALS~1\\Temp\\MYDATA"

(defun ExpEnvStr ( strVal / wshShell strValRet)

(setq wshShell (vlax-create-object "WScript.Shell"))
(setq strValRet (vlax-invoke-method wshShell

'ExpandEnvironmentStrings strVal))
(vlax-release-object wshShell)
strValRet

)
;; Retreive the value of the environment variable

;; Usage: (GetEnvStr "SYSTEM" "USERID")

;; Alt Example: (GetEnvStr "SYSTEM" "PROCESSOR_ARCHITECTURE")

(defun GetEnvStr ( strVarType strVarName / wshShell envVars strValRet)

(setq wshShell (vlax-create-object "WScript.Shell"))
(setq envVars (vlax-get-property wshShell 'Environment strVarType))
(setq strValRet (vlax-get-property envVars 'Item strVarName))
(vlax-release-object wshShell)
strValRet

)
;; Set the value to an environment variable

;; Usage: (SetEnvStr "SYSTEM" "USERID" "L123")

(defun SetEnvStr ( strVarType strVarName strVarVal / wshShell envVars)

(setq wshShell (vlax-create-object "WScript.Shell"))
(setq envVars (vlax-get-property wshShell 'Environment strVarType))
(vlax-put-property envVars 'Item strVarName strVarVal)
(vlax-release-object wshShell)

(princ)

)

5 Working with Microsoft Office


Being able to manipulate objects in AutoCAD and Windows can go a long way to improving workflow and help to decrease the number of redundant tasks that you might normally do every day. Being able to efficiently use your design information downstream can help a project get out faster and more cost effectively. Like you previously learned, Visual LISP is capable of working with other COM libraries and Microsoft offers many different COM libraries to work with its Microsoft Office applications such as Word and Excel.

The following samples demonstrate



  • Printing a Microsoft Word document to the default printer

  • Showing how to take information from AutoCAD to create a Microsoft Word document

  • Pushing and pulling information from an Microsoft Excel spreadsheet to modify content of a drawing

  • Accessing information from a Microsoft Access (MDB) database

Print Documents through Word


If you are creating documents with Word dynamically and they need to be a part of a bid package, you will most likely want to have them printed and someone review them or maybe you want to have a user manual online and allow the user to print specific documents off for certain in-drawing conditions or assembly instructions. Whatever your reason might be, you can print a Word document off and the sample code below shows using a custom function to do just that.

;; Usage: (PrintMSWordDoc "c:\\datasets\\CP417-7\\data files\\spec1.doc")

;; Open a document in MS Word and print it using the default printer

(defun PrintMSWordDoc (strWordDoc / wordObj wordDocsObj wordDocObj)

(if (= wordLibImport nil)

(progn

(vlax-import-type-library

:tlb-filename

"C:\\Program Files\\Microsoft Office\\OFFICE12\\MSWORD.OLB"

:methods-prefix "wordm-"

:properties-prefix "wordp-"

:constants-prefix "wordc-"

)

(setq wordLibImport T)

)

)
(setq wordObj (vlax-create-object "Word.Application.12"))

(setq wordDocsObj (vlax-get-property wordObj 'Documents))

(setq wordDocObj (wordm-open wordDocsObj strWordDoc))
(wordm-printout wordDocObj)
(wordm-close wordDocObj wordc-wdDoNotSaveChanges)

(wordm-quit wordObj wdDoNotSaveChanges)
(vlax-release-object wordObj)

(princ)

)

Create new Word Document Based on Information in Drawing


Often when you create a drawing, you might also need to generate a quote based on the information contained in the drawing. Using the Microsoft Word COM library you can create a new document from scratch or even populate information into a document based on a template.

The following sample code demonstrates how to create a new document from scratch and create a series of paragraphs that contain the names of the layers, dimension styles, text styles and blocks contained in the drawing.



;; Creates a new Word document and extracts styles from the current drawing.

;; The extracted information is added to the new Word document.

(defun c:CreateMSWordDoc ( / acadObj docObj wordObj wordDocsObj wordDocObj

wordParasObj wordParaObj wordParaRangeObj

wordSentencesObj wordSentenceObj

wordSentenceFontObj)
(if (= wordLibImport nil)

(progn

(vlax-import-type-library

:tlb-filename

"C:\\Program Files\\Microsoft Office\\OFFICE12\\MSWORD.OLB"

:methods-prefix "wordm-"

:properties-prefix "wordp-"

:constants-prefix "wordc-"

)

(setq wordLibImport T)

)

)
(setq acadObj (vlax-get-acad-object))
(setq docObj (vla-get-activedocument acadObj))
(setq wordObj (vlax-create-object "Word.Application.12"))

(setq wordDocsObj (vlax-get-property wordObj 'Documents))

(setq wordDocObj (wordm-Add wordDocsObj))

(setq wordParasObj (wordp-get-paragraphs wordDocObj))



(setq wordParaObj (wordm-add wordParasObj))

(setq wordParaRangeObj (wordp-get-range wordParaObj))

(wordp-put-text wordParaRangeObj

(strcat "Welcome to Autodesk University 2011"

"\nWhat you are seeing is a very basic "

"example of creating a Word document using "

"the MS Word object. The example code creates "

"a listing of layers, dimension styles, text "

"styles and block names from the current "

"drawing.\n\n"))
(setq wordSentencesObj (wordp-get-sentences wordParaRangeObj))

(setq wordSentenceObj (wordm-item wordSentencesObj 1))
(setq wordSentenceFontObj (wordp-get-font wordSentenceObj))

(wordp-put-bold wordSentenceFontObj :vlax-true)

(wordp-put-underline wordSentenceFontObj :vlax-true)

(wordp-put-size wordSentenceFontObj 16)



(setq wordParaObj (wordm-add wordParasObj))

(setq wordParaRangeObj (wordp-get-range wordParaObj))
(wordp-put-text wordParaRangeObj

(strcat "Report from drawing: " (vla-get-fullname docObj) "\n\n"))



(listItems (vla-get-layers docObj) "Layer List")

(listItems (vla-get-dimstyles docObj) "Dimension Style List")

(listItems (vla-get-textstyles docObj) "Text Style List")

(listItems (vla-get-blocks docObj) "Block List")
(wordp-put-visible wordObj :vlax-true)



(vlax-release-object wordObj)

(princ)

)
;; Used to create a new paragraph based on the items in the collection

;; The title line is formatted as bold, underlined and a size of 14.

(defun listItems (coll title / itemList wordParaObj wordParaRangeObj wordSentencesObj wordSentenceFontObj)

(setq itemList "")
(vlax-for for-item coll

(setq itemList (strcat itemList "\n" (vla-get-name for-item)))

)
(setq wordParaObj (wordm-add wordParasObj))

(setq wordParaRangeObj (wordp-get-range wordParaObj))
(wordp-put-text wordParaRangeObj (strcat title itemList "\n\n"))
(setq wordSentencesObj (wordp-get-sentences wordParaRangeObj))

(setq wordSentenceObj (wordm-item wordSentencesObj 1))
(setq wordSentenceFontObj (wordp-get-font wordSentenceObj))

(wordp-put-bold wordSentenceFontObj :vlax-true)

(wordp-put-underline wordSentenceFontObj :vlax-true)

(wordp-put-size wordSentenceFontObj 14)

)

Extract Information to Microsoft Excel Workbook


Microsoft Excel is a very powerful application that allows you to perform complex calculations or even create tables of information such as door and window schedules. The sample code below demonstrates the ability to extract information from a drawing. In this case it is the diameter of the circles in the drawing and their object handle. The object handle will be used to later update the objects in the drawing after the values in Microsoft Excel have been changed.

;; Creates a new Excel spreadsheet and extract the

;; circles from the current drawing.

;; The extracted information is added to the new Excel spreadsheet.

(defun c:ExtractDrawingToExcel ( / acadObj docObj excelObj excelWorkbooksObj

excelWorkbookObj excelWorksheetsObj

excelWorksheetObj excelRangeObj

spaceObj cnt for-item)
(if (= excelLibImport nil)

(progn

(vlax-import-type-library

:tlb-filename

"C:\\Program Files\\Microsoft Office\\OFFICE12\\Excel.exe"

:methods-prefix "exlm-"

:properties-prefix "exlp-"

:constants-prefix "exlc-"

)

(setq excelLibImport T)

)

)
(setq acadObj (vlax-get-acad-object))
(setq docObj (vla-get-activedocument acadObj))
(setq excelObj (vlax-create-object "Excel.Application.12"))

(exlp-put-visible excelObj :vlax-true)
(setq excelWorkbooksObj (vlax-get-property excelObj 'Workbooks))

(setq excelWorkbookObj (exlm-add excelWorkbooksObj))
(setq excelWorksheetsObj (vlax-get-property excelWorkbookObj 'Worksheets))

(setq excelWorksheetObj (exlp-get-item excelWorksheetsObj 1))
(setq excelRangeObj (exlp-get-range excelWorksheetObj "A1"))

(exlp-put-value2 excelRangeObj

(vlax-make-variant "Welcome to AU 2011" vlax-vbstring))
(if (= (vla-get-activespace docObj) acModelSpace)

(setq spaceObj (vla-get-modelspace docObj))

(setq spaceObj (vla-get-paperspace docObj))

)
(setq excelRangeObj (exlp-get-range excelWorksheetObj "A2"))

(exlp-put-value2 excelRangeObj (vlax-make-variant "Handle" vlax-vbstring))
(setq excelRangeObj (exlp-get-range excelWorksheetObj "B2"))

(exlp-put-value2 excelRangeObj (vlax-make-variant "Radius" vlax-vbstring))
(setq cnt 3)
(vlax-for for-item spaceObj

(if (= (vla-get-objectname for-item) "AcDbCircle")

(progn

(setq excelRangeObj

(exlp-get-range excelWorksheetObj (strcat "A" (itoa cnt))))

(exlp-put-value2 excelRangeObj

(vlax-make-variant (vla-get-handle for-item) vlax-vbstring))
(setq excelRangeObj

(exlp-get-range excelWorksheetObj (strcat "B" (itoa cnt))))

(exlp-put-value2 excelRangeObj

(vlax-make-variant (vla-get-radius for-item) vlax-vbdouble))

(setq cnt (+ cnt 1))

)

)

)
(exlm-saveas excelWorkbookObj

"c:\\datasets\\CP417-7\\data files\\circle-radius"

exlc-xlNormal "" "" :vlax-false

:vlax-true exlc-xlNoChange exlc-xlLocalSessionChanges

:vlax-false "" "" :vlax-false)



(vlax-release-object excelObj)

(princ)

)
;; Opens an Excel spreadsheet and updates the entities in the

;; drawing based on the values in the spreadsheet.

(defun c:UpdateDrawingFromExcel ( / acadObj docObj excelObj

excelWorkbooksObj excelWorkbookObj

excelWorksheetsObj excelWorksheetObj

excelRangeObj strHandle

ss cnt)
(if (= excelLibImport nil)

(progn

(vlax-import-type-library

:tlb-filename

"C:\\Program Files\\Microsoft Office\\OFFICE12\\Excel.exe"

:methods-prefix "exlm-"

:properties-prefix "exlp-"

:constants-prefix "exlc-"

)

(setq excelLibImport T)

)

)
(setq acadObj (vlax-get-acad-object))
(setq docObj (vla-get-activedocument acadObj))
(setq excelObj (vlax-create-object "Excel.Application.12"))

(exlp-put-visible excelObj :vlax-true)
(setq excelWorkbooksObj (vlax-get-property excelObj 'Workbooks))

(setq excelWorkbookObj

(exlm-open excelWorkbooksObj

"c:\\datasets\\CP417-7\\data files\\circle-radius"))
(setq excelWorksheetsObj (vlax-get-property excelWorkbookObj 'Worksheets))

(setq excelWorksheetObj (exlp-get-item excelWorksheetsObj 1))



(setq excelRangeObj (exlp-get-range excelWorksheetObj "A3"))

(setq cnt 3)

(while (setq strHandle

(vlax-variant-value (exlp-get-value2 excelRangeObj)))

(setq ss (handent strHandle))

(setq obj (vlax-ename->vla-object ss))
(setq excelRangeObj

(exlp-get-range excelWorksheetObj (strcat "B" (itoa cnt))))
(vla-put-radius obj

(vlax-variant-value (exlp-get-value2 excelRangeObj)))



(setq cnt (+ cnt 1))

(setq excelRangeObj

(exlp-get-range excelWorksheetObj (strcat "A" (itoa cnt))))

)



(vlax-release-object excelObj)

(princ)

)

Work with Access Database using DAO


The DAO (Data Access Object) allows you to access data in a Microsoft Access database which can be used to populate the title block of a drawing or even keep track of project management information. Microsoft Access databases are a great way to manage information in or from a drawing so it can be used downstream later to generate project quotes or manage information like building/IT assets.

The sample code demonstrates how to utilize an Microsoft Access database that contains a single table and to step through the records contained in the table as well as update a field for one of the records in the table.



;; Opens an Access Database file and reports on the number of records in a table and

;; the records contained in the table.

(defun c:AccessDatabase ( / daoObj dbObj rstObj fieldsObj)
(if (= daoLibImport nil)

(progn

(vlax-import-type-library

:tlb-filename

"C:\\Program Files\\Common Files\\

Microsoft Shared\\DAO\\dao360.dll"

:methods-prefix "daom-"

:properties-prefix "daop-"

:constants-prefix "daoc-"

)

(setq daoLibImport T)

)

)
(setq daoObj (vlax-create-object "DAO.DBEngine.36"))
(setq dbObj (daom-opendatabase daoObj

"c:\\datasets\\CP417-7\\data files\\AU2011.mdb"))
(setq rstObj (daom-openrecordset dbObj "tblEmployees" daoc-dbOpenDynaset))
(daom-movefirst rstobj)

(daom-movelast rstobj 0)

(prompt (strcat "\n" (itoa (daop-get-recordcount rstObj))

" records in table."))
(daom-movefirst rstobj)

(prompt "\n\nEmployee names")
(while (= (daop-get-eof rstObj) :vlax-false)

(setq fieldsObj (daop-get-fields rstObj))



(prompt (strcat "\nFirst name: "

(vlax-variant-value

(daop-get-value

(daop-get-item fieldsObj "FirstName")))))



(prompt (strcat "\nLast name: "

(vlax-variant-value

(daop-get-value (daop-get-item fieldsObj "LastName")))))

(terpri)
(daom-movenext rstobj)

)
(daom-movefirst rstobj)

(daom-findfirst rstobj "FirstName='Bob'")
(if (= (daop-get-nomatch rstobj) :vlax-true)

(prompt "\nNo matching record")

(progn

(setq fieldsObj (daop-get-fields rstobj))

(prompt (strcat "\nBob was in room "

(vlax-variant-value

(daop-get-value

(daop-get-item fieldsObj "RoomNumber")))))

(terpri)
(daom-edit rstobj)
(daop-put-value (daop-get-item fieldsObj "RoomNumber") "103A")
(prompt "but is now in room 103A.\n")
(daom-update rstobj 1 0)

(princ)

)

)
(daom-close rstobj)

(daom-close dbObj)
(vlax-release-object daoObj)

(gc)

(princ)

)

6 Where to Get More Information


When you are first start using the functionality found in an ActiveX library, you will most likely have some questions and where you go to find answers might not be clear. The following is a list of resources that you can use to get help:

  • Help System – The AutoLISP Reference Guide in the AutoCAD online Help system contains information on using some of the COM related functions, but you will also need to turn to the AutoCAD ActiveX Reference Guide. To access the AutoLISP Reference Guide, go to: http://exchange.autodesk.com/autocad/enu/help. The AutoCAD ActiveX Reference Guide can be found at C:\Program Files\Common Files\Autodesk Shared\ acadauto.chm.

  • Autodesk Discussion Forums – The Autodesk forums provide peer-to-peer networking and some interaction with Autodesk moderators. You can ask a question about anything in AutoCAD and get a response from a fellow user or Autodesk employee. To access the discussion forums, go to http://forums.autodesk.com, click AutoCAD, and then click one of the links for a subgroup.

  • AUGI Forums – The AUGI forums provide peer-to-peer networking where you can ask questions about virtually anything in AutoCAD and get a response from a fellow user. Visit AUGI at http://www.augi.com.

  • Industry Events and Classes – Industry events such as AUGI CAD Camp and Autodesk University are great places to learn about new features in an Autodesk product. Along with industry events, you might also be able to find classes at your local technical college or Autodesk Authorized Training Center (ATC).

  • Internet – There are samples and tutorials on the Internet that demonstrate other aspects of the AutoCAD and Microsoft Office ActiveX libraries. Use your favorite search engine, such as Google or Bing and search on the topic of interest.


Download 216.55 Kb.

Share with your friends:
1   2   3




The database is protected by copyright ©ininet.org 2024
send message

    Main page