CAD二次开发 学习笔记(4)
CAD二次开发 学习笔记(4)
打印信息验证器的作用:
PlotInfoValidator.Validate Method
验证器在PlotInfo对象上执行布局验证、绘图设置重写和绘图设备重写。如果验证成功,则PlotInfo对象被标记为已验证,验证器将已验证的PlotSettings和已验证的PlotConfig存储在AcPlPlotInfo对象上。
验证器执行以下一致性检查:
- 验证layoutId是否为非空。
- 验证设备是否存在且不是“None”设备。
- 验证设备上是否存在媒体。(如果设备上不存在该媒体,验证器可能会尝试查找匹配的媒体或创建自定义媒体,这取决于当前媒体匹配策略。)
- 验证布局和打印设置重写是否具有相同的modelType属性。
- 如果在布局上指定了绘图样式表或在绘图设置覆盖上指定了绘图样式表,则验证绘图样式表是否存在并与绘图模式(例如,CTB/STB)兼容。
- 如果绘图区域是View,则验证该视图是否存在于绘图中。
- 如果绘图区域是Window,则验证是否指定了有效窗口。
- 如果plot区域为Layout,则验证该布局为纸张空间布局(modelType为false)。
验证器还将记录以下条件的警告。
如果介质大小没有改变,但是介质单位改变了,如果纸张的胶印和比例没有相应的改变(基于新/旧单位),如果原始布局的横向/纵向方向与验证的设置不同。
验证器在其验证算法中支持纸张匹配策略。根据策略的设置,如果布局中提供的规范论文名称或覆盖在设备上不存在,验证器可能会尝试找到匹配的纸张大小。如果匹配算法失败,验证器还有策略来创建自定义的纸张大小。如果策略允许这些行为,并且它们成功了,则更新验证过的设置,以包含正确的规范媒体名称、媒体大小和可打印边界(边距),这些可能与原始布局或任何情节设置覆盖不同。
纸张匹配策略
Autodesk.AutoCAD.PlottingServices.MatchingPolicy Enumeration
Members |
Description |
MatchDisabled = 1 禁用纸张匹配 |
Media matching is disabled. |
MatchEnabled = 2 启用纸张匹配 |
Media matching is enabled. |
MatchEnabledCustom = 3 启用媒体匹配。如果没有找到匹配的媒体,则创建自定义大小并保存到磁盘。 |
Media matching is enabled. If no matching media is found, a custom size is created and saved to disk. |
MatchEnabledTemporaryCustom = 4 启用媒体匹配。如果没有找到匹配的媒体,则创建一个自定义大小并保存在临时PC3/PMP文件中,在销毁有效的PlotInfo对象时删除该文件。 |
Media matching is enabled. If no matching media is found, a custom size is created and saved in a temporary PC3/PMP file, which is deleted when the validated PlotInfo object is destroyed. |
纸张匹配计算公式
返回当前纸张匹配阈值,该阈值是匹配媒体大小时允许的最大错误值总和。
媒体匹配策略试图通过将所需的媒体大小和其他媒体属性(在布局或覆盖中指定)与指定设备可用的纸张大小进行比较来匹配纸张大小。这些属性的差异乘以权重因子,然后将差异加起来。
如果差异之和超过给定纸张实例的阈值,则不认为它是匹配的;否则,它被认为是匹配的。
可以用以下公式表示:
Match_Value =
(纸张边界差异*纸张边界权重)+
(可打印区域差异*可打印区域的权重)+
(尺寸差异*尺寸权重)+
(纸张组类型差异*纸张组权重)
对于任何给定的纸张,如果Match_Value小于计算匹配阈值,纸张匹配成功。
PlotEngine注意事项:
- 通过PlotFactory创建;
- 同一时刻只能存在一个PlotEngine实例;
- PlotEngine实例用完后要及时销毁Destroy;
PlotEngine的成对方法,
- 必须成对使用;
- 必须正确嵌套,否则会报错;
- 不同的嵌套层级,对应不同的状态;
PlotEngine Class
这个. net类包装了AcPlPlotEngine ObjectARX类。应用程序使用plotengine接口将一个或多个文档绘制到设备或文件中,为背景绘图收集绘图信息,或预览单个页面的绘图。引擎实例由PlotFactory类的方法返回。一次只能存在一个引擎对象,因此应用程序应该在需要引擎实例之前创建它们,对它们进行操作,并在不再需要它们时销毁它们(通过调用destroy())。引擎有状态的概念,它们通过嵌套的开始和结束调用在状态之间移动。
状态级别如下:无状态 (初始化) →打印状态→文件状态→页面状态→绘图状态;
例如,应用程序通过调用BeginPlot()从默认状态移动到绘图状态,并通过调用EndPlot()退出绘图状态。这些成对的方法必须正确嵌套。例如,如果当前状态为document时调用EndPlot()将返回一个错误。一个打印可以包含多个文档(BeginDocument()/EndDocument()对),一个文档可以包含多个页面(BeginPage()/EndPage()对),只要这些页面是文档兼容的。在绘制特定页面(布局)之前,布局必须是AutoCAD编辑器中的当前布局,如果是图纸空间布局,则图纸空间视口必须是活动视口。如果打印引擎用于预览,那么每个打印只能调用一个文档和页面。如果打印引擎用于将背景打印打包到文件中,那么每个打印应该只调用一个文档。
打印相关类图
选择多选线PolyLine对象,并改变其线宽
public static double width = 0; ObjectId objectId; /// <summary> /// 选择多选线PolyLine对象,并改变其线宽 /// </summary> [CommandMethod("ChangePolyLine")] public void ChangeLine() { Database db = HostApplicationServices.WorkingDatabase; Editor ed = Application.DocumentManager.MdiActiveDocument.Editor; PromptEntityResult result = ed.GetEntity("选择一个对象"); if (result.Status != PromptStatus.OK) return; objectId = result.ObjectId; ed.WriteMessage($"\n 当前对象objectId为 {objectId}"); using (Transaction tr = db.TransactionManager.StartTransaction()) { Polyline polyline = tr.GetObject(result.ObjectId, OpenMode.ForRead) as Polyline; if (polyline == null) return; FormChangeLine form = new FormChangeLine(); form.Visible = true; width = polyline.ConstantWidth; form.textBox1.Text = width.ToString(); ed.WriteMessage($"\n 当前对象线宽为 {width}"); tr.Dispose(); } db.Dispose(); } [CommandMethod("CommitChange")] public void CommitChange() { Editor ed = Application.DocumentManager.MdiActiveDocument.Editor; Database db = HostApplicationServices.WorkingDatabase; using (Transaction tr = db.TransactionManager.StartTransaction()) { Polyline polyline = tr.GetObject(objectId, OpenMode.ForWrite) as Polyline; polyline.ConstantWidth = width; tr.Commit(); } ed.WriteMessage($"\n\n 当前对象objectId为 {objectId}"); ed.WriteMessage($"\n 修改成功 width:{width}"); db.Dispose(); }
double width = 0; private void buttonEnlarge_Click(object sender, EventArgs e) { width = double.Parse(textBox1.Text); width++; textBox1.Text = width.ToString(); PlotTest0427.width = width; } private void buttonReduce_Click(object sender, EventArgs e) { width = double.Parse(textBox1.Text); if (width > 1) width--; textBox1.Text = width.ToString(); PlotTest0427.width = width; } private void buttonOK_Click(object sender, EventArgs e) { Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; doc.SendStringToExecute("CommitChange\n", true, false, false); this.Close(); } private void FormChangeLine_Load(object sender, EventArgs e) { } private void textBox1_TextChanged(object sender, EventArgs e) { PlotTest0427.width = double.Parse(textBox1.Text); }
运行结果
检测文本元素,并订正其格式
/// <summary> /// 检测文档中的文本元素,并将其修正为指定格式(字高、颜色等) /// </summary> [CommandMethod("textTest1")] public void TextTest1() { Editor ed = Application.DocumentManager.MdiActiveDocument.Editor; Database db = HostApplicationServices.WorkingDatabase; using (Transaction tr= db.TransactionManager .StartTransaction()) { BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable; BlockTableRecord btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; int i = 1,count=0,count2=0; foreach (ObjectId item in btr) { //单行文本检测 DBText dBText = tr.GetObject(item, OpenMode.ForWrite) as DBText; if (dBText!=null) { dBText.Height = 200; dBText.ColorIndex = 1; dBText.Rotation = 0; count++; } //多行文本检测 MText mText=tr.GetObject(item, OpenMode.ForWrite) as MText; if (mText != null) { mText.Height = 300; mText.ColorIndex = 2; mText.Rotation = 3.14 / 6; count2++; } ed.WriteMessage($"\n 第 {i} 个元素,ID是 {item} ,是否是单行文本? {dBText != null}"); i++; } ed.WriteMessage($"\n\n 模型空间共有 {i} 个对象,其中单行文本 {count} 个,多行文本 {count2} 个"); tr.Commit(); } }
运行前
运行后-统一订正格式后
---------------------------------分隔线------------------------------------
扩展图纸打印测试(A1加长图纸打印)
//激活打印窗口 FormPlot formPlot; [CommandMethod("PlotForm")] public void PlotForm() { formPlot = new FormPlot(); formPlot.Visible = true; } [CommandMethod("plotExtendTest")] public void plotExtendTest() { string deviceName = formPlot.deviceName; string mediaName = formPlot.mediaName; string path = formPlot.path; PlotMethod(deviceName, mediaName, path); }
public void PlotMethod(string deviceName, string mediaName, string targetPath) { if (Math.Abs(formPlot.p1.X- formPlot.p2.X) <0.0001 || Math.Abs(formPlot.p1.Y - formPlot.p2.Y) < 0.0001) { Application.ShowAlertDialog("打印区域为空!"); return; } Extents2d extents = new Extents2d( Math.Min(formPlot.p1.X, formPlot.p2.X), Math.Min(formPlot.p1.Y, formPlot.p2.Y), Math.Max(formPlot.p1.X, formPlot.p2.X), Math.Max(formPlot.p1.Y, formPlot.p2.Y) ); Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; //前台打印 Application.SetSystemVariable("BACKGROUNDPLOT", 0); using (Transaction tr = db.TransactionManager.StartTransaction()) { //获取当前布局管理器Layout Manager LayoutManager manager = LayoutManager.Current; //从布局管理器LayoutManager获取布局 Layout layout = tr.GetObject(manager.GetLayoutId(manager.CurrentLayout), OpenMode.ForRead) as Layout; //从Layout获取PlotInfo PlotInfo info = new PlotInfo(); info.Layout = layout.ObjectId; //复制Layout中的PlotSettings PlotSettings settings = new PlotSettings(layout.ModelType); settings.CopyFrom(layout); //获取当前设置检验器,PlotSettingsValidator PlotSettingsValidator settingsValidator = PlotSettingsValidator.Current; //设置打印区域SetPlotType settingsValidator.SetPlotType(settings, Autodesk.AutoCAD.DatabaseServices.PlotType.Window); settingsValidator.SetPlotWindowArea(settings, extents); //设置缩放比例 settingsValidator.SetUseStandardScale(settings, true); settingsValidator.SetStdScaleType(settings, StdScaleType.ScaleToFit); ////设置旋转角度 settingsValidator.SetPlotRotation(settings, PlotRotation.Degrees000); //设置居中打印 settingsValidator.SetPlotCentered(settings, true); //设置打印设备名称PlotConfigurationName settingsValidator.SetPlotConfigurationName(settings, deviceName, mediaName); //用上述设置信息 覆盖Plot Info //不会将修改保存到布局Layout info.OverrideSettings = settings; //验证打印信息PlotInfo PlotInfoValidator infoValidator = new PlotInfoValidator(); infoValidator.MediaMatchingPolicy = MatchingPolicy.MatchEnabled; infoValidator.Validate(info); //检查当前是否有打印任务正在执行 if (PlotFactory.ProcessPlotState == ProcessPlotState.NotPlotting) { //使用打印对话框PlotProgressDialog显示打印状态 using (PlotEngine engine = PlotFactory.CreatePublishEngine()) { PlotProgressDialog dialog = new PlotProgressDialog(false, 1, true); using (dialog) { //定义打印开始时的显示信息 dialog.set_PlotMsgString(PlotMessageIndex.DialogTitle, "打印进度"); dialog.set_PlotMsgString(PlotMessageIndex.CancelJobButtonMessage, "取消任务"); dialog.set_PlotMsgString(PlotMessageIndex.CancelSheetButtonMessage, "CancelSheet"); dialog.set_PlotMsgString(PlotMessageIndex.SheetSetProgressCaption, "SheetSetProgress"); dialog.set_PlotMsgString(PlotMessageIndex.SheetProgressCaption, "SheetProgress"); //设置打印进度条的范围和起始位置 dialog.LowerPlotProgressRange = 0; dialog.UpperPlotProgressRange = 100; dialog.PlotProgressPos = 0; //显示打印对话框 dialog.OnBeginPlot(); dialog.IsVisible = true; //开始打印 engine.BeginPlot(dialog, null); //定义打印输出-需要完整的路径和文件名 engine.BeginDocument(info, doc.Name, null, 1, true, targetPath); //显示当前打印任务信息 dialog.set_PlotMsgString(PlotMessageIndex.Status, $"打印:{doc.Name}-{layout.LayoutName}"); //设置图纸进度范围 dialog.OnBeginSheet(); //设置图纸进度范围 dialog.LowerSheetProgressRange = 0; dialog.UpperSheetProgressRange = 100; dialog.SheetProgressPos = 0; //打印第一张图纸/布局 PlotPageInfo pageInfo = new PlotPageInfo(); engine.BeginPage(pageInfo, info, true, null); engine.BeginGenerateGraphics(null); engine.EndGenerateGraphics(null); //结束第一张图纸/布局的打印 engine.EndPage(null); dialog.SheetProgressPos = 100; dialog.OnEndSheet(); //结束文档打印 engine.EndDocument(null); //打印结束 dialog.PlotProgressPos = 100; dialog.OnEndPlot(); engine.EndPlot(null); } } } } }
选取两个点,以确定打印窗口的范围
public Point3d p1, p2; private void buttonWindow_Click(object sender, EventArgs e) { Editor ed = Application.DocumentManager.MdiActiveDocument.Editor; using (EditorUserInteraction interaction = ed.StartUserInteraction(this)) { PromptPointResult result1 = ed.GetPoint("指定第一个点"); if (result1.Status == PromptStatus.OK) p1 = result1.Value; ed.WriteMessage($"第一个点坐标 X:{p1.X},Y:{p1.Y},Z:{p1.Z}"); PromptPointResult result2 = ed.GetPoint("指定第二个点"); if (result2.Status == PromptStatus.OK) p2 = result2.Value; ed.WriteMessage($"第二个点坐标 X:{p2.X},Y:{p2.Y},Z:{p2.Z}"); interaction.End(); this.Focus(); } }
窗体事件处理程序
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) { mediaName = comboBox1.Text; } public string deviceName = string.Empty; public string mediaName = "UserDefinedMetric (1262.00 x 594.00毫米)"; public string path = string.Empty; private void FormPlot_Load(object sender, EventArgs e) { comboBox1.Items.Add("UserDefinedMetric (1061.00 x 604.00毫米)"); comboBox1.Items.Add("UserDefinedMetric (1272.00 x 604.00毫米)"); comboBox1.Items.Add("UserDefinedMetric (1482.00 x 604.00毫米)"); comboBox1.Items.Add("UserDefinedMetric (1692.00 x 604.00毫米)"); comboBox1.SelectedIndex = 0; deviceName = textBox1.Text; } private void buttonPlot_Click(object sender, EventArgs e) { path = @"C:\Users\Administrator\Desktop\" + "myPDF" + DateTime.Now.ToFileTime() + ".pdf"; Document doc = Application.DocumentManager.MdiActiveDocument; doc.SendStringToExecute("plotExtendTest\n", true, false, false); } private void buttonCancel_Click(object sender, EventArgs e) { this.Close(); }
交互窗体
事件处理程序的原则
事件只是简单地提供了关于 AutoCAD 的状态或发生在 AutoCAD 中的活动的信息,记住这一点非常重要的。 尽管可以编写事件处理程序来响应那些事件,但触发事件处理程序的操作中间是有个 AutoCAD 在那儿的。 因此,如果想让事件处理程序与 AutoCAD 及数据库一起使用时提供安全可靠的操作,必须对事件处理程序能做什么不能做什么有所限制。
• 原则 1: 不要依赖于事件的顺序。
编写事件处理程序时, 不要依赖于你所认为的事件发生的确切顺序序列。 例如,如果你运行 OPEN 命令, CommandWillStart 事件、 DocumentCreateStarted 事件、DocumentCreated 事件和 CommandEnded 事件都会被触发。 然而, 这些事件可能不会每次都以确切的顺序发生。 你唯一可以依赖的是成对儿发生的那两个事件:开始事件和结束事件。
• 原则 2:不要依赖于操作的顺序。
如果你删除了对象 1,然后又删除了对象 2,不要依赖一个事实,即您将先收到对象1 的 ObjectErased 事件,然后收到对象 2 的 ObjectErased 事件。 你可能会先收到对象 2 的 ObjectErased 事件。
• 原则 3: 不要从事件处理程序内尝试任何交互功能。
试图从事件处理程序内执行交互功能会引起严重问题,因为事件被触发时 AutoCAD可能仍在处理命令。 因此, 应该牢记避免从事件处理程序中执行下列操作: 在命令提示行请求输入、 请求选择对象以及使用 SendStringToExecute()方法等。
• 原则 4:不要从事件处理程序内启动对话框。
一般认为对话框是一种交互功能,会干扰到 AutoCAD 的当前操作,而消息框和警告框不是交互功能,可以放心使用; 不过,在下列事件的处理程序里发出消息框可能会导致意想不到的结果序列: EnterModal、 LeaveModal、 DocumentActivated、DocumentToBeDeactivated 等。
• 原则 5:可以向数据库中的任何对象写入数据,但应避免修改引发事件的那个对象。
很显然,引发事件的那个对象已经打开并且还处在当前的操作过程中。因此,应避免从该对象的事件处理程序修改这个对象。不过,可以放心地从触发事件的对象读取信息。
• 原则 6: 不要从事件处理程序执行可能会触发相同事件的任何操作。
如果在事件处理程序中执行触发同一事件的相同动作,就会进入一个无限循环(死循环)。例如,永远不要试图在 ObjectOpenedForModify 事件的处理程序中打开一个对象,否则 AutoCAD 就会不停地打开对象、打开对象……
• 原则 7: 当 AutoCAD 显示一个模式对话框时没有事件被触发。
对象事件
Polyline polyline = null; /// <summary> /// 创建多段线,并添加修改事件的处理程序 /// </summary> [CommandMethod("AddPolylineEvent")] public void AddPolylineEvent() { Database db = HostApplicationServices.WorkingDatabase; using (Transaction tr=db.TransactionManager.StartTransaction()) { BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable; BlockTableRecord btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; polyline = new Polyline(); Random r = new Random(); for (int i = 0; i < 5; i++) { polyline.AddVertexAt(i,new Point2d(r.Next(0,500), r.Next(0, 200)),0,r.Next(0,5), r.Next(0, 5)); } polyline.Closed = true; btr.AppendEntity(polyline); tr.AddNewlyCreatedDBObject(polyline,true); polyline.Modified += PolylineModified; tr.Commit(); } } /// <summary> /// 移除事件处理程序 /// </summary> [CommandMethod("RemovePolylineEvent")] public void RemovePolylineEvent() { if (polyline == null) return; Database db = HostApplicationServices.WorkingDatabase; using (Transaction tr=db.TransactionManager.StartTransaction()) { polyline = tr.GetObject(polyline.ObjectId, OpenMode.ForRead) as Polyline; if (polyline.IsWriteEnabled == false) polyline.UpgradeOpen(); polyline.Modified -= PolylineModified; polyline = null; } } private void PolylineModified(object sender, EventArgs e) { Application .ShowAlertDialog($"多段线的面积是{polyline.Area}"); }
运行结果
文档集合事件
#region 文档集DocumentCollection事件的测试 /// <summary> /// 添加事件处理程序到文档激活事件 /// </summary> [CommandMethod("AddDocCollEvent")] public void AddDocCollEvent() { Application.DocumentManager.DocumentActivated += DocActivatedHandler; } /// <summary> /// 从文档激活事件移除事件处理程序 /// </summary> [CommandMethod("RemoveDocCollEvent")] public void RemoveDocCollEvent() { Application.DocumentManager.DocumentActivated -= DocActivatedHandler; } /// <summary> /// 文档激活事件的处理程序 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void DocActivatedHandler(object sender, DocumentCollectionEventArgs e) { Application.ShowAlertDialog($"{e.Document.Name}被激活了!"); } #endregion
运行结果
文档事件测试
#region 文档Document事件测试 /// <summary> /// 添加事件处理程序到文档关闭事件 /// </summary> [CommandMethod("AddDocEvent")] public void AddDocEvent() { Application.DocumentManager.MdiActiveDocument.BeginDocumentClose += BeginDocCloseHandler; } /// <summary> /// 从文档关闭事件移除事件处理程序 /// </summary> [CommandMethod("RemoveDocEvent")] public void RemoveDocEvent() { Application.DocumentManager.MdiActiveDocument.BeginDocumentClose -= BeginDocCloseHandler; } /// <summary> /// 事件处理程序 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void BeginDocCloseHandler(object sender, DocumentBeginCloseEventArgs e) { string[] m = new string[] { $"文档即将关闭。 \n确认继续?", "关闭文档" }; if (MessageBox.Show(m[0], m[1], MessageBoxButtons.YesNo) == DialogResult.No) e.Veto(); } #endregion
运行结果
CAD事件测试-更改系统变量,并触发事件(弹出一个警告对话框,并显示更改内容)
/// <summary> /// 将事件处理程序注册(添加)到事件 /// </summary> [CommandMethod("AddAppEvent")] public void AddAppEvent() { Application.SystemVariableChanged += SystemVariableChangedHandler; } /// <summary> /// 取消事件处理程序的注册(移除) /// </summary> [CommandMethod("RemoveAppEvent")] public void RemoveAppEvent() { Application.SystemVariableChanged -= SystemVariableChangedHandler; } /// <summary> /// 定义事件处理程序 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void SystemVariableChangedHandler(object sender, SystemVariableChangedEventArgs e) { Application.ShowAlertDialog($"\n改变了系统变量:{e.Name}\n改变后的值为:{Application.GetSystemVariable(e.Name)}"); }
运行结果
通过选择一个dwg文件,来启动CAD,并与CAD相关联
/// <summary> /// 通过选择dwg文件,启动CAD,以便与CAD进行关联 /// </summary> private void StartCAD() { try { app = System.Runtime.InteropServices.Marshal.GetActiveObject("AutoCAD.Applicaton") as AcadApplication; doc = app.ActiveDocument; } catch (Exception) { OpenFileDialog dialog = new OpenFileDialog(); dialog.Filter = "CAD文件(*.dwg)|*.dwg|CAD图形文件(*.dxf)|*.dxf"; dialog.ShowDialog(); dialog.Title = "打开CAD文件"; string path = dialog.FileName; if (path == "") { MessageBox.Show("选择文件无效!", "文件无效!"); Application.Exit(); } app = new AcadApplication(); if (File.Exists(path)) doc = app.Documents.Open(path, null, null); } app.Visible = true; Microsoft.VisualBasic.Interaction.AppActivate(app.Caption); }
通过WinForm程序,获取选择集对象,并显示直线对象的坐标信息到WinForm窗体控件
AcadApplication app; AcadDocument doc; /// <summary> /// 通过手动选择获取选择集,从而获取直线坐标 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button_GetLineCoords_Click(object sender, EventArgs e) { Microsoft.VisualBasic.Interaction.AppActivate(app.Caption); AcadSelectionSet ss = doc.SelectionSets.Add("NewSelectionSet001"); Int16[] filterType = new Int16[] { 0 }; object[] filterData = new object[] { "*" }; ss.SelectOnScreen(filterType, filterData); if (ss == null) return; int count = 1; foreach (AcadObject item in ss) { if (item.ObjectName == "AcDbLine") { AcadLine line = (AcadLine)item; listBox1.Items.Add($"第{count}条直线坐标"); listBox1.Items.Add($"起点坐标X:{line.StartPoint[0]},Y:{line.StartPoint[1]},Z:{line.StartPoint[2]}"); listBox1.Items.Add($"终点坐标X:{line.EndPoint[0]},Y:{line.EndPoint[1]},Z:{line.EndPoint[2]}"); count++; } } listBox1.Items.Add($"共选择{ss.Count}个对象,其中直线{count - 1}条"); doc.SelectionSets.Item("NewSelectionSet001").Delete(); Microsoft.VisualBasic.Interaction.AppActivate(this.Text); }
运行结果
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了