田草博客

互联网田草博客


网友交流QQ群:11740834 需注明申请加入原因

微信 公众号:ByCAD

邮箱:tiancao1001x126.com
ByCAD,微信公众号
首页 | 普通 | 电脑 | AutoCAD | VB/VB.NET | FLash | 结构 | 建筑 | 电影 | BIM | 规范 | 软件 | ID
-随机-|-分布-
-博客论坛-|-﨣﨤﨧﨨-
-网站导航-|-规范下载-
-BelovedFLash欣赏-

用户登陆
用户:
密码:
 

站点日历
73 2024 - 11 48
     12
3456789
10111213141516
17181920212223
24252627282930


站点统计

最新评论



统计图中中管线的总长度 AutoCAD.net 实体沿曲线轨迹移动
未知 翻译 Through the Interface 的 .NET下防止AutoCAD块被炸开   [ 日期:2010-11-03 ]   [ 来自:本站原创 ]  HTML
原文:http://through-the-interface.typepad.com/through ... /08/preventing-an-a.html
程序代码:[ 复制代码到剪贴板 ]
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.Runtime
Namespace ExplosionPrevention
    Public Class Commands
        Private _doc As Document
        Private _db As Database
        Private _blkDefs As New ObjectIdCollection()
        Private _blkRefs As New ObjectIdCollection()
        Private _blkConts As New ObjectIdCollection()
        Private _handlers As Boolean = False
        Private _exploding As Boolean = False
        <CommandMethod("STOPEX")> _
        Public Sub StopBlockFromExploding()
            _doc = Application.DocumentManager.MdiActiveDocument
            _db = _doc.Database
            If Not _handlers Then
                AddEventHandlers()
                _handlers = True
            End If
            ' Get the name of the block to protect
            Dim pso As New PromptStringOptions(vbLf & "Enter block name: ")
            pso.AllowSpaces = False
            Dim pr As PromptResult = _doc.Editor.GetString(pso)
            If pr.Status <> PromptStatus.OK Then
                Return
            End If
            Dim tr As Transaction = _db.TransactionManager.StartTransaction()
            Using tr
                ' Make sure the block definition exists
                Dim bt As BlockTable = DirectCast(tr.GetObject(_db.BlockTableId, OpenMode.ForRead), BlockTable)
                If bt.Has(pr.StringResult) Then
                    ' Collect information about the block...
                    ' 1. the block definition
                    Dim blkId As ObjectId = bt(pr.StringResult)
                    _blkDefs.Add(blkId)
                    Dim btr As BlockTableRecord = DirectCast(tr.GetObject(blkId, OpenMode.ForRead), BlockTableRecord)
                    ' 2. the block's contents
                    For Each id As ObjectId In btr
                        _blkConts.Add(id)
                    Next
                    ' 3. the block's references
                    Dim blkRefs As ObjectIdCollection = btr.GetBlockReferenceIds(True, True)
                    For Each id As ObjectId In blkRefs
                        _blkRefs.Add(id)
                    Next
                End If
                tr.Commit()
            End Using
        End Sub
        Private Sub AddEventHandlers()
            ' When a block reference is added, we need to
            ' check whether it's for a block we care about
            ' and add it to the list, if so
            AddHandler _db.ObjectAppended, AddressOf _ObjectAppended
            AddHandler _db.ObjectErased, AddressOf _ObjectErased
            AddHandler _db.BeginDeepClone, AddressOf _BeginDeepClone
            AddHandler _db.BeginDeepCloneTranslation, AddressOf _BeginDeepCloneTranslation
        End Sub

        Sub _ObjectAppended(ByVal sender As Object, ByVal e As ObjectEventArgs)
            Dim br As BlockReference = TryCast(e.DBObject, BlockReference)
            If br IsNot Nothing Then
                If _blkDefs.Contains(br.BlockTableRecord) Then
                    _blkRefs.Add(br.ObjectId)
                End If
            End If
        End Sub
        ' Conversely we need to remove block references
        ' that as they're erased
        Sub _ObjectErased(ByVal sender As Object, ByVal e As ObjectErasedEventArgs)
            ' This is called during as part of the cloning 
            ' process, so let's check that's not happening
            If Not _exploding Then
                Dim br As BlockReference = TryCast(e.DBObject, BlockReference)
                If br IsNot Nothing Then
                    ' If we're erasing, remove this block
                    ' reference from the list, otherwise if
                    ' we're unerasing we will want to add it
                    ' back in
                    If e.Erased Then
                        If _blkRefs.Contains(br.ObjectId) Then
                            _blkRefs.Remove(br.ObjectId)
                        End If
                    Else
                        If _blkDefs.Contains(br.BlockTableRecord) Then
                            _blkRefs.Add(br.ObjectId)
                        End If
                    End If
                End If
            End If
        End Sub
        ' This is where we fool AutoCAD into thinking the
        ' block contents have already been cloned
        Sub _BeginDeepClone(ByVal sender As Object, ByVal e As IdMappingEventArgs)
            ' Only for the explode context
            If e.IdMapping.DeepCloneContext <> DeepCloneType.Explode Then
                Return
            End If
            ' We add IDs to the map to stop the
            ' block contents from being cloned
            For Each id As ObjectId In _blkConts
                e.IdMapping.Add(New IdPair(id, id, True, True, True))
            Next
        End Sub
        ' And this is where we remove the mapping entries
        Sub _BeginDeepCloneTranslation(ByVal sender As Object, ByVal e As IdMappingEventArgs)
            ' Only for the explode context
            If e.IdMapping.DeepCloneContext <> DeepCloneType.Explode Then
                Return
            End If
            ' Set the flag for our CommandEnded handler
            _exploding = True
            ' Remove the entries we added on BeginDeepClone
            For Each id As ObjectId In _blkConts
                e.IdMapping.Delete(id)
            Next
        End Sub
        ' As the command ends we unerase the block references
        Sub _CommandEnded(ByVal sender As Object, ByVal e As CommandEventArgs)
            If e.GlobalCommandName = "EXPLODE" AndAlso _exploding Then
                ' By this point the block contents should not have
                ' been cloned, but the blocks have been erased
                Dim tr As Transaction = _db.TransactionManager.StartTransaction()
                Using tr
                    ' So we need to unerase each of the erased
                    ' block references
                    For Each id As ObjectId In _blkRefs
                        Dim obj As DBObject = tr.GetObject(id, OpenMode.ForRead, True)
                        ' Only unerase it if it's needed
                        If obj.IsErased Then
                            obj.UpgradeOpen()
                            obj.[Erase](False)
                        End If
                    Next
                    tr.Commit()
                End Using
                _exploding = False
            End If
        End Sub

    End Class

End Namespace


[本日志由 tiancao1001 于 2010-11-03 09:13 PM 编辑]


暂时没有评论
发表评论 - 不要忘了输入验证码哦!
作者: 用户:  密码:   注册? 验证:  防止恶意留言请输入问题答案:1*6=?  
评论:

禁止表情
禁止UBB
禁止图片
识别链接
识别关键字

字体样式 文字大小 文字颜色
插入粗体文本 插入斜体文本 插入下划线
左对齐 居中对齐 右对齐
插入超级链接 插入邮件地址 插入图像
插入 Flash 插入代码 插入引用
插入列表 插入音频文件 插入视频文件
插入缩进符合
点击下载按钮 下标 上标
水平线 简介分割标记
表  情
 
Tiancao Blog All Rights Reserved 田草博客 版权所有
Copyright ©