AutoLisp 函數總結


在本章中,我們將更多討論有關在Visual LISP中使用ActiveX性能。首先,我們從ActiveX的技術環境開始,包括對象、對象模型、集合、屬性、方法等方面。然后我們將深挖一些特定的ActiveX技術部分。了解ActiveX功能性是學習任何語言必不可少的工作。

ActiveX是一種面向對象的工具,也就是說它表現為對象的使用以及對象間的關聯這種方式。在這里我不想去解釋面向對象的問題,這些東西最好留給那些更專業的教科書去講。然而,我將嘗試給一些基本的面向對象方面的描述,以便大家有一個基本的了解。



在面向對象的環境中,任何事物都是以Classes(類)開始的。類是抽象的框架,用於描述對象應是什么樣的,以及他們應該如何表現和相互聯系的。在某種意義上說類定義了對象類型的種類。例如,一輛汽車是屬於交通工具類。交通工具是父類,而汽車是子類。反之,你可取得更多特定的和額外定義的子類,例如旅行車、面包車和運動型轎車。

類不處理特定的實例,他們更注重於實例方面的描述,而非使用方面。當你使用類時,你可以說調用類的一個實例。調用類的結果經常是創建了一個對象。對象可以是單獨的圖元或包含了更多對象的容器。

對象
一個對象就是類的一個實例。對象有其固定的屬性,同時也可以有固定的方法和事件。屬性是定義對象怎樣表現和反應的特性。方法是用於訪問或修改對象屬性或某些行為的內置函數。事件是由對象發送的通知,當執行或激活它們時,它用於響應特定動作。

就用上面的汽車類的例子來說,對象可以是特別的轎車。比如說,你的轎車,帶有特別的配置(制造、型號、顏色、選配、以及序列號)。你可以說,你的轎車是汽車類的一個實例,或汽車類派生的一些類。

圖3-1 對象模型

對象模型
對象模型是一個隨意的架構,或類之間的分層定義的排列關系,意思就是可以從更高級別的類來獲得一個對象。對象模型與訪問它的語言或工具無關,它有自己的邏輯框架。不管你是使用Visual Basic、VBA、Visual LISP、Delphi、Java、C/C++、C#.NET或帶有ActiveX接口的其它語言,它都將以相同的模型存在。這並不代表對象模型的所有特性都支持所有語言。某些特性在某些語言中可以訪問或比較容易被訪問,但在其它語言中可能就不行。

我們將對象模型比喻成一套房子,它由房間、門和窗組成。不同的人都可進入和使用房子,而他們都是面對同樣的這套房子。在這種情況下,房子和房間就是對象模型,而人即是編程語言。這樣,你應該懂吧。

類繼承
對象模型通常都是從根或源對象開始。在AutoCAD中,源對象是AutoCAD Application (AutoCAD應用程序)對象,也被稱之為AcadApplication對象。它提供了基本的屬性、方法、事件和來自所有其它對象和集合構成的集合。例如,AcadApplication對象有一集合為Documents(即Documents集合),在其中對應有一個或多個Document對象。每一Document對象有它自己的對象、集合、屬性和方法以及其它東西。

你可向下層瀏覽對象模型進入下一層次的對象和集合,也可以向上層瀏覽父對象和集合。模型非常強大,應用程序可直接訪問和操作環境來執行幾乎無限的任務。它同時保持每一事物都整齊有序,在開發軟件解決方案時能提供有效的幫助。

集合和詞典
集合是在相同父窗口中一組相似的對象。該容器有一個獨特的名字,在大多數情況下,將提供自己的方法來訪問所包含的對象。詞典是一種特殊類型的集合,它允許你擴展你自己的詞典。Visual LISP並沒有過多提供用於創建或處理集合的方法。它允許你遍歷它、修改項目、添加或刪除條目。詞典允許你添加自己的詞典並寫入數據,你可遍歷它、添加、修改和刪除其條目,同樣,你也可以添加 、修改和刪除詞典本身。

在AutoCAD中的一些公共的集合有Documents(文檔)、Layers(圖層)、Dimension Styles(標注樣式)、Linetypes(線型)、 Blocks(塊)等等。

在AutoCAD中的一些公共的詞典有PageSetups (頁面設置)、Layouts (布局)(它同樣也做為詞典保存),還有Express Tools中的個別組件,如WipeOuts (遮罩)。Xrecord對象也保存在詞典內。

屬性、方法和事件
屬性只是描述關聯於對象或集合的特性。例如它可包含名稱、高度、寬度、旋轉角度、比例縮放、顏色、圖層、線型等等。屬性根據不同的對象的類型而有所區別,但有些屬性對所有對象和集合是通用的。集合和詞典通常提供了Count和Name屬性,還有Item和Add方法。只有詞典提供了Delete方法,而你卻不能通過Visual LISP刪除集合。

方法是對象提供的用於訪問或編輯專用特性或針對對象本身執行特別動作的內置函數。常見的方法有Rotate(旋轉)、Erase(刪除)、Copy(復制)、Scale(比例縮放)和Offset(偏移)。你可能注意到,這些看起來就像AutoCAD編輯命令。嗯,在本質上是這樣的,但略有不同。

然而一般的AutoCAD編輯命令,必須在每步執行中驗證對象。而方法是由主對象提供的,因此,只能由每一對象單獨提供支持的方法。暈了吧?

另一種方式,OFFSET(偏移)命令可以在任何時間使用,但如果你試圖偏移一個文本對象, AutoCAD就會出現出錯信息。然而,文本對象本身提供的各種方法,如Copy(復制)、Rotate(旋轉)、Scale(比例縮放)和Move(移動),但沒有Offset(偏移)。所以你可以從對象“調用”各種方法,卻需要確定它對使用的對象是有效的。

事件是對象或集合由各種可以被檢測到的或可以響應的活動所產生動作。當事件與這些事件的反應相結合使用時,就稱為事件驅動編程。AutoCAD提供了一個被稱之為反應器的強大的事件反應工具集,它使你可在繪圖環境中發送觸發器來響應各種事件。例如,當對象在活動的圖形中被刪除時,您可以創建一個反應器響應一個Erase事件。這只是一個事件和反應器的例子。

屬性關聯
有一點很重要,就是你決不需要知道哪些屬性適用於哪些對象和集合。有兩個特別的函數對於保證您的代碼能夠在運行時妥善處理屬性和方法的執行:(vlax-property-available-p)(vlax-method-applicable-p)。這兩個函數只是兩個Visual LISP判斷函數,它提供布爾測試判斷條件是真或假(LISP術語為non-nil或nil)。

這些函數的語法如下:
(vlax-property-available-p object property) 
(vlax-method-applicable-p object method)
 

屬性是跟與之關聯的對象的類型相關。例如,一個Circle(圓)對象有一個Diameter(直徑)屬性,但Line (線)對象就沒有。根據不同的對象類型,屬性也各不一樣,下面的代碼在拾取CIRCLE(圓)圖元時會出錯:

(if (setq ent (entsel "\n選擇對象以獲取其屬性: "))
  (progn
    (setq obj (vlax-ename->vla-object (car ent)))
    (princ
      (strcat "\n長度: " (vla-get-Length obj))
    )
  )
)


但是,如果在取對象的屬性前先檢驗該屬性是否有效時,代碼的執行就能正常,如下面的例子所示:

(if (setq ent (entsel "\n選擇對象以獲取其屬性: "))
  (progn
    (setq obj (vlax-ename->vla-object (car ent)))
    (if (vlax-property-available-p obj 'Length)
      (princ
        (strcat "\n長度: " (vla-get-Length obj))
      )
      (princ "\n對象沒有 LENGTH 屬性…")
    )
  )
)


不幸的是,沒有直接的方法獲取給定對象的所有屬性的列表來用於遍歷編程。不過,你還是可以獲取列表信息的,這樣對你的幫助也不算小。

要查詢在給定的對象上有什么屬性和方法,可在該對象上使用(vlax-dump-object)函數。函數的語法是(vlax-dump-object object show-methods), show-methods參數可以是nil或非nil。如果是非nil,就顯示對象支持的方法,否則就不顯示方法。

圖 3-2 – Documents集合的屬性和方法 

圖3-2顯示了Documents集合對象的屬性和方法。你可看到輸出的第一行顯示了帶有一個描述的內部對象參照(IAcadDocuments),並且列出了可用的屬性和方法。

提示! 以下的命令定義對顯示所選圖元的屬性和方法會有用處。它沒有提供出錯處理,但是它仍是個有用的小工具。

(defun C:DUMP (/ ent obj)
  (while (setq ent (entsel "\n選擇圖元以獲取對象數據: "))
    (setq obj (vlax-ename->vla-object (car ent)))
    (vlax-dump-object obj T)
    (vlax-release-object obj)
  )
  (princ)
)


提示! 屬性后面的括號(RO)代表該屬性為只讀,在這里,所有的屬性均為只讀,方法后面括號內的數字表示了每一方法所需要的參數數目。

要訪問屬性,可使用(vla-get-xxx)函數,或更通用的(vlax-get-Property)函數,兩者都可以。第一個函數的語法是(vla-get-xxx object),其中XXX是屬性名。在使用(vlax-get-property)函數時,語法為(vlax-get-property object propertyname),其中propertyname可以是雙引號字符串或單引號字符串。

(vlax-get-property object property) 或 
(vla-get-property object) 或 
(vlax-get object property)
 

返回值是分配給該對象的指定名稱屬性的值,如果該對象的指定屬性不存在,就會產生錯誤。舉例來說,如果你對Line(直線)圖元查詢“Diameter”(直徑)屬性,就會產生錯誤。

參數: 
Object – 一個 vla-對象 
Property – 與對象相關的有效屬性。 

示例: 
(vlax-get-property objLine “Length”) 
(vlax-get-property objLine ‘Length) 
(vla-get-Length objLine)
 

所有這些語句都將完成同樣的事情。

屬性的名稱並不要求區分大小寫,但本書的例子都將首字母大寫,以示清晰。總的來說,你會發現以上前兩項都很好用,但也有情況是要求用到后兩項。特別是涉及到象Microsoft  Excel 或 Word這樣的外部應用程序。第四種方式 vlax-get 是R14版遺留下來的,只為了向后兼容而已。

使用方法
通過圖3-2的例子,你可看到Documents集合對象支持4種方法:Add、Close、Item和Open。Item方法需要使用一個參數(也就是在圖3-2中顯示在方法后面的那個(1)),它是由集合所引出的文檔的索引和命名。

通常Item方法有一個有趣的特性,那就是它可以接受字符串或整數值參數。當給的是整數參數時,它就簡單地返回集合的第(nth)條目,0為第一條目。當給的是一個字符串值時,它嘗試通過它的名稱屬性來取得條目。Item (名稱)方法不分大小寫,這是相當有用的,它不需要先對字符串進行大小寫轉換就可以接受名稱。

提示! 如果你熟悉Visual Basic或VBA並經常使用默認方法和默認屬性,那你要注意,這種特性在Visual LISP是不存在的。例如,在Visual Basic中,通過以下任意一種途徑來訪問Item方法都是可行的:
Object.Item(12) 或 Object(12) 或 Object(“Name”) 

這是因為在VB或VBA中,Item方法是大多數對象的默認方法。Visual LISP並不支持這種特性,它需要在每次使用時都闡明所有屬性和方法。例如:

(vlax-invoke-method documents “Item” 12) 會有效果… 
(vla-item documents “Drawing1.dwg”) 會有效果… 
(vlax-invoke-method documents 12) 不會有效果。 

使用圖3-2的例子,Item方法可通過以下任何方法使用:

(vla-Item documents 1) 
(vla-Item documents “Drawing1.dwg”) 
(vlax-invoke-method documents “Item” 1) 
(vlax-invoke-method documents ‘Item “Drawing1.dwg”)
 

(vlax-invoke-method object method [arguments]...) 或 
(vla-method object arguments) 或 
(vlax-invoke object method [arguments] ...) 


調用關聯於對象的方法並為方法提供任何所需的參數。如果成功,將返回結果。如果對象沒有提供對應的方法,將會產生ActiveX錯誤。例如,在Text(文本)圖元中調用“Offset”(偏移)方法,將會產生ActiveX錯誤。

參數: 
Object – 一個vla-對象 
Method – 由對象顯露的方法 
Arguments – 支持該方法的任何所需的參數 

示例: 
(vlax-invoke-method objLine “Move” point1 point2) 
(vla-Move objLine point1 point2) 
(vlax-invoke objLine “Move” point1 point2)
 

所有這些示例做的事情都一樣。對於大部分AutoCAD對象來說都是可行的,但對於由TypeLib接口或外部應用程序或ActiveX組件輸入創建的對象則不都可行。你可以將第一種方法用於外部應用程序對象,而可以將第二種方法用於內部對象。第三種方法是為了R14的向后兼容。

提示! 當你選擇對屬性和方法用Get或Put中的任意一種形式時,你會發現用較長的形式(如vlax-put-property)比用較短的形式(如vla-put-color)更靈活。原因是通過從函數中分離出屬性名稱,你就可以定義函數和循環語句,它們可以接受一個屬性列表及相關的數值,例如...

(defun MapPropertyList (object proplist)
  (foreach propset proplist
    (if (vlax-property-available-p object (car propset))
      (vlax-put-property object (car propset) (cadr propset))
    )
  )
)


當試圖在方法上使用這種方式時要特別小心,因為方法的參數列表會隨着對象和方法的變化而變化。有一些方法不需要參數,而另一些則隨長度變化。

數據類型

數據類型是用於描述給定對象或屬性可包含的數值的類型。數據類型的例子有整數、雙精度、貨幣、日期、字符串等等。在AutoLISP已經享受“類型無關”多年后,Visual LISP也同樣可以,但不單只這樣。在AutoCAD里,你可以盡可能地通過AutoLISP來保留這種類型無關,但當涉及其它應用程序時,例如Microsoft Excel,你將不可避免而且明智地用到數據類型。

類型無關並非免費午餐,其代價是效率低下。當你提前聲明了數據類型,你就通知編譯器調動僅僅夠用的資源來匹配預定數據。例如,存儲整數類型的數據遠比存儲“長”數據值要低得多。當你未使用數據類型時,所有數據都會自動分配盡可能長的數據類型,以確保能匹配所有可能出現的數據。其結果導致應用程序消耗的資源遠比它的需求大得多,無論是從初始加載的尺寸或者其運行時間資源的分配。

這就是為什么程序開發的語言中,象C++、Java,甚至是Visual Basic通常都是比較快的(相比使用自由類型語言編程的同樣功能)。他們確保能提前精簡處理以保證運行時有更快的性能。AutoLISP並不這樣做,因此是相對慢的處理語言。而Visual LISP相對會快一些,但只有你利用其新的特性,讓其最盡可能發揮。

常量和枚舉
常量是特殊的數據類型。正如其名,它的值是不可改變的。有時被稱為靜態。通常來說,常量是由程序語言或由托管應用程序本身提供,作為一種方便的手段。例如,acByLayer常量在屬性值中可以被256代替。名稱值比整數值更好明白也更好記。例如,以下兩個語句在功能上說是一致的。

(vla-put-color object acByLayer) 
(vla-put-color object 256)
 

枚舉是常量的邏輯組合,它用來確定常量值范圍。例如你可以用顏色值1、2、3、4、5,但也可以將之常量化為acRedacYellowacGreenacCyanacBlueacMagentaacWhite,這樣更清晰。這種類型的相關常量值范圍即稱為枚舉。參看附錄A為標准的AutoCAD枚舉清單。

提示!並不是所有的ActiveX枚舉都在Visual LISP中有提供。例如,標准的Decimal(十進制)或Short(短)數據類型並沒有鏡像為vlax-vbDecimal或vlax-vbShort。請參閱第六章學習更多關於數據類型的信息。

變體和安全數組
在上節的數據類型中,有提到對自由類型聲明使用最大的可用配額,例如在AutoLISP中的(setq)語句。事實上,是分配了一個變體數據類型,變體包括所有的數據類型,它提供了足夠的資源空間去包含任何其它數據類型,可以是數值、日期、字符串或其它。事實上,變體數據類型是ActiveX產生出來的。但這個概念更具有一般性,在ActiveX之前已經存在很長的時間。

事實上Visual LISP包含了將所有ActiveX數據轉換為帶有指示包含哪類類型的區分符的變體。感覺有點亂,但事實很簡單。該容器是一個包含有貨幣數據類型值的變體,當你分配給對象一個新值時,你必須提供區分符以使得這個數據能夠正確儲存。這是必須要做的,尤其是你在AutoCAD和其它應用程序(如Microsoft Excel)之間傳遞數值時。

除了發送數值外,你還可以從變體值中查詢嵌套的數據類型,也可將值正確的轉換成為相關的LISP數據類型。例如,你可查詢變體對象值是否包含了雙精度值。然后你可以在LISP中將這個數值讀取為實數(REAL)數據類型。Visual LISP提供了大量的函數用於在LISP環境中創建、讀取、修改變體量數據值。

安全數組相當於AutoLISP中的LIST對象。主要的區別在於它是靜態的。意思就是說他不可能根據他們能存儲的數字的多少來加長或改變項數。這將避免了在試圖分配或取得超出數組長度的元素時產生的不必要的錯誤。這就是它們之所以被稱為“安全”的原因。任何傳遞到ActiveX的LIST結構必須先轉換成安全數組。任何從ActiveX對象獲得的LIST面向對象的數據都必須通過象(car)、(nth)、(accoc)、(mapcar)、(member)等的LISP函數轉換成LIST數據類型。Visual LISP為創造操作、閱讀安全數組數據值提供了大量的功能。

更多關於變體和安全數組的內容,請參閱第六章。

命名空間
命名空間是分配用於運行過程的虛擬空間,它與空間中的其它資源相互配合。但它有時也可以和其它命名空間中的其它過程相聯系。可以把命名空間想象成卧室。你的應用程序就如在卧室工作的人,也即在特定命名空間的過程。其它的應用程序就如在鄰近卧室(命名空間)工作的一樣,這兩個人可以相互獨立和隔離的,但他們也可以互相傳遞數據以便溝通。這就是命名空間工作的原理。

使用命名空間的好處在於可以在特定的命名空間中的過程與另外命名空間相獨立的,這樣可以在它們之間不相互破壞(如在爭奪保存資源時)。它們也可直接通過它們的命名空間加載和卸載過程。換句話說,這有點象拆掉房子里一間卧室,而房子就如模塊化形式建的一樣。移去一個房間不會影響到其它房間或過程的生存。

可能使用命名空間最大的短處是會導致在操作系統或其宿主應用程序上的一些開銷。為了管理好給定的命名空間,它必須有自己的內存地址范圍和指針分配。這需要消耗額外的資源去跟蹤和控制命名空間,這反過來又在必要時提供了直接的方法去訪問它、卸載它或暫停它。

AutoCAD提供了在Visual LISP內部對命名空間的內部管理方法,同樣在ObjectARX和VBA中也可以。這是Visual LISP比AutoLISP功能強大改進的又一表現。實際上每個打開的文檔都是其自己的命名空間(如果你不是在單文件模式下工作的話),當在一個圖形中設置一個變量而又試圖在另一個圖形中讀取它時,這個影響就會看到。是有辦法可以實現在這些圖形中傳遞變量的,我們第十章將會談到。

接口和類型庫
接口是用於連接其它ActiveX過程或構件的對象模型的手段。當你想利用其它應用程序的特定的屬性、常量或方法時,你首先要定義一個接口去加載那個目標應用的對象模型。例如,有時你想通過Visual LISP來利用Excel自己的工具直接用Microsoft Excel來保存一些AutoCAD信息到電子表格文件。這就需要定義接口,然后就可使用類型庫

要使用類型庫,就必須將其加載到內存,並確定接口指針已經定義。Visual LISP提供了一毓函數用於加載和配置類型庫接口。

(vlax-import-type-library 
  :tlb-filename name string 
  :methods-prefix    string 
  :properties-prefix string 
  :constants-prefix  string 


輸入類型庫參照到當前命名空間中。

參數
:tlb-filename string – (字符串) 為類型庫文件的路徑和文件名 
:methods-prefix string – (字符串) 為任意前綴字符串標識符 
:properties-prefix string – (字符串) 為任意前綴字符串標識符
:constants-prefix string – (字符串) 為任意前綴字符串標識符

示例
(vlax-import-type-library
  :tlb-filename             "c:\\myfiles\\typelibs\\tlfile.tlb"
  :methods-prefix           "dsxm-"
  :properties-prefix        "dsxp-"
  :constants-prefix         "dsxc-"
)


該示例輸入了由tlfile.tlb文件定義的外部應用程序或控件的類型庫接口。其它的參數定義了類型庫接口所暴露的方法、屬性和常量的前綴。

如果該類型庫提供了一個名為AddNumbers的方法,在我們的Visual LISP代碼中它將被識別為dsxm-AddNumbers。有趣的是,一旦你已經輸入了類型庫並且程序運行成功后,Visual LISP將識別這些外部應用程序中的所有已定義的屬性、方法、常量,並將其做為內置的LISP函數把它們的代碼變藍。這也是Visual LISP IDE可以幫你編程及提高你及時發現錯誤的能力的另一原因。

圖3-3 類型庫接口

類型庫僅僅是一個接口,它暴露了提供者的所有對象模型成員供給其它應用程序查詢用。當加載類型庫時,它立刻定義並識別相關應用程序提供者的所有公開暴露的屬性、常量和方法給應用程序使用者使用。

在圖3-3中,Excel類型庫被加載以做便Visual LISP可以連接到Excel對象模型並使用其暴露的工具。這樣可以節省你很多時間和麻煩,因為它在Excel中建立了直接的訪問工具,這樣就可以做你想需要的而不必嘗試在Visual LISP中重復另起爐灶。下面的例子顯示了它是如何使用的。

例如,當通過從Visual LISP中調用,將一個定值做為參數提供給Excel函數,你可以用常量枚舉名來代替實際所代表的數值以使得你的編碼清晰易懂。這也省去了你需要瀏覽Excel中的所有枚舉並把它們翻譯成Visual LISP的時間。如果Excel提供了一個如put-cellcolor的常量時,那就可以在Visual LISP中直接使用它。

Visual LISP需要類型庫信息來確定對象的方法、屬性和常量是否存在。有些對象不含有任何類型庫信息,例如AcadDocument對象。

(vlax-typeinfo-available-p object) 

如果對象的類型庫信息存在,返回T。如果不存在,則返回nil。

參數:
Object – 一個vla-對象。 

(defun Excel-Get-Cell (rng row column)
  (vlax-variant-value
    (msxl-get-item
      (msxl-get-cells rng)
      (vlax-make-variant row)
      (vlax-make-variant column)
    )
  )
)
(defun Excel-Put-CellColor (row col intcol / rng)
  (setq rng (Excel-Get-Cell (msxl-get-ActiveSheet xlapp) row col))
  (msxl-put-colorindex (msxl-get-interior rng) intcol)
)


上例中定義的第二個函數提供了一個在Visual LISP中對一個Excel工作表中的給定單元填色的方法。這可以通過使用Excel中已暴露接口的方法,這是通過首先加載Excel類型庫實現的。這個以上顯示的類型庫項帶有一個 msxl-前綴。

當你調用了一個類型庫接口,其中涉及到的函數隨后會被VLISP編輯器語法引擎識別到。當你正確地輸入了它們后,它們就會改變顏色以顯示它們確實被從外面的類型庫接口中被視為一個有效的函數而顯示出來。這是一個很有用的編碼練習的基礎:語法感知。

提示!類型庫有很多種形式,他們通常是.TLB文件。但也可以是.OLB、.DLL,甚至是.EXE。值得一提的是Microsoft Office 97 和 2000版通常用.TLB文件,而OFFICE XP自己使用.EXE文件來對類型庫提供對其它應用的接口定義。請翻閱與你准備使用外部應用程序或服務相關的參考資料以了解它是如何暴露共ActiveX類型庫信息的內容。

盡管變體和安全數組數據類型這個話題在本書的前幾節已經講過,但在Visual LISP的ActiveX領域中它們具有相當重要的位置,值得我們用一整章的篇幅來專門講解。我們將首先簡要了解他們是什么,然后開始探索如何通過Visual LISP函數來使用它們。

正如我們前面提到的,變體是一種數據類型,它被設計成能包含所有任何其它數據的通用容器。他們消耗最多的內存並可處理所有的數據類型,因為他們會根據資源需求取最大內存。

象C/C++、Visual Basic以及Delphi這類語言會提供聲明語句去提前通知編譯器確定每個變量將包含什么數據類型。這不僅保證了精簡的資源需求,同時也允許編輯期間進行錯誤檢查,以防止運行時的問題。

Visual LISP變體函數
(vlax-make-variant [value] [type]) 
使用給定的值或符號賦值來創建一個變體對象

參數:
Value - 要指定給變體的值。如果省略該參數,變體將創建為 vlax-vbEmpty 類型(未初始化)。
Type – 變體的數據類型,如果省略該參數,變體將根據最接近的ActiveX數據類型來確定LISP數據類型(看下表)。

示例:
(vlax-make-variant) 或 (vlax-make-variant nil) 
創建一個未初始化(vlax-vbEmpty)變體。

(vlax-make-variant 10 :vlax-vbInteger) 
創建一個整型(vlax-vbInteger) 變體,其值為10。

(vlax-make-variant “vlisp example”) 
創建一個字符串類型(vlax-vbString)變體,其值為“vlisp example”。

(setq dblarray (vlax-make-safearray vlax-vbDouble ‘(0 . 3))) 
(vlax-make-variant dblarray :vlax-vbArray) 
創建一個包含雙精度值安全數組的變體。

提示!ActiveX數據類型中的十進制和短型在Visual LISP中並不支持,但當從外部資源讀取值時,你可以用(vlax-variant-type)來指定其類型。將這些類型的數據發送到外部資源時,你需要使用數字表示法來替代(vlax-vbDecimal)和(vlax-vbShort),因為在Visual LISP中它們並未作為枚舉提供。例如,十進制數據類型的枚舉值為14。

變體數據類型
如果你不為變體構造器指定數據類型又會怎樣?Visual LISP將會使用默認映射嘗試將它轉換到一個適當的數據類型。表6-1顯示了從LISP到變體的數據類型的默認映射。

  LISP 數據類型      分配的變體默認數據類型   
  nil      vlax-vbEmpty   
  :vlax-null      vlax-vbNull   
  INT (integer)      vlax-vbLong   
  REAL (float)      vlax-vbDouble   
  STR (string)      vlax-vbString   
  VLA-OBJECT      vlax-vbObject   
  :vlax-true or :vlax-false      vlax-vbBoolean   
  VARIANT      與初始值的類型相同   
  SafeArray      vlax-vbArray   
  N/A      vlax-vbShort   
  N/A      vlax-vbDecimal   
  N/A      vlax-vbDate   



表 6-1 – Visual LISP默認LISP->變體數據類型映射 

(vlax-variant-type variant) 
返回變體的數據類型,如果variant不是變體,則返回錯誤信息。返回值是數據類型的枚舉值(查看附錄A的數據類型枚舉值)。

參數:
Variant – 變體。

示例:
(setq vartest (vlax-make-variant 6 vlax-vbInteger)) 
(vlax-variant-type vartest) 
返回 2 (整數類型) 

(setq vartest (vlax-make-variant “dog” vlax-vbString)) 
(vlax-variant-type vartest) 
返回 8 (字符串類型) 

(vlax-variant-value symbol) 
返回包含於變體符號中值。如果symbol不包含變體數據類型。則返回錯誤信息。

參數:
Symbol – 包含變體值的符號。

示例:
(setq vartest (vlax-make-variant “testvalue” vlax-vbString)) 
(vlax-variant-value vartest) 
將“testvalue”值作為字符串結果返回。

(setq sa (vlax-make-safearray vlax-vbDouble ‘(0 . 2))) 
(setq vartest (vlax-make-variant sa vlax-vbDouble)) 
(vlax-variant-value vartest) 
返回#<safearray...>值,它是vla-object類型。

(vlax-safearray->list (vlax-variant-value vartest)) 
返回結果是(0.0 0.0 0.0)列表值。

(vlax-variant-change-type symbol type) 
更改變體的數據類型。

參數:
Symbol - 變體值
Type - 要轉換到的數據類型數字或枚舉

示例:
(setq vartest (vlax-make-variant 5 vlax-vbInteger)) 
(setq vartest (vlax-variant-change-type vartest vlax-vbString)) 
轉換vartest為字符串類型(vlax-vbString)變體,它將致使通過(vlax-variant-value)返回的值為“5”。

(vlax-make-safearray type dim1 [dim2] …) 
創建一個安全數組,其數據類型為type,維度范圍dim1,以此類推,可以指定額外的維度。不管什么原因,如果操作失敗,語句將返回nil。 

參數:
Type – 數據類型(整數或枚舉)
Dim1 – 第一維數組(一維數組)
Dim2 – (可選)第二維維數(二維數組)等。

示例:
(setq sa (vlax-make-safearray vlax-vbDouble ‘(0 . 2))) 
創建一個雙精度的單維數組,它可容納三個不同的元素(0,1,2)。

(setq sa (vlax-make-safearray vlax-vbString ‘(0 . 1) ‘(1 . 3))) 
創建一個字符型二維數組,第一維包含兩個元素,由索引0開始。第二給包含三個元素,由索引1開始。

提示!要填充安全數組,可使用(vlax-safearray-fill)還是(vlax-safearray-put-element)來填充,至於使用哪個填充,可根據用戶是否需要一次只指定一個元素或一次性指定所有元素來決定。

(vlax-safearray->list symbol) 
如果symbol包含安全數組,元素將轉換為LISP LIST數據類型被返回。如果symbol不包含安全數組,會產生錯誤。你需要將對該函數的調用封裝到錯誤捕獲內以使這個錯誤能得到適當處理。

參數:
Symbol – 包含安全數組的符號

(vlax-safearray-type symbol) 
如果symbol包含安全數組,元素的數據類型將以枚舉結果返回(整數值)。這將可匹配整數或枚舉結果(查看附錄X有關數據類型枚舉)。如果symbol不包含安全數組,將產生錯誤。

參數:
Symbol – 包含安全數組的符號

示例:
(setq sa (vlax-make-safearray vlax-vbdouble ‘(0 . 3))) 
(vlax-safearray-type sa) 
返回5(雙精度),相當於vlax-vbDouble

(vlax-safearray-fill safearray ‘element-values) 
指定值給安全數組內的多個元素。如果提供的參數不是一個數組,將返回ActiveX錯誤。你需要將對該函數的調用封裝到錯誤捕獲內以使這個錯誤能得到適當處理。

參數:
Safearray        安全數組類型的對象
Element-values        一個存儲於數組中的值列表,你可以指定與數組中元素一樣多的值。如果你指定的數值少於元素個數,剩余的元素保留他們當前值或為空。對於多維數組,element-values必須是列表的列表,每一列表對應數組的一維。

示例:
創建一個雙精度值的單維數組:
_$ (setq myarray (vlax-make-safearray vlax-vbdouble '(0 . 2))) 
#<safearray...> 
使用vlax-safearray-fill來填充數組元素值:
_$ (vlax-safearray-fill myarray '(1 2 3)) 
#<safearray...> 
列出數組包含的值以校驗元素值:
_$ (vlax-safearray->list myarray) 
(1.0 2.0 3.0) 

(vlax-safearray-get-element safearray element [element...]) 
返回安全數組中指定元素的值,element的值是整數,表示在該數組中要取得的索引位置。如果safearray參數非安全數組對象,將產生ActiveX錯誤。你需要將對該函數的調用封裝到錯誤捕獲內以使這個錯誤能得到適當處理。

參數:
Safearray –安全數組類型的對象
Element – 整數,指要取得的索引位置

示例:
_$ (setq sa (vlax-make-safearray vlax-vbString '(1 . 2) '(1 . 2) ))
#<safearray...> 
使用vlax-safearray-put-element來填充數組:
_$ (vlax-safearray-put-element sa 1 1 "A") 
"a" 
_$ (vlax-safearray-put-element sa 1 2 "B") 
"b" 
_$ (vlax-safearray-put-element sa 2 1 "C") 
"c" 
_$ (vlax-safearray-put-element sa 2 2 "D") 
"d" 
使用vlax-safearray-get-element來檢索數組第一維的第二元素:
_$ (vlax-safearray-get-element sa 1 1) 
”A” 
_$ (vlax-safearray-get-element a 2 2) 
”D" 

(vlax-safearray-put-element safearray element [element...] value) 
在安全數組中指定新值給單個元素。如果safearray參數不是安全數組對象,將產生ActiveX錯誤。如果提供的元素值不能與數組中的數據類型相匹配,將返回ActiveX錯誤。你需要將對該函數的調用封裝到錯誤捕獲內以使這個錯誤能得到適當處理。

參數:
Safearray         安全數組類型的對象
Element         指向你將指定值的元素所在位置的系列索引值。對於一維數組,指定一個索引值,對於二維數組,指定兩個索引值,以此類推。
Value         指定給每個元素的值。在數組中要指定不同的值給數組中個別的元素,要分開調用獨立的值來對應不同的元素位置。

示例:
_$ (setq sa (vlax-make-safearray vlax-vbString '(1 . 2) '(1 . 2) )) 
#<safearray...> 
使用vlax-safearray-put-element來填充數組:
_$ (vlax-safearray-put-element sa 1 1 "A") 
"A" 
_$ (vlax-safearray-put-element sa 1 2 "B") 
"B" 
_$ (vlax-safearray-put-element sa 2 1 "C") 
"C" 
_$ (vlax-safearray-put-element sa 2 2 "D") 
"D" 
你也可以用vlax-safearray-fill函數來填充數組值,以下的函數調用能和三個vlax-safearray-put-element調用一樣完成同樣的任務:
(vlax-safearray-fill sa '(("A" "B") ("C" "D"))) 

(vlax-safearray-get-dim safearray) 
返回給定安全數組中的維數(數組維數的數字)。如果給定的參數不是數組,將返回ActiveX錯誤。你需要將對該函數的調用封裝到錯誤捕獲內以使這個錯誤能得到適當處理。

參數:
Safearray 安全數組類型的對象

示例:
_$ (setq myarray (vlax-make-safearray vlax-vbinteger '(2 . 5))) 
#<safearray...> 
_$ (vlax-safearray-get-dim myarray) 


(vlax-safearray-get-l-bound safearray dim) 
返回指定數組的維數下界(整數值)。如果給定的參數不是數組,將返回ActiveX錯誤。你需要將對該函數的調用封裝到錯誤捕獲內以使這個錯誤能得到適當處理。

參數:
Safearray – 安全數組類型的對象
Dim – 整數,數組的第幾維,第一維為1

示例:
以下示例是求以下所定義的安全數組的下界值:
(vlax-make-safearray vlax-vbString '(1 . 2) '(0 . 1) )) 
取得數組第一維的起始索引值(下界):
_$ (vlax-safearray-get-l-bound tmatrix 1) 1 

(vlax-safearray-get-u-bound safearray dim) 
返回指定數組維度的上界(整數值)。如果指定的參數不是數組,將返回ActiveX錯誤。你需要將對該函數的調用封裝到錯誤捕獲內以使這個錯誤能得到適當處理。

參數:
Safearray – 安全數組類型的對象
Dim – 整數,數組的第幾維,第一維為1。

(setq sa (vlax-make-safearray vlax-vbString '(1 . 2) '(0 . 1) )) 
_$ (vlax-safearray-get-u-bound sa 1) 

第一維的上界的索引值為2。

取得數組第二維的上界索引值,其值為1:
_$ (vlax-safearray-get-u-bound sa 2) 1 

Visual LISP提供了一系列用於創建、操控和關閉ActiveX對象的函數。這通常是對外部應用程序會話對象而言的,但它同時也可以適用於任何外部進程對象,如DLL或OCX接口。

 

(vlax-get-object program-id)
嘗試連接到存在的對象(進程),與Visual Basic/VBA函數 GetObject (program-id)相同。

 

參數:
Program-ID – 字符串,應用對象類標識符的名稱。例如“Word.Application”或“Excel.Application”。

 

示例:
(setq xlapp (vlax-get-object “Excel.Application”))
成功時返回外部Excel應用程序進程的vla-對象,否則返回nil。

 

(vlax-create-object program-id)
嘗試創建一個新的對象會話(進程)。與Visual Basic函數 CreateObject (program-id)相同。

 

參數:
Program-ID – 字符串,應用程序對象類標識符名稱。例如“Word.Application”或“Excel.Application”。

 

示例:
(setq xlapp (vlax-create-object “Excel.Application”))
成功時返回新的外部Excel應用程序進程的vla-對象,否則返回nil。

 

(vlax-get-or-create-object program-id)
嘗試先連接到存在的對象會話,然后,如果找不到,就嘗試創建一個新的對象會話。這個函數在Visual Basic中沒有對應的函數,它是Visual LISP中特有的。

 

參數:
Program-ID – 字符串,指應用程序對象類標識符名稱。例如“Word.Application”或“Excel.Application”。

 

示例:
(setq xlapp (vlax-get-or-create-object “Excel.Application”))
成功時返回外部Excel應用程序對象的vla-對象,否則返回nil。

 

(vlax-write-enabled-p object)
如果object可以修改則返回T,否則返回nil。

 

備注:請小心該函數。在對象實際上是開放可修改狀態下,有時它會返回False。

 

參數:
Object – 任何Vla-對象

 

(vlax-object-erased-p object)
如果object在圖中已經被刪除則返回T,否則返回nil。

 

參數:
Object – 任何代表圖元對象類型的vla-對象。

 

(vlax-release-object object)
從內存中釋放對象。它不是重新分配內存。當釋放一個指向外部應用程序會話的對象時,這里強烈建議使用(gc),它能從操作系統資源中強行釋放外部進程。

 

參數:
Object – 任何vla-對象。

 

警告!盡管對象符號是局部的,函數用完后不一定要釋放對象的資源。但還是建議當已經不需要這個對象時可使用該函數以確保釋放對象。然而,需要提醒的是,既使是釋放了由外部應用程序驅動的對象,它也可能沒有從內存或操作系統進程堆棧中被全部釋放。最好是在你完成代碼后釋放所有不再使用的對象,然后再調用(gc)函數去強制回收內存堆棧。
 
Visual LISP提供的最有用的函數是文件和目錄函數。這些函數集可用於訪問和修改文件屬性,以及列出指定文件夾中的文件及文件夾。使用這些函數的一個例子,是將其用於對話框的列表框的環境中。

可能你喜歡在列表框中顯示圖紙文件清單,而不顯示其擴展名(這樣的名稱會短一些)。就可結合目錄列表框和vl_filename-base函數來實現,如下所示:
(mapcar ‘vl-filename-base (vl-directory-files pathname “*.dwg”)) 

這樣將返回名稱的列表,如(“圖形1”“圖形2”…)。注意在這個例子中並沒有提供錯誤檢查。如果(vl-directory-files)函數返回nil,其余的語句就會因出錯而崩潰。該例只是用來證明這些函數是如何相結合並用於使文件和目錄的信息更容易使用。

(vl-file-size filename) 
以整數形式返回filename的字節數。如果沒找到文件名,就返回nil。

參數:
Filename 字符串,指要查詢文件的名稱。

示例:
(vl-file-size “c:\\myfile1.txt”); 返回 125523 (大約 124 Kb) 

(vl-file-copy source-filename target-filename [append]) 
從源位置(source-filename)復制文件到目標位置(target-filename)。如果append為非nil,同時目標文件存在,源文件就會被添加到已存在的目標文件。如果目標文件存在而append為nil,該文件將不被復制同時返回值為nil。如果成功,將返回整數值。

參數:
Source-filename 被復制文件的名稱,如果文件不在默認的搜索路徑中,則該文件名必須包含完整的路徑位置。
Target-filename 源文件要復制到的目標名稱。如果目標路徑未指定,則使用默認的工作目錄位置。
Append (可選)如果是非nil,代表如果目標文件存在,源文件將會被附加到目標文件上去。

示例:
(vl-file-copy “c:\\myfile1.txt” “c:\\mycopy.txt”) 
(vl-file-copy “c:\\myfile2.txt” “c:\\mycopy.txt” T); 添加目錄文件
 

(vl-file-delete filename) 
刪除文件名。如果成功返回T,否則返回nil。

參數:
Filename 字符串,指要刪除的文件的名稱。

(vl-file-rename old-name new-name) 
重命名現有的文件,由old-name重命名為new-name。如果成功返回T,否則返回nil。

參數:
Old-Name 字符串,指現有文件的名稱。
New-Name 字符串,指重命名后的文件名稱。

(vl-file-directory-p filename) 
如果filename是目錄文件夾名稱則返回T,如果filename實際上是一個文件或根本不存在,則返回nil。

(vl-file-systime filename) 
返回文件最后修改的日期和時間值列表。返回的列表為(年 月 星期 日  時 分 秒)的格式。

(vl-filename-base filename) 
返回不帶路徑和擴展名返回基本文件名。

參數:
Filename 字符串,指文件名,可帶或不帶路徑和擴展名。

示例:
(vl-filename-base “c:\\myfiles\\drawing1.dwg”) 
返回“drawing1”
(vl-filename-base “drawing1.dwg”) 
返回“drawing1”


(vl-filename-directory filename) 
從指定的filename字符串返回目錄或路徑前綴值。

參數:
Filename 字符串,指包含路徑的文件名。

示例:
(vl-filename-directory “c:\\dwgfiles\\working\\drawing1.dwg”) 
返回: “c:\\dwgfiles\\working”
 

(vl-filename-extension filename) 
返回給定文件名字符串的擴展名。

參數:
Filename 字符串,指文件名稱。

示例:
(vl-filename-extension “c:\\myfiles\\drawing1.dwg”) 
返回 “dwg”
 

(vl-filename-mktemp [pattern directory extension]) 
創建一個用於臨時文件的獨特文件名。返回代表文件名稱的字符串,格式為:directory\base<XXX><.extension>。其中base多達5個字符,由pattern中取得,XXX是一個3字符的獨特組合。

所有在VLISP會話中由vl-filename-mktemp生成的文件名都會在你退出VLISP會話時被刪除。

參數:
Pattern 字符串,包含了文件名樣式;如果nil或缺省,vl-filename-mktemp就用“$VL~~”。
Directory 字符串,臨時文件目錄的名稱;如果nil或缺省,vl-filename-mktemp就在以下順序中選擇一個目錄:
■如果在pattern已指定目錄,就用它。
■在TMP環境變量中指定的目錄。
■在TEMP環境變量中指定的目錄。
■當前目錄。
Extension 字符串,指定給文件的擴展名;如果nil或缺省,vl-filename-mktemp使用pattern中的擴展名部分(有可能是空字符串)。

示例:
(vl-filename-mktemp) 
"C:\\TMP\\$VL~~004" 
(vl-filename-mktemp "myapp.del") 
"C:\\TMP\\MYAPP005.DEL" 
(vl-filename-mktemp "c:\\acad2002\\myapp.del") 
"C:\\ACAD2002\\MYAPP006.DEL" 
(vl-filename-mktemp "c:\\acad2002\\myapp.del")
"C:\\ACAD2002\\MYAPP007.DEL" 
(vl-filename-mktemp "myapp" "c:\\acad2002") 
"C:\\ACAD2002\\MYAPP008" 
(vl-filename-mktemp "myapp" "c:\\acad2002" ".del") 
"C:\\ACAD2002\\MYAPP00A.DEL"
 

(vl-directory-files path pattern [mode]) 
按照不同的模式,返回文件或子文件夾的列表。

參數:
Path 字符串,指要查詢的路徑名。
Pattern 字符串,指要查詢文件。可以包含通配符。如果不指定或nil,則使用“*.*”
Mode (可選)整數。以下其中一個…
-1 = 只列出目錄名
0 =  列出文件及目錄(未指定時的默認值)
1 =  只列出文件

示例:
命令: (vl-directory-files “c:\\dwgfiles\\Working” “*.dwg”) 
(“drawing1.dwg” “drawing2.dwg” . . .) 
命令: (vl-directory-files “c:\\dwgfiles” nil -1) 
(“.” “..” “Finished” “Working”) 
命令: (vl-directory-files “c:\\dwgfiles” nil 1) 
nil
 
AutoLISP提供了大量強大的映射和循環函數,如 (while)(foreach)(mapcar)(apply)。而Visual LISP也增加了一些更適合用於與ActiveX集合對象的函數。這些函數包括有 (vlax-for)(vl-every)(vlax-map-collection)等等。

(vlax-map-collection object function) 
應用function到集合對象的成員(對象),如果對象不是集合,則生成錯誤。

參數:
Object 代表集合的vla對象。
Function 用於對象的符號或lambda表達式。

示例:
(setq docs (vla-get-documents (vlax-get-acad-object))) 
(vlax-map-collection docs ‘vlax-dump-object) 
這將重復每個已打開文件並列表所有特性...
; IAcadDocument: An AutoCAD drawing 
; 特性值: 
; Active (RO) = -1 
; ActiveDimStyle = #<VLA-OBJECT IAcadDimStyle 046bb644> 
; ActiveLayer = #<VLA-OBJECT IAcadLayer 046bbd84> 
; ActiveLayout = #<VLA-OBJECT IAcadLayout 046b8a64> 
; ActiveLinetype = #<VLA-OBJECT IAcadLineType 046b89b4> 
… 還有其它… 


(vlax-for symbol collection [expression1 [expression2]]…) 
循環集合的成員對象並對每一成員對象執行語句。如果第二個參數不是集合對象,將生成錯誤。引用的symbol是局部的和臨時的,就如 (foreach)一樣。

參數:
Symbol 指定給集合中每個vla對象的符號。
Collection 代表集合的vla對象
Expressions 求值的一個或多個語句(可選項)

示例:
(setq acad (vlax-get-acad-object)) 
(setq layers (vla-get-layers (vla-get-activedocument acad))) 
(vlax-for eachLayer layers
  (princ (vla-get-name eachLayer))
  (terpri) 
)
 
這將在命令提示處列出活動圖形中所有圖層的名稱。

(vl-position item list) 
找到時返回在list中item的第n個位置。如果list中未找到item,則返回nil。第一元素的位置索引為零(0)。

參數:
Item  任何符號或值。
List  值或符號列表。

示例:
(setq mylist ‘(“A” “B” “C”)) 
(vl-position “B” mylist) 返回 1 
(vl-position “b” mylist) 返回 nil


(vl-every predicate-function list ...)
       

      vl-every 函數將每個表的第一個元素作為參數(如果有多個表則形成參數表)傳遞給測試函數,然后傳遞每個表中的下一個元素,以此類推,直至其中一個表到達結束處為止。


      參數:

      Predicate-function測試函數。它可以是任何一個函數:參數個數和 vl-every 提供的表的個數一致,且對任何用戶指定條件返回T。如果 predicate-function 結合每個元素后均返回非 nil 值,函數返回 T,否則返回 nil。


      predicate-function 的值可以采用下列格式之一:

      ■符號(函數名)

      ■(function(lambda(A1 A2)...))


      List(s) 被測試的列表。


      示例:

      在給定的文件夾中檢查大於1024字節的文件:

(vl-every 
  (function
    (lambda (filename) 
      (> (vl-file-size filename) 1024)
    )
  )
  (vl-directory-files nil nil 1) 


      對比兩個表...

(vl-every '= '(1 2) '(1 3)) 
返回 nil 
(vl-every '= '(1 2) '(1 2 3)) 
返回 T
       


      第一個表達式返回 nil,因為 vl-every 比較兩個表中的第二個元素,而它們在數值上並不相等。第二個表達式返回 T,因為 
vl-every
       在處理完較短的表 (1,2) 中所有元素后即停止比較,而直到這時為止,兩個表是相等的。如果到達了表的結束處,則 
vl-every
       返回非 nil 值。


_$ (setq list1 (list 1 2 3 4)) 
(1 2 3 4) 
_$ (setq list2 nil) 
nil 
_$ (vl-every '= list2 list1) 

      返回值為 T,因為 
vl-every
       處理 nil 表時,假定已經到達了表的結束處(盡管沒有對其中任何元素應用論斷)。既然如此,
vl-every
     將返回非 nil 值。
(vl-load-all filename) 
      在同一時間內加載命名的VLX文件到所有打開的文檔中。它還會加載那些在同一
AutoCAD
      應用程序會話中后續打開的任何文檔中。


      參數:

      Filename 符號或字符串,代表有效的文件名。


(vl-propagate ‘symbol)
       

      在AutoCAD應用程序名稱空間中復制符號和與其相關的值到所有打開的文檔中去,以及在同一AutoCAD應用程序會話中后續打開的任何文檔中。


      參數:

      Symbol 一個引用符號的名稱。


(vl-bb-set ‘symbol)
       

      張貼符號及其相關的值到黑板名稱空間。黑板名稱空間是AcadApplication名稱空間的一部分,它可被所有在Documents集合中打開的文件訪問。這提供了與Windows粘貼板相似的功能,不過它只用於張貼和取回LISP符號而已。


      參數:

      Symbol 一個引用符號的名稱。


(vl-bb-ref ‘symbol)
       

      從黑板名稱空間取回符號及其相關的值。


      參數:

      Symbol 一個引用符號的名稱。


(vl-list-exported-functions) 
      返回那些由任何已加載的VLX應用程序顯露給文檔名稱空間的所有函數的表。


(vlax-add-cmd “globalname” ‘function [“localname” | flags])
       

      將VLX應用程序中使用(defun)方式而未定義為C:的函數定義為命令行函數。你必須至少要指定globalname和function項。localname和flags項是可選的。你不能將(vlax-add-cmd)用於顯露那些創建反應器對象或充當反應器回調的函數顯示為命令。如果成功返回globalname值,不成功則返回nil。


      推薦從獨立名稱空間VLX使用vlax-add-cmd函數。然后使用APPLOAD命令明確加載VLX,這樣比將LISP文件放到啟動組好。


      參數:

      GlobalName 字符串,在命令提示符中指定的命令名稱。

      Function 代表函數名稱的引用符號。

      LocalName (可選項) VLX應用程序名稱空間內部的命令名稱。如果省略,默認為GobalName。

      Flags (可選項)修改關於透明、pickset和pickfirst等項命令行為。

主要標志選項:
ACRX_CMD_MODAL
       (0) 在使用其他命令時不能調用該命令。

ACRX_CMD_TRANSPARENT
       (1) 在使用其他命令時可以調用該命令。

二級標志選項:
ACRX_CMD_USEPICKSET
       (2) 檢索選擇優先集時,在 AutoCAD 中清除設置。命令能夠獲取優先集,但不能檢索或設置夾點。

ACRX_CMD_REDRAW
       (4) 檢索選擇優先集或夾點集時,不將它們從 AutoCAD 中清除。命令可獲取優先集和夾點集。


      如果同時設置了 ACRX_CMD_USEPICKSET 和 ACRX_CMD_REDRAW,則效果和僅設置 ACRX_CMD_REDRAW 一樣。關於標志的詳細信息,請參見 《ObjectARX 參考手冊》中的“Command Stack”。


      示例:

      在Transparent.VLX中定義並加載到AutoCAD中的函數:

(vl-load-com) 
(vl-doc-export ‘example1) 
(defun example1 () 
   (princ “\這是一個透明函數的示例。”)
   (princ) 
)   
(vlax-add-cmd “example1” ‘example1 “example1” ACRX_CMD_TRANSPARENT) 
(princ) 
命令: LINE 
指定第一點: ‘EXAMPLE1 
這是一個透明函數的示例。 
重新回到LINE命令。 
指定第一點:
       


(vlax-remove-cmd “globalname”) 
      刪除之前用(vlax-add-cmd)定義的命令定義。函數本身並不受影響,但是命令提示符接口從命令組中被刪除了。


      參數:

      GlobalName 字符串,指要刪除的命令名稱。

      示例:

(vlax-remove-cmd “example1”) 

(vlax-remove-cmd “example2”) 
nil
       


(vl-acad-defun ‘function)
       

      使 (defun)的LISP函數能作為C:函數給ObjectARX應用程序調用。


      這使函數可以經由ObjectARX應用程序訪問。


      參數:

      Function 代表函數名稱的引用符號。


      示例:

(vl-acad-defun ‘example1)
       


(vl-acad-undefun ‘function)
       

      取消一個之前用(vl-acad-defun)函數顯露的命令。如果成功則返回T,否則返回nil。


      參數:

      Function 代表函數名稱的引用符號。

      示例:

(vl-acad-undefun ‘example1”) 
T
       
Visual LISP提供了專門的函數用於訪問和修改Windows注冊表。你可以用這些函數在本地注冊表的HKEY_LOCAL_MACHINE和HKEY_CURRENT_USER單元中查詢和修改注冊表項。你不能使用Visual LISP注冊表函數來訪問遠程注冊表,也不能用Visual LISP來訪問HKEY_USERS和HKEY_CLASSES_ROOT以及HKEY_CURRENT_CONFIG注冊表單元。

注意,即使在Visual LISP可以訪問的注冊表單元,你仍會受限於進程所有者的安全環境以致限制了你的訪問。換句話說,如果Visual LISP應用程序是被一個對這台機器權限有限的用戶使用時,有些注冊表項可能無法訪問或不能被Visual LISP修改。這個問題在網絡環境中需要重點考慮,因為它的組策略會修改注冊表的訪問許可。

(vl-registry-read regkey [value-name]) 
如果注冊表中有定義注冊表項或注冊表值名(符號),則返回值指定給一個明確的注冊表項或注冊表值名(符號)的值。如果未找到該注冊表項或值名,則結果就為nil。

參數:
RegKey 在HKEY_LOCAL_MACHINE或HKEY_CURRENT_USER單元中的注冊表項名稱。
Value-Name (可選項)在指定注冊表項下方的從屬值名(符號)的名稱。

示例:
(vl-registry-write “HKEY_CURRENT_USER\\Example1” “FOO” “123”) 
“123”
(vl-registry-read "HKEY_CURRENT_USER\\Example1" “FOO”) 
“123” 
(vl-registry-read “HKEY_CURRENT_USER\\Example1”) 
nil 
(vl-registry-write "HKEY_CURRENT_USER\\Example2" "" "ABCDEF") 
"ABCDEF" 
(vl-registry-read "HKEY_CURRENT_USER\\Example2") 
"ABCDEF"
 

(vl-registry-write regkey [value-name] value) 
將值寫入注冊表項或注冊表項的值名中去,如果成功返回值。如果不成功則返回nil。

參數:
RegKey 注冊表項的名稱。
Value-Name (可選項)在指定注冊表項下方的從屬值名(符號)的名稱。
Value 寫入到指定的注冊表項或值名的值。

示例:
(vl-registry-write “HKEY_CURRENT_USER\\Example1” “TEST1” “123”) 
“123” 
(vl-registry-write “HKEY_CURRENT_USER\\Example1” “” “456”) 
“456” 

(vl-registry-delete regkey [value-name]) 
刪除注冊表中指定位置的注冊表項及其相關的值,成功時返回T,如果失敗則返回nil。如果提供了value-name且不為nil,指定的值將被從注冊表中清除。如果沒有value-name或為nil,該函數將刪除指定注冊表項及它的所有值。如果注冊表中下面有子注冊表項存在,該注冊表項將不能被刪除。要刪除含有子注冊表項的注冊表項,你必須先用 (vl-registry-descendents)來收集子注冊表項並先將它們刪除。

參數:
RegKey 注冊表項的名稱。
Value-Name (可選項)在指定注冊表項下方的從屬值名(符號)的名稱。

示例:
(vl-registry-write "HKEY_CURRENT_USER\\Example1" "TEST1" "123") 
"123" 
(vl-registry-delete "HKEY_CURRENT_USER\\Example1") 
T 

(vl-registry-descendents regkey [value-names]) 
返回指定注冊表項下屬的子項或值名的表。如果提供了value-names且不為nil,將從注冊表中列出指定的值名。如果沒有value-names或為nil,該函數則顯示注冊表項的所有子項。還要注意到,返回的值經常是按倒序排列。

參數:
RegKey 注冊表項名稱。
Value-Names 包含regkey入口的數值的字符串。

示例:
(vl-registry-descendents "HKEY_LOCAL_MACHINE\\SOFTWARE") 
("WexTech Systems" "Voice" "Synaptics" "Symantec" "Secure" "Program Groups" "Policies" "ODBC" "Nico Mak Computing" "MicroVision" "Microsoft" "MetaStream" "McNeel" "McAfee" "JavaSoft" "Intel Corporation" "INTEL" "InstalledOptions" "Helios" "DOSLib" "Dell Computers" "Dell Computer Corporation" "Dell Computer" "DameWare Development" "Clients" "Classes" "BVRP Software" "BigFix" "Autodesk" "ATI Technologies" "Apple Computer, Inc." "America Online" "Adobe" "Adaptec" "3Com") 

你可打開 AutoCAD安裝程序的Visual LISP樣板目錄下的RegDump.LSP文件,可看到注冊表函數的更多例子。在這個文件中,你可以找到一個名為 (registry-tree-dump)的有用函數,它對指定注冊表項執行遞歸來搜索到其下級的所有子項和值名。

提示:你可以創建一對Get和Set函數來保存和恢復注冊表值,用於控制標准位置和錯誤捕獲。你應該會發現以下兩個函數是很有用的:

(setq G$REGROOT "HKEY_CURRENT_USER\\Software\\MyApplication\\") 
(defun RegGet (key default / val)
  (if (= nil (setq val (vl-registry-read (strcat G$REGROOT key))))
    (progn
      (regset key default) 
(setq val (vl-registry-read (strcat G$REGROOT key)))
    )
  )
  (if val val default) 

(defun RegSet (key val)
  (vl-registry-write (strcat G$REGROOT key) "" val)
)
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM