乐筑天下

搜索
欢迎各位开发者和用户入驻本平台 尊重版权,从我做起,拒绝盗版,拒绝倒卖 签到、发布资源、邀请好友注册,可以获得银币 请注意保管好自己的密码,避免账户资金被盗
查看: 382|回复: 13

用VB6进行Autocad的二次开发(原创)

[复制链接]

23

主题

561

帖子

13

银币

中流砥柱

Rank: 25

铜币
653
发表于 2014-10-18 19:03:00 | 显示全部楼层 |阅读模式
版本较高一些,都支持COM开发,而vb6基于COM开发是其拿手好戏。因此,用VB6进行Autocad的二次开发是完全可以的!
      当然,AutoDesk官方并没有明确说明关于用vb6开发的相关信息,而且,vb6的autocad二次开发的程序也有一定的局限性,因此,用VB6进行Autocad的二次开发应用并不广泛!
      AutoDesk官方提供VBA开发的方式,VBA与VB语法几乎完全相同,开发方便、灵活,但由于vba是解释执行,运行速度较慢,而且,源代码几乎没有保密性可言,因此,几乎没人有用VBA进行autocad的商业开发。
     本人介绍一些用VB6进行Autocad的二次开发的方法,以抛砖引玉。
一、基本情况介绍
     1、vb6与autocad的连接
    vb6调用任何COM对象(即ActiveX对象,包括ActiveX Dll 、ActiveX EXE等 ),基本都有两种方法,即前期绑定和后期绑定,
前期绑定需要在Vb6IDE环境下引用COM对象,而后期绑定则不需要引用,只需要用代码实现即可。关于前期绑定和后期绑定,是VB6的一些基础知识,这里不做介绍。
      哪么在用VB6进行Autocad的二次开发,是采用前期绑定和后期绑定呢?应该说是都可以了,但是,在编码调试过程中,最好引用COM对象,编码的自动完成功能就值得你这么做!
接下来,我们开始进行VB6+Autocad二次开发的第一步了
(1)打开vb6 IDE,新建一个“标准 exe"工程,在”工程“菜单下,”引用“ Autocad 200* Type Library(你电脑里正确安装的某个版本的Autocad)
(2)新建模块,命名为ModCommon,输入以下代码:
  1. Public objCad As Object  ''定义为全局Autocad对象
  2.    Public Sub ConnectAutoCAD()
  3.     On Error Resume Next
  4.     #Const cadVer = "R16"''条件编译开关,根据你电脑安装的Autocad版本修改,如果实在不知道,把本行代码注释掉也行
  5.     #If cadVer = "R16" Then
  6.         '----------------------------------
  7.         '' R16(autocad2004~2006)
  8.         Set objCad = GetObject(, "Autocad.Application.16")
  9.         If Err Then
  10.             Err.Clear
  11.             Set objCad = CreateObject("Autocad.Application.16")
  12.             objCad.Visible = True
  13.             If Err Then
  14.                 MsgBox "计算机可能没有正确安装相应版本的Autocad", vbOKOnly + vbCritical
  15.                 End
  16.             End If
  17.         End If
  18.         '----------------------------------------------------
  19.     #ElseIf cadVer = "R17" Then
  20.         '     '----------------------------------
  21.         '    'R17(autocad2007~2009)
  22.         Set objCad = GetObject(, "Autocad.Application.17")
  23.         If Err Then
  24.             Err.Clear
  25.             Set objCad = CreateObject("Autocad.Application.17")
  26.             objCad.Visible = True
  27.             If Err Then
  28.                 MsgBox "计算机可能没有正确安装相应版本的Autocad", vbOKOnly + vbCritical
  29.                 End
  30.             End If
  31.         End If
  32.     #ElseIf cadVer = "R18" Then
  33.         '    '----------------------------------------------------
  34.         '----------------------------------
  35.         '''''    R18(autocad2010~2012)
  36.         Set objCad = GetObject(, "Autocad.Application.18")
  37.         If Err Then
  38.             Err.Clear
  39.             Set objCad = CreateObject("Autocad.Application.18")
  40.             objCad.Visible = True
  41.             If Err Then
  42.                 MsgBox "计算机可能没有正确安装相应版本的Autocad", vbOKOnly + vbCritical
  43.                 End
  44.             End If
  45.         End If
  46.         '''    '----------------------------------------------------
  47.         '----------------------------------------------------
  48.     #ElseIf cadVer = "R19" Then
  49.         'R19(autocad2013~2014)
  50.         Set objCad = GetObject(, "Autocad.Application.19")
  51.         If Err Then
  52.             Err.Clear
  53.             Set objCad = CreateObject("Autocad.Application.19")
  54.             objCad.Visible = True
  55.             If Err Then
  56.                 MsgBox "计算机可能没有正确安装相应版本的Autocad", vbOKOnly + vbCritical
  57.                 End
  58.             End If
  59.         End If
  60.         '''''''''''''''''''''''''''''''''''''''''''
  61.     #ElseIf cadVer = "R20" Then
  62.         '    'R20(autocad2015~2015)
  63.         Set objCad = GetObject(, "Autocad.Application.20")
  64.         If Err Then
  65.             Err.Clear
  66.             Set objCad = CreateObject("Autocad.Application.20")
  67.             objCad.Visible = True
  68.             If Err Then
  69.                 MsgBox "计算机可能没有正确安装相应版本的Autocad", vbOKOnly + vbCritical
  70.                 End
  71.             End If
  72.         End If
  73.         ''
  74.         '----------------------------------------------------
  75.     #Else
  76.         '    '----------------------------------
  77.         '通用代码
  78.         Set objCad = GetObject(, "Autocad.Application")
  79.         If Err Then
  80.             Err.Clear
  81.             Set objCad = CreateObject("Autocad.Application")
  82.             objCad.Visible = True
  83.             If Err Then
  84.                 MsgBox "计算机可能没有正确安装相应版本的Autocad", vbOKOnly + vbCritical
  85.                 End
  86.             End If
  87.         End If
  88.         '----------------------------------------------------
  89.     #End If
  90.         
  91.     AppActivate objCad.Caption
  92.   
  93. End Sub

(3)在 form1中输入以下代码:
  1. Private Sub Form_Load()
  2. ConnectAutoCAD
  3. End Sub

按F5运行程序,一阵等待后,你会发现Autocad展现在你面前
回复

使用道具 举报

23

主题

561

帖子

13

银币

中流砥柱

Rank: 25

铜币
653
发表于 2014-10-25 22:57:00 | 显示全部楼层

2、坐标标注
坐标标注本身很简单,类似的工具满天飞,我这里也贴一个

q0ymr3xiobh.gif

q0ymr3xiobh.gif


  1. Public Sub SeriesCoordinate()                                                   '连续标坐标
  2.     Dim blnExitSeriesCoord As Boolean
  3.     ' InitCommonVar
  4.     '全局变量
  5.     Coordinate_TextHeight = 3
  6.     ratio = 1
  7.     TextRowSpace = 0.6
  8.     Do
  9.         Coordinate blnExitSeriesCoord '本子过程源码需要回复才能看到
  10.     Loop Until blnExitSeriesCoord
  11. End Sub
  1.     On Error GoTo err1
  2.     '    Dim Coordinate_TextHeight As Double '文字高
  3.     '    Dim Ratio As Double '全局比例
  4.     '    Dim TextRowSpace As Double '文字行间距
  5.     '    Coordinate_TextHeight = 3
  6.     '    Ratio = 1
  7.     '    TextRowSpace = 0.6
  8.     Dim p1, p2                                                                  '标注点坐标,标注文字位置
  9.     p1 = ThisDrawing.Utility.GetPoint(, "请点击要标注的点(按回车键退出):")
  10.     p2 = ThisDrawing.Utility.GetPoint(p1, "请点击标注位置(按回车键退出):")
  11.     Dim T1   As AcadText, T2 As AcadText
  12.     Dim strT As String, intStrL1 As Integer, intStrL2 As Integer                'Y和X坐标文字的长度
  13.     strT = "X " & Format$(p1(1), "0.000")
  14.     intStrL1 = Len(strT)
  15.     Dim pt1(2) As Double, pt2(2) As Double                                      '文字坐标
  16.     If p2(0) > p1(0) Then                                                       '确定标注点与标注文字位置的左右关系,以确定文字插入点
  17.         pt1(0) = p2(0)
  18.         pt1(1) = p2(1) + TextRowSpace / 2 * Coordinate_TextHeight * ratio
  19.     Else
  20.         pt1(0) = p2(0) - intStrL1 * Coordinate_TextHeight * ratio * _
  21.         ThisDrawing.ActiveTextStyle.Width ^ 2                                   '宽度比例(总是宽度比例的平方,因为当前文字样式设了宽度,而AcadText本身又有个ScaleFactor,而且等于width)
  22.         pt1(1) = p2(1) + TextRowSpace / 2 * Coordinate_TextHeight * ratio
  23.     End If
  24.     Set T1 = ThisDrawing.ModelSpace.AddText(strT, pt1, Coordinate_TextHeight * ratio)
  25.     T1.Visible = False
  26.     strT = "Y " & Format$(p1(0), "0.000")
  27.     intStrL2 = Len(strT)
  28.     pt2(0) = pt1(0)
  29.     pt2(1) = pt1(1) - T1.Height * (1 + TextRowSpace)                            'TextRowSpace代表文字间距是TextRowSpace倍的字高
  30.     Set T2 = ThisDrawing.ModelSpace.AddText(strT, pt2, Coordinate_TextHeight * ratio)
  31.     T2.Visible = False
  32.     Dim Pend(2) As Double                                                       '标注结束点
  33.     Pend(0) = p2(0)
  34.     Dim TminP, TmaxP
  35.     If intStrL1 > intStrL2 Then                                                 '取最长文字长度
  36.         T1.GetBoundingBox TminP, TmaxP
  37.     Else
  38.         T2.GetBoundingBox TminP, TmaxP
  39.     End If
  40.     If p2(0) > p1(0) Then                                                       '确定标注点与标注文字位置的左右关系,以确定标注结束点位置
  41.         Pend(0) = p2(0) + (TmaxP(0) - TminP(0))
  42.         Pend(1) = p2(1)
  43.     Else
  44.         Pend(0) = p2(0) - (TmaxP(0) - TminP(0))
  45.         Pend(1) = p2(1)
  46.         pt1(0) = Pend(0)
  47.         pt2(0) = Pend(0)
  48.         T1.InsertionPoint = pt1
  49.         T2.InsertionPoint = pt2
  50.     End If
  51.     T1.Visible = True
  52.     T2.Visible = True
  53.     Dim L1 As AcadLine, L2 As AcadLine
  54.     Set L1 = ThisDrawing.ModelSpace.AddLine(p1, p2)
  55.     Set L2 = ThisDrawing.ModelSpace.AddLine(p2, Pend)
  56.     Exit Sub
  57. err1:
  58.     Err.Clear
  59.     blnExitSeriesCoord = True
  60. End Sub

对于vb或vba来说,在没创建AcadText对象之前,很难精确算出AcadText对象的长度,本例子中,先大致估算,然后生成AcadText对象,但暂时隐藏它,通过GetBoundingBox 取得AcadText对象真实大小后,再调整AcadText对象位置和直线长度!
回复

使用道具 举报

13

主题

59

帖子

2

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
111
发表于 2014-10-24 18:47:00 | 显示全部楼层
顶!
楼主的免费教程,无私分享令人敬佩!
支持!!
回复

使用道具 举报

0

主题

1

帖子

1

银币

初来乍到

Rank: 1

铜币
1
发表于 2015-10-8 16:47:00 | 显示全部楼层

为什么我一编译就出错呢
回复

使用道具 举报

23

主题

561

帖子

13

银币

中流砥柱

Rank: 25

铜币
653
发表于 2014-11-22 23:09:00 | 显示全部楼层
增加一个判断点在pl曲线内侧还是外侧
回复

使用道具 举报

23

主题

561

帖子

13

银币

中流砥柱

Rank: 25

铜币
653
发表于 2014-10-18 19:21:00 | 显示全部楼层
2、Autocad对象模型
Autocad对象模型是树型结构,具体内容详见Autocad开发人员帮助或乐筑天下论坛翻译的中文版AcadAuto.chm。
Autocad对象模型中最重要的对象是AcadDocument对象,在VBA中,当前图的AcadDocument对象的对象名是ThisDrawing,这个名起的非常好,顾名而思意,在AcadAuto.chm中,所有涉及到AcadDocument对象的代码都用的是ThisDrawing.
如以下代码:
  1. Sub Example_TextString()
  2.     ' This example creates a text object in model space.
  3.     ' It then returns the text string for that object.
  4.    
  5.     Dim textObj As AcadText
  6.     Dim text As String
  7.     Dim insertionPoint(0 To 2) As Double
  8.     Dim height As Double
  9.    
  10.     ' Define the text object
  11.     text = "Hello, World."
  12.     insertionPoint(0) = 2: insertionPoint(1) = 2: insertionPoint(2) = 0
  13.     height = 0.5
  14.    
  15.     ' Create the text object in model space
  16.     Set textObj = ThisDrawing.ModelSpace.AddText(text, insertionPoint, height)
  17.     ZoomAll
  18.    
  19.     ' Return the current text string for the object
  20.     text = textObj.textString
  21.     MsgBox "The TextString property equals: " & text, vbInformation, "TextString 示例"
  22.       
  23. End Sub

而在VB6中,即使你引用Autocad对象,也没有ThisDrawing这个对象,如果用vb6测试VBA代码时,就会很麻烦。因此,需要你在ModCommon.bas中增加函数。
  1. Public Function ThisDrawing() As AcadDocument
  2.     If Not (objCad Is Nothing) Then Set ThisDrawing = objCad.ActiveDocument
  3. End Function

有了上面代码,你就可以轻松测试大部分VBA代码了。
*请你想想,为什么不把ThisDrawing定义成一个AcadDocument类型的变量,而是要定义成返回AcadDocument类型的函数呢?
回复

使用道具 举报

23

主题

561

帖子

13

银币

中流砥柱

Rank: 25

铜币
653
发表于 2014-10-19 22:54:00 | 显示全部楼层

用VB6进行Autocad的二次开发的基本环境已经搭建完成,接下来牛刀小试了!
首先我们征对单行文字进行各种操作。
1、增量复制
功能,请看gif演示

zbuibe1s54o.gif

zbuibe1s54o.gif

分析:实现该功能分解步骤:
(1)选择单行文字
(2)输入序号的增量,即每复制一次增加几?
(3)复制基点与目标点和原文字与目标文字插入点的计算
(4)生成一个新单行文字
对于(1)选择单行文字文字来说,有多选和单选的区别,多选一般用AcadSelectionSet对象的Select****方法,而单选一般用
AcadDocumnet的Utility类的GetEntity 方法。
对于单选,本人给出一个子程序SelectSingleText。
在工程中新建一个模块,取名为ModTextTreatment.bas
添加以下代码:
  1. Private Sub SelectSingleText(returnObj As AcadText, blnESC As Boolean)
  2.     Dim basePnt As Variant
  3.     On Error Resume Next
  4. RETRY:
  5.     ThisDrawing.Utility.GetEntity returnObj, basePnt, "请选择单行文字:"
  6.    ' Debug.Print Err.Number, Err.Description
  7.     If Err.Number = -2147352567 Then
  8.         blnESC = True
  9.         Exit Sub
  10.     End If
  11.     If Err  0 Then
  12.         Err.Clear
  13.         GoTo RETRY
  14.     Else
  15.         returnObj.Highlight True
  16.      End If

子程序SelectSingleText的简要说明:
参数:returnObj 返回选择的单行文字;
blnESC是一个标记,标记用户是否选择了文字,有可能用户按ESC键取消了操作
如果用户按ESC键取消了操作,返回的错误号Err.Number = -2147352567,你猜猜我是如何知道的?
回复

使用道具 举报

23

主题

561

帖子

13

银币

中流砥柱

Rank: 25

铜币
653
发表于 2014-10-19 23:08:00 | 显示全部楼层
(2)输入序号的增量,即每复制一次增加几?
Autocad的键盘输入,大部分都可以用Utility类中的方法。这里我们用GetReal
  1.     Dim IncreaseNum As Double
  2.     IncreaseNum = ThisDrawing.Utility.GetReal("请输入增加量(可以为负,默认为1):")

本来这样就可以了,但是,“默认为1”,就是用户懒得输入,或,最常用到的情况,直接按回车或空格键就代替用户输入,这样是会出错的,因为getReal不支持输入空内容。因此,又用到错误处理(关于vb的内容,这里不讲)
  1.    On Error GoTo Err2
  2.      Dim IncreaseNum As Double
  3.      IncreaseNum = ThisDrawing.Utility.GetReal("请输入增加量(可以为负,默认为1):")
  4.     If IncreaseNum = 0 Then IncreaseNum = 1
  5.     Err2:
  6.     Err.Clear
  7.     Resume Next
  8.    
回复

使用道具 举报

23

主题

561

帖子

13

银币

中流砥柱

Rank: 25

铜币
653
发表于 2014-10-19 23:13:00 | 显示全部楼层

(3)复制基点与目标点和原文字与目标文字插入点的计算
这个就不详细说了,一些简单的计算
(4)生成一个新单行文字
这里用的AcadText对象的copy +move方法
以下为增量复制的完整代码
  1.    
  2. Public Sub CopyTextIncrement()                                                  '增量复制
  3.     Dim objText As AcadText, blnESC As Boolean
  4.    
  5.     SelectSingleText objText, blnESC
  6.    
  7.     If blnESC Then Exit Sub
  8.    
  9.     On Error GoTo Err2
  10.    
  11.     Dim IncreaseNum As Double
  12.    
  13.     IncreaseNum = ThisDrawing.Utility.GetReal("请输入增加量(可以为负,默认为1):")
  14.    
  15.     If IncreaseNum = 0 Then IncreaseNum = 1
  16.    
  17.     On Error GoTo err1
  18.    
  19.     Dim copyObj As AcadText, pt1, pt2
  20.    
  21.     Dim dx As Double, dy As Double, InsPt(2) As Double
  22.    
  23.     pt1 = ThisDrawing.Utility.GetPoint(, "请指定复制基点:")
  24.     dx = pt1(0) - objText.InsertionPoint(0)
  25.     dy = pt1(1) - objText.InsertionPoint(1)
  26.    
  27.     Do
  28.         InsPt(0) = objText.InsertionPoint(0) + dx
  29.         InsPt(1) = objText.InsertionPoint(1) + dy
  30.         pt2 = ThisDrawing.Utility.GetPoint(InsPt, "请指定复制到点:")
  31.         Set copyObj = objText.Copy()
  32.         
  33.         Dim strText As String, iPos As Integer, iDotPos As Integer, strFormat As String
  34.         
  35.         strText = RTrim(objText.TextString)
  36.         iPos = Len(strText)
  37.         
  38.         Do While IsNumeric(Mid(strText, iPos))
  39.             iPos = iPos - 1
  40.             
  41.             If iPos = 0 Then Exit Do
  42.         Loop
  43.         
  44.         If iPos = Len(strText) Then
  45.             strText = strText & CStr(IncreaseNum)
  46.         Else
  47.             iDotPos = InStr(iPos + 1, strText, ".", vbTextCompare)              '取小数点位置
  48.             
  49.             If iDotPos  0 Then
  50.                 strFormat = "#." & String(Len(strText) - iDotPos, "0")
  51.                 strText = Mid(strText, 1, iPos) & Format(Val((Mid(strText, iPos + 1)) + _
  52.                 IncreaseNum), strFormat)
  53.             Else
  54.                 strText = Mid(strText, 1, iPos) & CStr(Val((Mid(strText, iPos + 1)) + _
  55.                 IncreaseNum))
  56.             End If
  57.         End If
  58.         
  59.         copyObj.TextString = strText
  60.         copyObj.Move InsPt, pt2
  61.         objText.Highlight False
  62.         Set objText = copyObj
  63.         objText.Highlight True
  64.     Loop
  65.    
  66.     Exit Sub
  67.    
  68. err1:
  69.     Err.Clear
  70.     objText.Highlight False
  71.     Debug.Print Err.Description
  72.    
  73.     Exit Sub
  74.    
  75. Err2:
  76.     Err.Clear
  77.    
  78.     Resume Next
  79.    
  80. End Sub
回复

使用道具 举报

1

主题

7

帖子

3

银币

初来乍到

Rank: 1

铜币
11
发表于 2014-10-20 18:44:00 | 显示全部楼层
你的排图框的源码呢,
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

  • 微信公众平台

  • 扫描访问手机版

  • 点击图片下载手机App

QQ|关于我们|小黑屋|乐筑天下 繁体中文

GMT+8, 2024-11-22 00:01 , Processed in 0.285093 second(s), 75 queries .

© 2020-2024 乐筑天下

联系客服 关注微信 帮助中心 下载APP 返回顶部 返回列表