找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 1051|回复: 13

[讨论]:关于实现标注的问题

[复制链接]
发表于 2003-6-3 12:37:36 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
大家好,我有个想法,就是当选择标注进行标注后,跟着直接新建一个标注的层。
我用vba写了这个程序,但运行后达不到象cad里那样的标注效果,就是在确定尺寸界线的长度时并不能实现象cad里那样尺寸线和标注文字随着光标移动。请大家帮助解决这个问题,程序如下:
Sub dli()
Dim dli As AcadDimAligned
Dim pt1 As Variant
Dim pt2 As Variant
Dim pt3 As Variant
pt1 = ThisDrawing.Utility.GetPoint(, "startpt")
pt2 = ThisDrawing.Utility.GetPoint(pt1, "endpt")
pt3 = ThisDrawing.Utility.GetPoint(pt2, "textpt")
Set dli = ThisDrawing.ModelSpace.AddDimAligned(pt1, pt2, pt3)
Dim layer1 As AcadLayer
Set layer1 = ThisDrawing.Layers.Add("标注")
layer1.Color = acGreen
dli.Layer = "标注"
End Sub
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

已领礼包: 181个

财富等级: 日进斗金

发表于 2003-6-3 12:58:45 | 显示全部楼层
如果不调用CAD的内部命令,那就只能使用第三方的程序,或者自己使用系统的API来控制。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2003-6-3 13:14:34 | 显示全部楼层
我是在学这方面的问题,如果调用cad的命令,请问具体怎样操作。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 181个

财富等级: 日进斗金

发表于 2003-6-3 13:17:25 | 显示全部楼层
以下是我尝试的,将鼠标依次定位到直线的两个端点,由于像素是整数,因而会形成误差。


  1.   [FONT=courier new]
  2. '将像素转换成ACAD的当前图形单位。
  3. Function PixelsToAcadUnit(ByVal Pixels As Integer) As Double
  4.     Dim ViewSize As Double
  5.     ViewSize = acadDoc.GetVariable("VIEWSIZE")
  6.     Dim ScreenSize As Variant
  7.     ScreenSize = acadDoc.GetVariable("SCREENSIZE")
  8.     PixelsToAcadUnit = Pixels * ViewSize / ScreenSize(1)
  9. End Function

  10. '将ACAD的当前图形单位转换成像素。
  11. Function AcadUnitToPixels(ByVal AcadUnit As Double) As Double
  12.     Dim ViewSize As Double
  13.     ViewSize = acadDoc.GetVariable("VIEWSIZE")
  14.     Dim ScreenSize As Variant
  15.     ScreenSize = acadDoc.GetVariable("SCREENSIZE")
  16.     AcadUnitToPixels = AcadUnit * ScreenSize(1) / ViewSize
  17. End Function

  18. '将ACAD中的某一点坐标转换到屏幕上的某一像素位置。
  19. Private Function AcadCoordToPixels(ByVal AcadCoord As Variant) As POINTAPI
  20.     Dim ViewCtr As Variant
  21.     ViewCtr = acadDoc.GetVariable("VIEWCTR")
  22.     Dim ScreenSize As Variant
  23.     ScreenSize = acadDoc.GetVariable("SCREENSIZE")
  24.     Dim p As POINTAPI
  25.     Debug.Print AcadUnitToPixels(AcadCoord(0) - ViewCtr(0))
  26.     p.X = Round(ScreenSize(0) / 2 + AcadUnitToPixels(AcadCoord(0) - ViewCtr(0)), 0)
  27.     p.Y = Round(ScreenSize(1) / 2 - AcadUnitToPixels(AcadCoord(1) - ViewCtr(1)), 0)
  28.     Dim lRet As Long
  29.     lRet = ClientToScreen(acadDoc.hWnd, p)
  30.     AcadCoordToPixels = p
  31. End Function



  32. Option Explicit
  33. Private Type POINTAPI
  34.     X As Long
  35.     Y As Long
  36. End Type
  37. Private Declare Function SetCursorPos Lib "user32" (ByVal X As Long, ByVal Y As Long) As Long
  38. Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
  39. Private Declare Function ClientToScreen Lib "user32" (ByVal hWnd As Long, lpPoint As POINTAPI) As Long

  40. Dim acadApp As AcadApplication
  41. Dim acadDoc As AcadDocument

  42. Sub test()
  43.     Set acadApp = GetObject(, "AutoCAD.Application")
  44.     acadApp.Visible = True
  45.     Set acadDoc = acadApp.ActiveDocument
  46.     AppActivate acadApp.Caption
  47.     Dim p1 As POINTAPI
  48.     p1 = AcadCoordToPixels(acadDoc.ModelSpace(0).StartPoint)
  49.     Dim p2 As POINTAPI
  50.     p2 = AcadCoordToPixels(acadDoc.ModelSpace(0).EndPoint)
  51.     Sleep 1000
  52.     SetCursorPos p1.X, p1.Y
  53.     Sleep 1000
  54.     SetCursorPos p2.X, p2.Y
  55. End Sub

  56.   [/FONT]
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2003-6-3 13:24:52 | 显示全部楼层
是在vb下编写的吧,好象很烦琐啊,能不能象你所说的调用cad内部的命令,然后用程序得到最后的标注对象,然后给它指定层呢。那怎样给参数赋值呢?
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 181个

财富等级: 日进斗金

发表于 2003-6-3 13:48:02 | 显示全部楼层
首先保存模型空间中的实体数目,接着使用SendCommand,发送"_dimaligned"命令,调用对齐标注命令,等运行完之后,再检查模型空间中的实体数目,如果是上一次的值加1,表示操作成功,那么引用最后一个实体,修改它的层属性和颜色属性。
如:



  1.   [FONT=courier new]
  2. Sub test()
  3.     Dim n As Integer
  4.     n = ThisDrawing.ModelSpace.Count
  5.     ThisDrawing.SendCommand "_dimaligned" & vbCr
  6.     If ThisDrawing.ModelSpace.Count = n + 1 Then
  7.         ThisDrawing.ModelSpace(n).Layer = "标注"
  8.         ThisDrawing.ModelSpace(n).Color = acGreen
  9.     End If
  10. End Sub[/FONT]
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2003-6-3 20:37:29 | 显示全部楼层
调试了一下,好象没任何反映,是不是程序执行完ThisDrawing.SendCommand "_dimaligned" & vbCr就退出了啊,真的搞不懂,我改了以下也是不行,只能是下次执行时才能把上次标注的对象转到标注层上去。程序如下:
Sub a()
Dim layer1 As AcadLayer
Set layer1 = ThisDrawing.Layers.add("标注")
layer1.Color = acGreen
Dim n As Integer
ThisDrawing.SendCommand "_dimaligned" & vbCr
For Each ent In ThisDrawing.ModelSpace
If TypeOf ent Is AcadDimAligned Then
  ent.Layer = "标注"
    End If
     Next
                       
End Sub
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 181个

财富等级: 日进斗金

发表于 2003-6-3 23:13:26 | 显示全部楼层
查出原因了,是因为调用CAD的内部命令时是异步调用,即只是发送一个消息,而不会等候命令执行完再继续执行下一个语句,造成了标注还没完成,而语句就已经执行结束了。
只好改用事件来拭操作了,在开始命令和结束命令中操作。如下:

  1.   [FONT=courier new]
  2. Option Explicit

  3. Dim n As Integer

  4. Sub test()
  5.     ThisDrawing.SendCommand "_dimaligned" & vbCr
  6. End Sub

  7. Private Sub AcadDocument_BeginCommand(ByVal CommandName As String)
  8.     If CommandName = "DIMALIGNED" Then
  9.         n = ThisDrawing.ModelSpace.Count
  10.     End If
  11. End Sub

  12. Private Sub AcadDocument_EndCommand(ByVal CommandName As String)
  13.     If CommandName = "DIMALIGNED" Then
  14.         If ThisDrawing.ModelSpace.Count = n + 1 Then
  15.             ThisDrawing.ModelSpace(n).Layer = "标注"
  16.             ThisDrawing.ModelSpace(n).Color = acGreen
  17.         End If
  18.     End If
  19. End Sub
  20.   [/FONT]
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2003-6-4 12:25:37 | 显示全部楼层
实现DIMENSION自动另居一层的一种方法。
在命令发送前对命令进行判断,如果含有“DIM”字样则改变ACTIVELAYER为DIM层,命令后再返回原层。
以下代码加入ThisDrawing

  1.   [FONT=courier new]
  2. Dim X1 As Class1
  3. Sub StartDimensionMode()
  4.     Set X1 = New Class1
  5. End Sub
  6. Sub EndDimensionMode()
  7.     Set X1 = Nothing
  8. End Sub

  9.   [/FONT]


新建CLASS MODULE--CLASS1
加入如下代码

  1.   [FONT=courier new]
  2. Public WithEvents App As AcadApplication
  3. Dim curLayer As AcadLayer
  4. Dim dimCommand As Boolean
  5. Private Sub App_BeginCommand(ByVal CommandName As String)
  6.     On Error Resume Next
  7.     If InStr(UCase(CommandName), "DIM") Then
  8.         Set curLayer = ActiveDocument.ActiveLayer
  9.         ActiveDocument.ActiveLayer = getDimLayer
  10.         dimCommand = True
  11.     End If
  12. End Sub

  13. Private Sub App_EndCommand(ByVal CommandName As String)
  14.     On Error GoTo errhandle
  15.     If dimCommand Then
  16.         ActiveDocument.ActiveLayer = curLayer
  17.         dimCommand = False
  18.     End If
  19.     Exit Sub
  20. errhandle:
  21.     ActiveDocument.ActiveLayer = ActiveDocument.Layers(0)
  22.     dimCommand = False
  23. End Sub

  24. Private Sub App_SysVarChanged(ByVal SysvarName As String, ByVal newVal As Variant)
  25.    
  26. End Sub

  27. Private Sub Class_Initialize()
  28.     Set App = AcadApplication
  29. End Sub
  30. Function getDimLayer() As AcadLayer
  31.     Dim tLayer As AcadLayer
  32.     Dim color As AcadAcCmColor
  33.     Set color = AcadApplication.GetInterfaceObject("AutoCAD.AcCmColor.16")
  34.     Call color.SetRGB(255, 0, 0)
  35.      For Each tLayer In App.ActiveDocument.Layers
  36.         If tLayer.Name = "DIMLayer" Then
  37.             Set getDimLayer = tLayer
  38.             Exit Function
  39.         End If
  40.     Next
  41.     Set tLayer = App.ActiveDocument.Layers.Add("DIMLayer")
  42.     tLayer.TrueColor = color
  43.     Set getDimLayer = tLayer
  44.    
  45. End Function

  46.   [/FONT]
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2003-6-4 12:33:12 | 显示全部楼层
ok了,太感谢了,其实最重要的是通过这个例子使我明白事件操作的编程方法,这样的话,如果根据自己的实际需要,就可以把很多cad命令来进行扩充了。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 181个

财富等级: 日进斗金

发表于 2003-6-4 12:56:53 | 显示全部楼层
最初由 Laoyao 发布
[B]实现DIMENSION自动另居一层的一种方法。
在命令发送前对命令进行判断,如果含有“DIM”字样则改变ACTIVELAYER为DIM层,命令后再返回原层。
以下代码加入ThisDrawing
[CODE]
  
Dim X1 As Cla... [/B]


演示了类以及事件的使用,同时能够对R2004的真彩色功能进行应用,可供大家参考,欢迎能够常来。

在R2004中,每一个实体都可以使用真彩色的功能,它将原来的Color属性(整型)变更为TrueColor属性(Color对象)。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2003-6-4 13:05:06 | 显示全部楼层
因为不会对DIMENSION OBJECT使用WITHEVENTS,所以只能在APPLICATION中判断。
请问版主,如何对DIMENSION OBJECT使用WITHEVENTS
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 181个

财富等级: 日进斗金

发表于 2003-6-4 13:31:00 | 显示全部楼层
关于对象的事件有两种,一种是文档中的事件,它提供了当对象增加、修改和删除时触发的事件。另一种是对象本身的修改事件,它是对象创建之后进行修改时触发的事件。
对于上面的问题,应该使用文档级的事件,在事件触发的过程当中首先,判断对象的类型,如果是标注对象,那么就进行相关的操作,否则略过。这个事件其实是图形数据库变更的触发事件,因而对象的类型就比较多,比如在VBA中平常所没有的块表对象、层表对象、块表记录对象等,如果熟悉ARX的话,理解它的原因就比较简单。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2006-7-4 18:42:56 | 显示全部楼层
'将像素转换成ACAD的当前图形单位。
Function PixelsToAcadUnit(ByVal Pixels As Integer) As Double
    Dim ViewSize As Double
    ViewSize = acadDoc.GetVariable("VIEWSIZE")
    Dim ScreenSize As Variant
    ScreenSize = acadDoc.GetVariable("SCREENSIZE")
    PixelsToAcadUnit = Pixels * ViewSize / ScreenSize(1)
End Function
哪位能给解释以下 SCREENSIZE  和 VIEWSIZE的意思和关系
想解决一个问题:目前的视口大小表示多少实际尺寸
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

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

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-11-22 15:07 , Processed in 0.388963 second(s), 58 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表