cad.net 以激活形式在前台打開cad文檔


委托的學習一文中,提供了一個函數用於輸入路徑獲取數據庫,

而本文提供的是以激活形式打開cad文檔,也就是和用戶拖動dwg到cad打開一樣.

需要對鎖文檔的有所理解.

容易發生的坑是:不能使用doc.Dispose();

因為我十分喜歡手動釋放圖元和記錄,因為曾經發生過不釋放就出錯的問題.....

尤其是遍歷全圖的時候,必須手動釋放,不然某些實體沒有釋放就會引起錯誤..(可能由於我使用的是Acad2008)

尼克勞斯的這篇博文里也有說過,不手動釋放面域,也會引起錯誤...


#if !HC2020
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.PlottingServices;
using Autodesk.AutoCAD.Geometry;
using PlotType = Autodesk.AutoCAD.DatabaseServices.PlotType;
using Acap = Autodesk.AutoCAD.ApplicationServices.Application;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Runtime;
#else
using GrxCAD.DatabaseServices;
using GrxCAD.EditorInput;
using GrxCAD.Geometry;
using GrxCAD.ApplicationServices;
using GrxCAD.Runtime;
using GrxCAD.Colors;
using GrxCAD.GraphicsInterface;
using Acap = GrxCAD.ApplicationServices.Application; 
using PlotType = GrxCAD.DatabaseServices.PlotType;
using GrxCAD.PlottingServices; 
#endif

using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Windows.Forms;
using System.Collections.Specialized;

using JoinBox;
using System;
using System.IO;
namespace JoinBox.JoinBox_Code.Winform.批量打印
{
    public class OpreateCad
    {
        [CommandMethod("tete", CommandFlags.Session)]
        public void tete()
        {
            var paths = new List<string>();
            string dwgPath = AutoGo.DwgCurrentPath();
            var ofd = new OpenFileDialog
            {
                AutoUpgradeEnabled = false,//OpenFileDialog會卡頓,用這個就好了
                Filter = "AutoCAD 圖形(*.dwg)|*.dwg",
                Multiselect = true,//允許同時選擇多個文件  
                InitialDirectory = dwgPath,
            };
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                paths.AddRange(ofd.FileNames);
            }

            ActiveDwg(paths, (doc, layout) =>
            {
                var ed = doc.Editor;
                ed.WriteMessage(Environment.NewLine + "打印的數據庫:" + doc.Database.Filename);
                ed.WriteMessage("打印的布局:" + layout.LayoutName);
            });
        }

        /// <summary>
        /// 打開dwg,並且激活
        /// </summary>
        /// <param name="m_ps"></param>
        public static void ActiveDwg(IEnumerable<string> m_ps, Action<Document, Layout> action)
        {
            var m_printfiles = m_ps.ToList();
            for (int i = 0; i < m_printfiles.Count(); i++)
            {
                Opendwg(m_printfiles[i]);
            }

            //遍歷激活
            foreach (Document doc in Acap.DocumentManager)
            {
                if (!doc.IsActive && !doc.IsDisposed)//CommandFlags.Session則不會是IsActive的
                {
                    Acap.DocumentManager.MdiActiveDocument = doc;//切換文檔,如果切換過來之后后續代碼沒有執行了,是因為沒有CommandFlags.Session
                    var db = doc.Database;
                    using (doc.LockDocument()) //鎖定文檔,為了切換布局
                    {
                        using (Transaction tr = db.TransactionManager.StartTransaction())
                        {
                            var bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                            foreach (ObjectId btrId in bt)
                            {
                                var btr = tr.GetObject(btrId, OpenMode.ForRead) as BlockTableRecord;
                                if (!btr.IsLayout)
                                {
                                    continue;
                                }

                                var layout = tr.GetObject(btr.LayoutId, OpenMode.ForRead) as Layout;
                                if (LayoutManager.Current.CurrentLayout != layout.LayoutName)
                                {
                                    LayoutManager.Current.CurrentLayout = layout.LayoutName;//非模態這里會失敗,所以要鎖文檔    
                                }
                                action(doc, layout);//然后打印......其他操作.......
                                layout.Dispose();
                                btr.Dispose();
                            }

                            //不是必須的
                            //if (m_printfiles.Contains(doc.Name))  //這里還要判斷是不是已經保存了的
                            //{
                            //    //這里一定要保存一次,不然就會切換文檔卡死.cad08版本的時候
                            //    doc.SendStringToExecute("_qsave\n", false, true, true); //不需要切換文檔
                            //}

                            bt.Dispose();
                            tr.Commit();
                        }
                    }
                    //if (!doc.IsActive)
                    //{
                    //    doc.CloseAndDiscard();
                    //}

#if 重要解釋
                    //不可以釋放doc,因為切換會導致內存報錯問題......
                    //沒有CommandFlags.Session的話,釋放了之后 doc.IsActive == false了.
                    //doc.Dispose();
#endif
                }
            }
        }


        /// <summary>
        /// 在cad的前台打開dwg
        /// </summary>
        /// <param name="strFileName"></param> 
        public static bool Opendwg(string strFileName)
        {
            var dm = Acap.DocumentManager;
            if (File.Exists(strFileName))
            {
                try
                {
#if NET35 || NET40
                    dm.Open(strFileName, false);
#else
                
                    dm.AppContextOpenDocument(strFileName); 
#endif
                }
                catch (System.Exception e)
                {
                    dm.MdiActiveDocument.Editor.WriteMessage("此文件打開錯誤: " + strFileName + "\n\r錯誤信息:" + e.Message);
                    return false;
                }
            }
            else
            {
                dm.MdiActiveDocument.Editor.WriteMessage("此文件不存在: " + strFileName);
                return false;
            }
            return true;
        }
    }
}

(完)


免責聲明!

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



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