在ActiveX技术中,GetEntity方法能够返回一个AcadEntity类型的对象和一个Variant类型变量(表示拾取点的位置)。在拖管封装的ARX中无法直接使用这些返回值,但是在AutoCAD的一个进程中,不同语言中ObjectID的值是一致的,就可以通过ObjectId在两种语言中实现实体的传递。 最核心的部分我已写入下面的GetEntity函数,需要注意:必须在一个模块中实现该函数,因为需要对ActiveX中的GetEntity函数进行错误处理;为了减少客户程序中编程者的记忆量,利用.NET中变量范围的特性,在不同的模块或类使用了同样的函数或对象名称;注意需要引用AutoCAD 2005类型库和AutoCAD/ObjectDBX Common 16.0类型库。PubFunction模块中放置核心的GetEntity函数及其调用的函数,详细代码为:- Imports Autodesk.AutoCAD.ApplicationServicesImports Autodesk.AutoCAD.DatabaseServicesImports Autodesk.AutoCAD.RuntimeImports Autodesk.AutoCAD.GeometryImports Autodesk.AutoCAD.Interop Module PubFunction Private Const VK_ESCAPE = &H1B ' 代表Esc键 Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer ' 功能:判断用户是否按下某一个键 ' 输入:代表键的常量(从API Viewer中获得) ' 调用:API函数GetAsyncKeyState ' 返回:如果用户按下了指定的键,返回True;否则返回False ' 示例: ' If CheckKey(&H1B) = True Then do sth Private Function CheckKey(ByVal lngKey As Long) As Boolean If GetAsyncKeyState(lngKey) Then CheckKey = True Else CheckKey = False End If End Function Public Function GetEntity(ByRef entId As ObjectId, ByRef ptPick As Point3d) As Boolean Dim acadApp As AcadApplication = CType(Application.AcadApplication, AcadApplication) Dim objSelect As Common.AcadEntity Dim basePnt As Object ' 选择对象并判断类型 TryRetry: acadApp.ActiveDocument.Utility.GetEntity(objSelect, basePnt, "选择对象:") Catch ex As Exception When objSelect Is Nothing ' 处理未选择到实体的错误 ' 处理按下Esc键的错误 If CheckKey(VK_ESCAPE) = True Then Exit Function Else GoTo Retry End If GoTo Retry Finally End Try ' 函数的返回值 entId.OldId = objSelect.ObjectID If (basePnt.GetType().IsArray() = True) Then ptPick.Set(basePnt(0), basePnt(1), basePnt(2)) End If Return True End FunctionEnd Module
可以在一个类文件中注册一个命令方法,对GetEntity函数进行测试:- <CommandMethod("ZffTest", "GetEnt", CommandFlags.Modal)> _ Public Shared Sub GetEntity() Dim entId As ObjectId Dim ptPick As Point3d Dim ent As Entity If (PubFunction.GetEntity(entId, ptPick) = True) Then ent = entId.Open(OpenMode.ForRead) CommandLinePrompts.Message(Chr(13) & Chr(10) & "已经选择了" & ent.GetType().ToString) ent.Close() End If End Sub
实际上,如果用对象的Handle作为传递桥梁应该也是可以的,但是我个人习惯用ObejctId。不得不指出,在我们所进行的VBA编程中,由于大家都使用全局变量来传递数据,因此ObjectId和Handle很少使用,但是在VC进行的ARX开发中,一般禁止使用全局变量(为保证工程的可移植性和健壮性),这时候ObjectId和Handle作为函数和类之间传递数据的桥梁非常普遍。 |