明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 10186|回复: 12

Kean专题(12)—Plotting

[复制链接]
发表于 2009-6-20 16:17 | 显示全部楼层 |阅读模式
本帖最后由 作者 于 2009-6-20 17:02:23 编辑

http://through-the-interface.typepad.com/through_the_interface/plotting/
一、使用Design Review 2008的批打印插件
May 10, 2007
Automating batch printing of DWF files using Design Review 2008
We sometimes receive questions on how best to automate the printing of DWF files. Autodesk Design Review 2008 now has a new Batch Print Plug-in enabling just this.
Once you've installed the plug-in, you'll be able to use the Batch Print Wizard in Design Review (on the file menu, once a DWF has been loaded). This Wizard allows you to configure a batch job for Design Review to process and save it to a BPJ (Batch Print Job) file. This BPJ (which is basically a very simple XML file) can then be used to drive the batch print process automatically.
The next logical step is clearly to create the BPJ programmatically, which can be done using a number of XML libraries (MS XML etc.) or simply by writing out a text file using your favourite string output routines.
So let's look at creating the BPJ file "manually" using the Batch Print Wizard.
Here's the second screen you'll see, once you've skipped the welcome:

When you've selected the files you wish to print and added them to the right-hand side using the ">" button, you can move on to the next page:

This is where you modify the print setup for each of your DWFs, by clicking on the item and hitting "rint Setup", or just double-clicking the item.

And then you're ready to save the BPJ file (or just "rint" directly).
I saved mine as "c:\My Documents\MyFiles.bpj", and here are its contents, with additional whitespace added for readability:
  1. <configuration_file>
  2.   <DWF_File
  3.     FileName="C:\My Documents\\First.dwf"
  4.     PageSize="11.0 x 8.5 in"
  5.     NoOfSections="2"
  6.     Print_to_scale="100"
  7.     User_defined_Zoom_Factor="100"
  8.     Print_Style="0"
  9.     Print_What="0"
  10.     Fit_To_Paper="1"
  11.     Paper_Size="9"
  12.     Paper_Size_Width="2100"
  13.     Paper_Size_Height="2970"
  14.     Orientation="2"
  15.     Number_of_copies="1"
  16.     PrinterName="\\beihpa001\BEIPRN003"
  17.     Page_Range="1"
  18.     Print_Range_Str=""
  19.     Reverse_Order="0"
  20.     Collate="0"
  21.     printColor="0"
  22.     printAlignment="4"
  23.     Use_DWF_Paper_Size="0"
  24.     PaperName="A4"
  25.     useHPIP="0"
  26.     HPIPMediaID="-1"
  27.     HPIPExcludeEModel="1"
  28.     HPIPPaperName=""/>
  29.   <DWF_File
  30.     FileName="C:\My Documents\\Second.dwf"
  31.     PageSize="11.0 x 8.5 in"
  32.     NoOfSections="2"
  33.     Print_to_scale="100"
  34.     User_defined_Zoom_Factor="100"
  35.     Print_Style="0"
  36.     Print_What="0"
  37.     Fit_To_Paper="1"
  38.     Paper_Size="9"
  39.     Paper_Size_Width="2100"
  40.     Paper_Size_Height="2970"
  41.     Orientation="2"
  42.     Number_of_copies="1"
  43.     PrinterName="\\beihpa001\BEIPRN003"
  44.     Page_Range="1"
  45.     Print_Range_Str=""
  46.     Reverse_Order="0"
  47.     Collate="0"
  48.     printColor="0"
  49.     printAlignment="4"
  50.     Use_DWF_Paper_Size="0"
  51.     PaperName="A4"
  52.     useHPIP="0"
  53.     HPIPMediaID="-1"
  54.     HPIPExcludeEModel="1"
  55.     HPIPPaperName=""/>
  56. </configuration_file>
复制代码
This is clearly straightforward to create programmatically from your application. The next question is how best to automate the print process, now we have our BPJ.
The simplest way is to call the Design Review executable with the BPJ file as a command-line argument:

The executable returns straight away, and you'll see a log file created in the same location as the BPJ (in my case "c:\My Documents\MyFiles.log"), detailing the results of the print job:
  1. Batch Printing initiated with Configuration file: "\My Documents\MyFiles.bpj". Start Time: Thu May 10 17:16:35 2007
  2.   Opening DWF file : "C:\My Documents\\First.dwf". Start Time: Thu May 10 17:16:35 2007
  3.   DWF file: "C:\My Documents\\First.dwf" Opened successfully. End Time: Thu May 10 17:16:37 2007
  4.     Status:DWF Open Successful
  5.   Started Printing DWF File: "C:\My Documents\\First.dwf". Start Time: Thu May 10 17:16:39 2007
  6.       Printing To    : \\beihpa001\BEIPRN003
  7.       HPIP set to    : False
  8.       Paper Size    : 2100 X 2970
  9.       Print Range    : Current Page
  10.       No Of Copies  : 1
  11.       Scale          : 100 %, Tile Pages (Not Applicable For 3D Sections)
  12.       Print Alignment: LowerLeft (Not Applicable For 3D Sections)
  13.       Orientation    : Landscape
  14.       Print Color    : Color
  15.       Started Printing Section Number : 0. Start Time: Thu May 10 17:16:39 2007
  16.       Finished Printing Section Number: 0. End Time  : Thu May 10 17:16:42 2007
  17.       Started Printing Section Number : 1. Start Time: Thu May 10 17:16:43 2007
  18.       Finished Printing Section Number: 1. End Time  : Thu May 10 17:16:43 2007
  19.   Finished Printing DWF file: "C:\My Documents\\First.dwf" . End Time: Thu May 10 17:16:43 2007
  20.   Opening DWF file : "C:\My Documents\\Second.dwf". Start Time: Thu May 10 17:16:43 2007
  21.   DWF file: "C:\My Documents\\Second.dwf" Opened successfully. End Time: Thu May 10 17:16:45 2007
  22.     Status:DWF Open Successful
  23.   Started Printing DWF File: "C:\My Documents\\Second.dwf". Start Time: Thu May 10 17:16:46 2007
  24.       Printing To    : \\beihpa001\BEIPRN003
  25.       HPIP set to    : False
  26.       Paper Size    : 2100 X 2970
  27.       Print Range    : Current Page
  28.       No Of Copies  : 1
  29.       Scale          : 100 %, Tile Pages (Not Applicable For 3D Sections)
  30.       Print Alignment: LowerLeft (Not Applicable For 3D Sections)
  31.       Orientation    : Landscape
  32.       Print Color    : Color
  33.       Started Printing Section Number : 0. Start Time: Thu May 10 17:16:46 2007
  34.       Finished Printing Section Number: 0. End Time  : Thu May 10 17:16:49 2007
  35.       Started Printing Section Number : 1. Start Time: Thu May 10 17:16:49 2007
  36.       Finished Printing Section Number: 1. End Time  : Thu May 10 17:16:50 2007
  37.   Finished Printing DWF file: "C:\My Documents\\Second.dwf" . End Time: Thu May 10 17:16:50 2007
  38. Batch Printing Finished with Configuration file: "\My Documents\MyFiles.bpj". End Time: Thu May 10 17:16:50 2007
  39. Total Time Taken to complete Batch Print Process: 0 hr: 0 Min: 15 Sec.
复制代码
This log file can be parsed programmatically if it's important for your application to know whether any pages had difficulty printing.

本帖子中包含更多资源

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

x
发表于 2023-8-10 17:38 | 显示全部楼层
图纸尺寸列表中 显示的是英文 MM,而不是中文 毫米,,而CAD自带德打印模块显示的 图纸尺寸 是 中文 毫米,编程 怎么实现
发表于 2023-7-2 15:27 | 显示全部楼层

打印预览有没有调过了的?为啥一直卡在预览界面?
发表于 2023-6-29 19:38 | 显示全部楼层
打印预览有没有调过了的?为啥一直卡在预览界面?
 楼主| 发表于 2009-6-21 11:34 | 显示全部楼层
二、使用NetApi实现简单的打印任务
September 25, 2007
Driving a basic AutoCAD plot using .NET
I just missed my connecting flight in Chicago, so have 3 hours to pass until the next, and decided to post some code I finally got around to writing on the plane from Zurich.
I've had a few requests for code showing how to plot using the .NET API in AutoCAD. There's an existing ObjectARX (C++) sample on the SDK, under samples/editor/AsdkPlotAPI, but there isn't a publicly posted .NET version right now.
Here's the C# code I put together. Please bear in mind that it was written during less than ideal coding conditions, and I haven't spent a substantial amount of time going through it... it seems to work fine for me, but do post a comment if you have trouble with it.
  1. using Autodesk.AutoCAD.Runtime;
  2. using Autodesk.AutoCAD.ApplicationServices;
  3. using Autodesk.AutoCAD.DatabaseServices;
  4. using Autodesk.AutoCAD.EditorInput;
  5. using Autodesk.AutoCAD.Geometry;
  6. using Autodesk.AutoCAD.PlottingServices;
  7. namespace PlottingApplication
  8. {
  9.   public class PlottingCommands
  10.   {
  11.     [CommandMethod("simplot")]
  12.     static public void SimplePlot()
  13.     {
  14.       Document doc =
  15.         Application.DocumentManager.MdiActiveDocument;
  16.       Editor ed = doc.Editor;
  17.       Database db = doc.Database;
  18.       Transaction tr =
  19.         db.TransactionManager.StartTransaction();
  20.       using (tr)
  21.       {
  22.         // We'll be plotting the current layout
  23.         BlockTableRecord btr =
  24.           (BlockTableRecord)tr.GetObject(
  25.             db.CurrentSpaceId,
  26.             OpenMode.ForRead
  27.           );
  28.         Layout lo =
  29.           (Layout)tr.GetObject(
  30.             btr.LayoutId,
  31.             OpenMode.ForRead
  32.           );
  33.         // We need a PlotInfo object
  34.         // linked to the layout
  35.         PlotInfo pi = new PlotInfo();
  36.         pi.Layout = btr.LayoutId;
  37.         // We need a PlotSettings object
  38.         // based on the layout settings
  39.         // which we then customize
  40.         PlotSettings ps =
  41.           new PlotSettings(lo.ModelType);
  42.         ps.CopyFrom(lo);
  43.         // The PlotSettingsValidator helps
  44.         // create a valid PlotSettings object
  45.         PlotSettingsValidator psv =
  46.           PlotSettingsValidator.Current;
  47.         // We'll plot the extents, centered and
  48.         // scaled to fit
  49.         psv.SetPlotType(
  50.           ps,
  51.           Autodesk.AutoCAD.DatabaseServices.PlotType.Extents
  52.         );
  53.         psv.SetUseStandardScale(ps, true);
  54.         psv.SetStdScaleType(ps, StdScaleType.ScaleToFit);
  55.         psv.SetPlotCentered(ps, true);
  56.         // We'll use the standard DWF PC3, as
  57.         // for today we're just plotting to file
  58.         psv.SetPlotConfigurationName(
  59.           ps,
  60.           "DWF6 ePlot.pc3",
  61.           "ANSI_A_(8.50_x_11.00_Inches)"
  62.         );
  63.         // We need to link the PlotInfo to the
  64.         // PlotSettings and then validate it
  65.         pi.OverrideSettings = ps;
  66.         PlotInfoValidator piv =
  67.           new PlotInfoValidator();
  68.         piv.MediaMatchingPolicy =
  69.           MatchingPolicy.MatchEnabled;
  70.         piv.Validate(pi);
  71.         // A PlotEngine does the actual plotting
  72.         // (can also create one for Preview)
  73.         if (PlotFactory.ProcessPlotState ==
  74.             ProcessPlotState.NotPlotting)
  75.         {
  76.           PlotEngine pe =
  77.             PlotFactory.CreatePublishEngine();
  78.           using (pe)
  79.           {
  80.             // Create a Progress Dialog to provide info
  81.             // and allow thej user to cancel
  82.             PlotProgressDialog ppd =
  83.               new PlotProgressDialog(false, 1, true);
  84.             using (ppd)
  85.             {
  86.               ppd.set_PlotMsgString(
  87.                 PlotMessageIndex.DialogTitle,
  88.                 "Custom Plot Progress"
  89.               );
  90.               ppd.set_PlotMsgString(
  91.                 PlotMessageIndex.CancelJobButtonMessage,
  92.                 "Cancel Job"
  93.               );
  94.               ppd.set_PlotMsgString(
  95.                 PlotMessageIndex.CancelSheetButtonMessage,
  96.                 "Cancel Sheet"
  97.               );
  98.               ppd.set_PlotMsgString(
  99.                 PlotMessageIndex.SheetSetProgressCaption,
  100.                 "Sheet Set Progress"
  101.               );
  102.               ppd.set_PlotMsgString(
  103.                 PlotMessageIndex.SheetProgressCaption,
  104.                 "Sheet Progress"
  105.               );
  106.               ppd.LowerPlotProgressRange = 0;
  107.               ppd.UpperPlotProgressRange = 100;
  108.               ppd.PlotProgressPos = 0;
  109.               // Let's start the plot, at last
  110.               ppd.OnBeginPlot();
  111.               ppd.IsVisible = true;
  112.               pe.BeginPlot(ppd, null);
  113.               // We'll be plotting a single document
  114.               pe.BeginDocument(
  115.                 pi,
  116.                 doc.Name,
  117.                 null,
  118.                 1,
  119.                 true, // Let's plot to file
  120.                 "c:\\test-output"
  121.               );
  122.               // Which contains a single sheet
  123.               ppd.OnBeginSheet();
  124.               ppd.LowerSheetProgressRange = 0;
  125.               ppd.UpperSheetProgressRange = 100;
  126.               ppd.SheetProgressPos = 0;
  127.               PlotPageInfo ppi = new PlotPageInfo();
  128.               pe.BeginPage(
  129.                 ppi,
  130.                 pi,
  131.                 true,
  132.                 null
  133.               );
  134.               pe.BeginGenerateGraphics(null);
  135.               pe.EndGenerateGraphics(null);
  136.               // Finish the sheet
  137.               pe.EndPage(null);
  138.               ppd.SheetProgressPos = 100;
  139.               ppd.OnEndSheet();
  140.               // Finish the document
  141.               pe.EndDocument(null);
  142.               // And finish the plot
  143.               ppd.PlotProgressPos = 100;
  144.               ppd.OnEndPlot();
  145.               pe.EndPlot(null);
  146.             }
  147.           }
  148.         }
  149.         else
  150.         {
  151.           ed.WriteMessage(
  152.             "\nAnother plot is in progress."
  153.           );
  154.         }
  155.       }
  156.     }
  157.   }
  158. }
A few comments on the code: I chose to plot to a file using the standard DWF plot driver/PC3 file, mainly as it avoids having to second-guess what printers/plotters everyone uses. :-) The SDK sample populates comboboxes in a dialog to allow selection of the device and the media size, but I've just gone with a choice that should work on all systems.
Here's what you should see when you launch the SIMPLOT command:

The output file should be created in "c:\test-output.dwf".
I added a simple check to fail gracefully when another plot is in progress... as this code will drive either a foreground or a background plot (depending on the value of the BACKGROUNDPLOT system variable), there's clear scope for failure if the code doesn't check via PlotFactory.ProcessPlotState (or handle the exception if another plot is already happening when you call PlotFactory.CreatePublishEngine()).
Now that I'm online I've found there's quite a similar code sample to the ADN site (also converted from the original SDK sample, I suspect):

本帖子中包含更多资源

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

x
 楼主| 发表于 2009-6-21 11:40 | 显示全部楼层
三、使用NetApi实现多表打印任务
September 29, 2007
Driving a multi-sheet AutoCAD plot using .NET
Somewhat symmetrically I’m posting this from Chicago airport, once again, but thankfully I’m now on my way home. It was a busy week of meetings, but I did get the chance to put together some code that extended the last post into the realm of multi-sheet plot jobs.
The following code took some work, but I finally managed to iron out the obvious wrinkles and put together an approach to plot multiple sheets into a single document. The standard DWF6 driver doesn’t appear to support multiple sheet jobs (directly, at least), so I chose to use the DWFx driver that I probably downloaded and installed from here.
I haven’t “diffed” and colour-coded the changed lines with the previous post, as there ended up being quite a lot of swapping around etc., but you should be able to perform that comparison yourself, if you so wish.
Here’s the C# code:
  1. using Autodesk.AutoCAD.Runtime;
  2. using Autodesk.AutoCAD.ApplicationServices;
  3. using Autodesk.AutoCAD.DatabaseServices;
  4. using Autodesk.AutoCAD.EditorInput;
  5. using Autodesk.AutoCAD.Geometry;
  6. using Autodesk.AutoCAD.PlottingServices;
  7. namespace PlottingApplication
  8. {
  9.   public class PlottingCommands
  10.   {
  11.     [CommandMethod("mplot")]
  12.     static public void MultiSheetPlot()
  13.     {
  14.       Document doc =
  15.         Application.DocumentManager.MdiActiveDocument;
  16.       Editor ed = doc.Editor;
  17.       Database db = doc.Database;
  18.       Transaction tr =
  19.         db.TransactionManager.StartTransaction();
  20.       using (tr)
  21.       {
  22.         BlockTable bt =
  23.           (BlockTable)tr.GetObject(
  24.             db.BlockTableId,
  25.             OpenMode.ForRead
  26.           );
  27.         PlotInfo pi = new PlotInfo();
  28.         PlotInfoValidator piv =
  29.           new PlotInfoValidator();
  30.         piv.MediaMatchingPolicy =
  31.           MatchingPolicy.MatchEnabled;
  32.         // A PlotEngine does the actual plotting
  33.         // (can also create one for Preview)
  34.         if (PlotFactory.ProcessPlotState ==
  35.             ProcessPlotState.NotPlotting)
  36.         {
  37.           PlotEngine pe =
  38.             PlotFactory.CreatePublishEngine();
  39.           using (pe)
  40.           {
  41.             // Create a Progress Dialog to provide info
  42.             // and allow thej user to cancel
  43.             PlotProgressDialog ppd =
  44.               new PlotProgressDialog(false, 1, true);
  45.             using (ppd)
  46.             {
  47.               ObjectIdCollection layoutsToPlot =
  48.                 new ObjectIdCollection();
  49.               foreach (ObjectId btrId in bt)
  50.               {
  51.                 BlockTableRecord btr =
  52.                   (BlockTableRecord)tr.GetObject(
  53.                     btrId,
  54.                     OpenMode.ForRead
  55.                   );
  56.                 if (btr.IsLayout &&
  57.                     btr.Name.ToUpper() !=
  58.                       BlockTableRecord.ModelSpace.ToUpper())
  59.                 {
  60.                   layoutsToPlot.Add(btrId);
  61.                 }
  62.               }
  63.               int numSheet = 1;
  64.               foreach (ObjectId btrId in layoutsToPlot)
  65.               {
  66.                 BlockTableRecord btr =
  67.                   (BlockTableRecord)tr.GetObject(
  68.                     btrId,
  69.                     OpenMode.ForRead
  70.                   );
  71.                 Layout lo =
  72.                   (Layout)tr.GetObject(
  73.                     btr.LayoutId,
  74.                     OpenMode.ForRead
  75.                   );
  76.                 // We need a PlotSettings object
  77.                 // based on the layout settings
  78.                 // which we then customize
  79.                 PlotSettings ps =
  80.                   new PlotSettings(lo.ModelType);
  81.                 ps.CopyFrom(lo);
  82.                 // The PlotSettingsValidator helps
  83.                 // create a valid PlotSettings object
  84.                 PlotSettingsValidator psv =
  85.                   PlotSettingsValidator.Current;
  86.                 // We'll plot the extents, centered and
  87.                 // scaled to fit
  88.                 psv.SetPlotType(
  89.                   ps,
  90.                 Autodesk.AutoCAD.DatabaseServices.PlotType.Extents
  91.                 );
  92.                 psv.SetUseStandardScale(ps, true);
  93.                 psv.SetStdScaleType(ps, StdScaleType.ScaleToFit);
  94.                 psv.SetPlotCentered(ps, true);
  95.                 // We'll use the standard DWFx PC3, as
  96.                 // this supports multiple sheets
  97.                 psv.SetPlotConfigurationName(
  98.                   ps,
  99.                   "DWFx ePlot (XPS Compatible).pc3",
  100.                   "ANSI_A_(8.50_x_11.00_Inches)"
  101.                 );
  102.                 // We need a PlotInfo object
  103.                 // linked to the layout
  104.                 pi.Layout = btr.LayoutId;
  105.                 // Make the layout we're plotting current
  106.                 LayoutManager.Current.CurrentLayout =
  107.                   lo.LayoutName;
  108.                 // We need to link the PlotInfo to the
  109.                 // PlotSettings and then validate it
  110.                 pi.OverrideSettings = ps;
  111.                 piv.Validate(pi);
  112.                 if (numSheet == 1)
  113.                 {
  114.                   ppd.set_PlotMsgString(
  115.                     PlotMessageIndex.DialogTitle,
  116.                     "Custom Plot Progress"
  117.                   );
  118.                   ppd.set_PlotMsgString(
  119.                     PlotMessageIndex.CancelJobButtonMessage,
  120.                     "Cancel Job"
  121.                   );
  122.                   ppd.set_PlotMsgString(
  123.                     PlotMessageIndex.CancelSheetButtonMessage,
  124.                     "Cancel Sheet"
  125.                   );
  126.                   ppd.set_PlotMsgString(
  127.                     PlotMessageIndex.SheetSetProgressCaption,
  128.                     "Sheet Set Progress"
  129.                   );
  130.                   ppd.set_PlotMsgString(
  131.                     PlotMessageIndex.SheetProgressCaption,
  132.                     "Sheet Progress"
  133.                   );
  134.                   ppd.LowerPlotProgressRange = 0;
  135.                   ppd.UpperPlotProgressRange = 100;
  136.                   ppd.PlotProgressPos = 0;
  137.                   // Let's start the plot, at last
  138.                   ppd.OnBeginPlot();
  139.                   ppd.IsVisible = true;
  140.                   pe.BeginPlot(ppd, null);
  141.                   // We'll be plotting a single document
  142.                   pe.BeginDocument(
  143.                     pi,
  144.                     doc.Name,
  145.                     null,
  146.                     1,
  147.                     true, // Let's plot to file
  148.                     "c:\\test-multi-sheet"
  149.                   );
  150.                 }
  151.                 // Which may contain multiple sheets
  152.                 ppd.StatusMsgString =
  153.                   "Plotting " +
  154.                   doc.Name.Substring(
  155.                     doc.Name.LastIndexOf("\") + 1
  156.                   ) +
  157.                   " - sheet " + numSheet.ToString() +
  158.                   " of " + layoutsToPlot.Count.ToString();
  159.                 ppd.OnBeginSheet();
  160.                 ppd.LowerSheetProgressRange = 0;
  161.                 ppd.UpperSheetProgressRange = 100;
  162.                 ppd.SheetProgressPos = 0;
  163.                 PlotPageInfo ppi = new PlotPageInfo();
  164.                 pe.BeginPage(
  165.                   ppi,
  166.                   pi,
  167.                   (numSheet == layoutsToPlot.Count),
  168.                   null
  169.                 );
  170.                 pe.BeginGenerateGraphics(null);
  171.                 ppd.SheetProgressPos = 50;
  172.                 pe.EndGenerateGraphics(null);
  173.                 // Finish the sheet
  174.                 pe.EndPage(null);
  175.                 ppd.SheetProgressPos = 100;
  176.                 ppd.OnEndSheet();
  177.                 numSheet++;
  178.               }
  179.               // Finish the document
  180.               pe.EndDocument(null);
  181.               // And finish the plot
  182.               ppd.PlotProgressPos = 100;
  183.               ppd.OnEndPlot();
  184.               pe.EndPlot(null);
  185.             }
  186.           }
  187.         }
  188.         else
  189.         {
  190.           ed.WriteMessage(
  191.             "\nAnother plot is in progress."
  192.           );
  193.         }
  194.       }
  195.     }
  196.   }
  197. }
The output of the MPLOT command will be created in “c:\test-multi-sheet.dwfx”, which can then be viewed using Autodesk Design Review 2008 or the XPS viewer that ships with Windows Vista or from here for Windows XP.
Update
I spent some more time looking at this code and noticed a minor issue... We need to tell the plot dialog that we're working with multiple sheets in its constructor. So we first need to count the sheets and then create the dialog. Here's the modified section of code:
  1.           PlotEngine pe =
  2.             PlotFactory.CreatePublishEngine();
  3.           using (pe)
  4.           {
  5.             // Collect all the paperspace layouts
  6.             // for plotting
  7.             ObjectIdCollection layoutsToPlot =
  8.               new ObjectIdCollection();
  9.             foreach (ObjectId btrId in bt)
  10.             {
  11.               BlockTableRecord btr =
  12.                 (BlockTableRecord)tr.GetObject(
  13.                   btrId,
  14.                   OpenMode.ForRead
  15.                 );
  16.               if (btr.IsLayout &&
  17.                   btr.Name.ToUpper() !=
  18.                     BlockTableRecord.ModelSpace.ToUpper())
  19.               {
  20.                 layoutsToPlot.Add(btrId);
  21.               }
  22.             }
  23.             // Create a Progress Dialog to provide info
  24.             // and allow thej user to cancel
  25.             PlotProgressDialog ppd =
  26.               new PlotProgressDialog(
  27.                 false,
  28.                 layoutsToPlot.Count,
  29.                 true
  30.               );
  31.             using (ppd)
  32.             {
This now leads to the plot progress dialog showing multiple progress bars:

本帖子中包含更多资源

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

x
 楼主| 发表于 2009-6-23 22:04 | 显示全部楼层
四、单表打印预览
October 01, 2007
Previewing and plotting a single sheet in AutoCAD using .NET
This week's posts take the code I threw together last week for single-sheet and multi-sheet plotting, and introduces the concept of "plot preview".
I'm learning as I go for much of this, so there are structural (although usually not functional) changes being made to the code as it develops. In this instance, for example, I've factored off common functionality needed by both previewing and plotting into a single helper function. This will no doubt evolve further (and change in structure) when I come to apply the principle to multi-sheet plotting later in the week.
Here's the C# code:
  1. using Autodesk.AutoCAD.Runtime;
  2. using Autodesk.AutoCAD.ApplicationServices;
  3. using Autodesk.AutoCAD.DatabaseServices;
  4. using Autodesk.AutoCAD.EditorInput;
  5. using Autodesk.AutoCAD.PlottingServices;
  6. namespace PlottingApplication
  7. {
  8.   public class PreviewCommands
  9.   {
  10.     [CommandMethod("simprev")]
  11.     static public void SimplePreview()
  12.     {
  13.       Document doc =
  14.         Application.DocumentManager.MdiActiveDocument;
  15.       Editor ed = doc.Editor;
  16.       Database db = doc.Database;
  17.       // PlotEngines do the previewing and plotting
  18.       if (PlotFactory.ProcessPlotState ==
  19.           ProcessPlotState.NotPlotting)
  20.       {
  21.         // First we preview...
  22.         PreviewEndPlotStatus stat;
  23.         PlotEngine pre =
  24.           PlotFactory.CreatePreviewEngine(
  25.             (int)PreviewEngineFlags.Plot
  26.           );
  27.         using (pre)
  28.         {
  29.           stat =
  30.             PlotOrPreview(
  31.               pre,
  32.               true,
  33.               db.CurrentSpaceId,
  34.               ""
  35.             );
  36.         }
  37.         if (stat == PreviewEndPlotStatus.Plot)
  38.         {
  39.           // And if the user asks, we plot...
  40.           PlotEngine ple =
  41.             PlotFactory.CreatePublishEngine();
  42.           stat =
  43.             PlotOrPreview(
  44.               ple,
  45.               false,
  46.               db.CurrentSpaceId,
  47.               "c:\\previewed-plot"
  48.             );
  49.         }
  50.       }
  51.       else
  52.       {
  53.         ed.WriteMessage(
  54.           "\nAnother plot is in progress."
  55.         );
  56.       }
  57.     }
  58.     static PreviewEndPlotStatus PlotOrPreview(
  59.       PlotEngine pe,
  60.       bool isPreview,
  61.       ObjectId spaceId,
  62.       string filename)
  63.     {
  64.       Document doc =
  65.         Application.DocumentManager.MdiActiveDocument;
  66.       Editor ed = doc.Editor;
  67.       Database db = doc.Database;
  68.       PreviewEndPlotStatus ret =
  69.         PreviewEndPlotStatus.Cancel;
  70.       Transaction tr =
  71.         db.TransactionManager.StartTransaction();
  72.       using (tr)
  73.       {
  74.         // We'll be plotting the current layout
  75.         BlockTableRecord btr =
  76.           (BlockTableRecord)tr.GetObject(
  77.             spaceId,
  78.             OpenMode.ForRead
  79.           );
  80.         Layout lo =
  81.           (Layout)tr.GetObject(
  82.             btr.LayoutId,
  83.             OpenMode.ForRead
  84.           );
  85.         // We need a PlotInfo object
  86.         // linked to the layout
  87.         PlotInfo pi = new PlotInfo();
  88.         pi.Layout = btr.LayoutId;
  89.         // We need a PlotSettings object
  90.         // based on the layout settings
  91.         // which we then customize
  92.         PlotSettings ps =
  93.           new PlotSettings(lo.ModelType);
  94.         ps.CopyFrom(lo);
  95.         // The PlotSettingsValidator helps
  96.         // create a valid PlotSettings object
  97.         PlotSettingsValidator psv =
  98.           PlotSettingsValidator.Current;
  99.         // We'll plot the extents, centered and
  100.         // scaled to fit
  101.         psv.SetPlotType(
  102.           ps,
  103.           Autodesk.AutoCAD.DatabaseServices.PlotType.Extents
  104.         );
  105.         psv.SetUseStandardScale(ps, true);
  106.         psv.SetStdScaleType(ps, StdScaleType.ScaleToFit);
  107.         psv.SetPlotCentered(ps, true);
  108.         // We'll use the standard DWF PC3, as
  109.         // for today we're just plotting to file
  110.         psv.SetPlotConfigurationName(
  111.           ps,
  112.           "DWF6 ePlot.pc3",
  113.           "ANSI_A_(8.50_x_11.00_Inches)"
  114.         );
  115.         // We need to link the PlotInfo to the
  116.         // PlotSettings and then validate it
  117.         pi.OverrideSettings = ps;
  118.         PlotInfoValidator piv =
  119.           new PlotInfoValidator();
  120.         piv.MediaMatchingPolicy =
  121.           MatchingPolicy.MatchEnabled;
  122.         piv.Validate(pi);
  123.         // Create a Progress Dialog to provide info
  124.         // and allow thej user to cancel
  125.         PlotProgressDialog ppd =
  126.           new PlotProgressDialog(isPreview, 1, true);
  127.         using (ppd)
  128.         {
  129.           ppd.set_PlotMsgString(
  130.             PlotMessageIndex.DialogTitle,
  131.             "Custom Preview Progress"
  132.           );
  133.           ppd.set_PlotMsgString(
  134.             PlotMessageIndex.SheetName,
  135.             doc.Name.Substring(
  136.               doc.Name.LastIndexOf("\") + 1
  137.             )
  138.           );
  139.           ppd.set_PlotMsgString(
  140.             PlotMessageIndex.CancelJobButtonMessage,
  141.             "Cancel Job"
  142.           );
  143.           ppd.set_PlotMsgString(
  144.             PlotMessageIndex.CancelSheetButtonMessage,
  145.             "Cancel Sheet"
  146.           );
  147.           ppd.set_PlotMsgString(
  148.             PlotMessageIndex.SheetSetProgressCaption,
  149.             "Sheet Set Progress"
  150.           );
  151.           ppd.set_PlotMsgString(
  152.             PlotMessageIndex.SheetProgressCaption,
  153.             "Sheet Progress"
  154.           );
  155.           ppd.LowerPlotProgressRange = 0;
  156.           ppd.UpperPlotProgressRange = 100;
  157.           ppd.PlotProgressPos = 0;
  158.           // Let's start the plot/preview, at last
  159.           ppd.OnBeginPlot();
  160.           ppd.IsVisible = true;
  161.           pe.BeginPlot(ppd, null);
  162.           // We'll be plotting/previewing
  163.           // a single document
  164.           pe.BeginDocument(
  165.             pi,
  166.             doc.Name,
  167.             null,
  168.             1,
  169.             !isPreview,
  170.             filename
  171.           );
  172.           // Which contains a single sheet
  173.           ppd.OnBeginSheet();
  174.           ppd.LowerSheetProgressRange = 0;
  175.           ppd.UpperSheetProgressRange = 100;
  176.           ppd.SheetProgressPos = 0;
  177.           PlotPageInfo ppi = new PlotPageInfo();
  178.           pe.BeginPage(
  179.             ppi,
  180.             pi,
  181.             true,
  182.             null
  183.           );
  184.           pe.BeginGenerateGraphics(null);
  185.           ppd.SheetProgressPos = 50;
  186.           pe.EndGenerateGraphics(null);
  187.           // Finish the sheet
  188.           PreviewEndPlotInfo pepi =
  189.             new PreviewEndPlotInfo();
  190.           pe.EndPage(pepi);
  191.           ret = pepi.Status;
  192.           ppd.SheetProgressPos = 100;
  193.           ppd.OnEndSheet();
  194.           // Finish the document
  195.           pe.EndDocument(null);
  196.           // And finish the plot
  197.           ppd.PlotProgressPos = 100;
  198.           ppd.OnEndPlot();
  199.           pe.EndPlot(null);
  200.         }
  201.         // Committing is cheaper than aborting
  202.         tr.Commit();
  203.       }
  204.       return ret;
  205.     }
  206.   }
  207. }
When you execute the SIMPREV command, you receive enter a "preview" mode, from where you can either cancel or plot. The trick was really in determining the button selected by the user, which we do by passing an appropriate object (of class PreviewEndPlotInfo) into the EndPage() function, to collect information on what the users selects. The next post will take this further, allowing the user to cycle through multiple sheets using "next" and "previous" buttons.

 楼主| 发表于 2009-6-23 22:07 | 显示全部楼层
五、多表打印预览
October 04, 2007
Previewing and plotting multiple sheets in AutoCAD using .NET
This was a fun one to work on. The code in this post combines and extends upon techniques shown in two earlier posts: one showing how to plot multiple sheets and the other showing how to preview a single-sheet plot.
One of the key differences when plotting or previewing is that while plotting can directly support multiple sheets (assuming the device does so), previewing does not. The good news is that AutoCAD provides you the user interface elements to allow cycling through plots: the user is provided with "Next" and "revious" buttons - it's then up to you to implement the appropriate logic to preview different sheets when the buttons are used.
I chose to use the same helper function for both preview and plot, even though they are a little different in nature. The reason is obvious (to me, at least) - it reduces the amount of code to debug and maintain - but it might, for some, make the code a little less easy to read. Ultimately the trick I used was to reduce the set of sheets being handled at the beginning of the function to a single sheet in the case of a preview, which allowed me to combine both approaches in a single function.
Here's the C# code:
  1. using Autodesk.AutoCAD.Runtime;
  2. using Autodesk.AutoCAD.ApplicationServices;
  3. using Autodesk.AutoCAD.DatabaseServices;
  4. using Autodesk.AutoCAD.EditorInput;
  5. using Autodesk.AutoCAD.PlottingServices;
  6. using System.Collections.Generic;
  7. namespace PlottingApplication
  8. {
  9.   public class PreviewCommands
  10.   {
  11.     [CommandMethod("mprev")]
  12.     static public void MultiSheetPreview()
  13.     {
  14.       Document doc =
  15.         Application.DocumentManager.MdiActiveDocument;
  16.       Editor ed = doc.Editor;
  17.       Database db = doc.Database;
  18.       ObjectIdCollection layoutsToPlot =
  19.         new ObjectIdCollection();
  20.       Transaction tr =
  21.         db.TransactionManager.StartTransaction();
  22.       using (tr)
  23.       {
  24.         // First we need to collect the layouts to
  25.         // plot/preview in tab order
  26.         SortedDictionary<int, ObjectId> layoutDict =
  27.           new SortedDictionary<int, ObjectId>();
  28.         BlockTable bt =
  29.           (BlockTable)tr.GetObject(
  30.             db.BlockTableId,
  31.             OpenMode.ForRead
  32.           );
  33.         foreach (ObjectId btrId in bt)
  34.         {
  35.           BlockTableRecord btr =
  36.             (BlockTableRecord)tr.GetObject(
  37.               btrId,
  38.               OpenMode.ForRead
  39.             );
  40.           if (btr.IsLayout &&
  41.               btr.Name.ToUpper() !=
  42.                 BlockTableRecord.ModelSpace.ToUpper())
  43.           {
  44.             // The dictionary we're using will
  45.             // sort on the tab order of the layout
  46.             Layout lo =
  47.               (Layout)tr.GetObject(
  48.                 btr.LayoutId,
  49.                 OpenMode.ForRead
  50.               );
  51.             layoutDict.Add(lo.TabOrder,btrId);
  52.           }
  53.         }
  54.         // Let's now get the layout IDs and add them to a
  55.         // standard ObjectIdCollection
  56.         SortedDictionary<int,ObjectId>.ValueCollection vc =
  57.           layoutDict.Values;
  58.         foreach (ObjectId id in vc)
  59.         {
  60.           layoutsToPlot.Add(id);
  61.         }
  62.         // Committing is cheaper than aborting
  63.         tr.Commit();
  64.       }
  65.       // PlotEngines do the previewing and plotting
  66.       if (PlotFactory.ProcessPlotState ==
  67.           ProcessPlotState.NotPlotting)
  68.       {
  69.         int layoutNum = 0;
  70.         bool isFinished = false;
  71.         bool isReadyForPlot = false;
  72.         while (!isFinished)
  73.         {
  74.           // Create the preview engine with the appropriate
  75.           // buttons enabled - this depends on which
  76.           // layout in the list is being previewed
  77.           PreviewEngineFlags flags =
  78.             PreviewEngineFlags.Plot;
  79.           if (layoutNum > 0)
  80.             flags |= PreviewEngineFlags.PreviousSheet;
  81.           if (layoutNum < layoutsToPlot.Count - 1)
  82.             flags |= PreviewEngineFlags.NextSheet;
  83.           PlotEngine pre =
  84.             PlotFactory.CreatePreviewEngine((int)flags);
  85.           using (pre)
  86.           {
  87.             PreviewEndPlotStatus stat =
  88.               MultiplePlotOrPreview(
  89.                 pre,
  90.                 true,
  91.                 layoutsToPlot,
  92.                 layoutNum,
  93.                 ""
  94.               );
  95.             // We're not checking the list bounds for
  96.             // next/previous as the buttons are only shown
  97.             // when they can be used
  98.             if (stat == PreviewEndPlotStatus.Next)
  99.             {
  100.               layoutNum++;
  101.             }
  102.             else if (stat == PreviewEndPlotStatus.Previous)
  103.             {
  104.               layoutNum--;
  105.             }
  106.             else if (stat == PreviewEndPlotStatus.Normal ||
  107.                     stat == PreviewEndPlotStatus.Cancel)
  108.             {
  109.               isFinished = true;
  110.             }
  111.             else if (stat == PreviewEndPlotStatus.Plot)
  112.             {
  113.               isFinished = true;
  114.               isReadyForPlot = true;
  115.             }
  116.           }
  117.         }
  118.         // If the plot button was used to exit the preview...
  119.         if (isReadyForPlot)
  120.         {
  121.           PlotEngine ple =
  122.             PlotFactory.CreatePublishEngine();
  123.           using (ple)
  124.           {
  125.             PreviewEndPlotStatus stat =
  126.               MultiplePlotOrPreview(
  127.                 ple,
  128.                 false,
  129.                 layoutsToPlot,
  130.                 -1,
  131.                 "c:\\multisheet-previewed-plot"
  132.               );
  133.           }
  134.         }
  135.       }
  136.       else
  137.       {
  138.         ed.WriteMessage(
  139.           "\nAnother plot is in progress."
  140.         );
  141.       }
  142.     }
  143.     static PreviewEndPlotStatus MultiplePlotOrPreview(
  144.       PlotEngine pe,
  145.       bool isPreview,
  146.       ObjectIdCollection layoutSet,
  147.       int layoutNumIfPreview,
  148.       string filename
  149.     )
  150.     {
  151.       Document doc =
  152.         Application.DocumentManager.MdiActiveDocument;
  153.       Editor ed = doc.Editor;
  154.       Database db = doc.Database;
  155.       PreviewEndPlotStatus ret =
  156.         PreviewEndPlotStatus.Cancel;
  157.       ObjectIdCollection layoutsToPlot;
  158.       if (isPreview && layoutNumIfPreview >= 0)
  159.       {
  160.         // Preview is really pre-sheet, so we reduce the
  161.         // sheet collection to contain the one we want
  162.         layoutsToPlot = new ObjectIdCollection();
  163.         layoutsToPlot.Add(
  164.           layoutSet[layoutNumIfPreview]
  165.         );
  166.       }
  167.       else
  168.       {
  169.         // If we're plotting we need all the sheets,
  170.         // so copy the ObjectIds across
  171.         ObjectId[] ids = new ObjectId[layoutSet.Count];
  172.         layoutSet.CopyTo(ids,0);
  173.         layoutsToPlot = new ObjectIdCollection(ids);
  174.       }
  175.       Transaction tr =
  176.         db.TransactionManager.StartTransaction();
  177.       using (tr)
  178.       {
  179.         // Create a Progress Dialog to provide info
  180.         // and allow thej user to cancel
  181.         PlotProgressDialog ppd =
  182.           new PlotProgressDialog(
  183.             isPreview,
  184.             layoutsToPlot.Count,
  185.             true
  186.           );
  187.         using (ppd)
  188.         {
  189.           int numSheet = 1;
  190.           foreach (ObjectId btrId in layoutsToPlot)
  191.           {
  192.             BlockTableRecord btr =
  193.               (BlockTableRecord)tr.GetObject(
  194.                 btrId,
  195.                 OpenMode.ForRead
  196.               );
  197.             Layout lo =
  198.               (Layout)tr.GetObject(
  199.                 btr.LayoutId,
  200.                 OpenMode.ForRead
  201.               );
  202.             // We need a PlotSettings object
  203.             // based on the layout settings
  204.             // which we then customize
  205.             PlotSettings ps =
  206.               new PlotSettings(lo.ModelType);
  207.             ps.CopyFrom(lo);
  208.             // The PlotSettingsValidator helps
  209.             // create a valid PlotSettings object
  210.             PlotSettingsValidator psv =
  211.               PlotSettingsValidator.Current;
  212.             // We'll plot the extents, centered and
  213.             // scaled to fit
  214.             psv.SetPlotType(
  215.               ps,
  216.               Autodesk.AutoCAD.DatabaseServices.PlotType.Extents
  217.             );
  218.             psv.SetUseStandardScale(ps, true);
  219.             psv.SetStdScaleType(ps, StdScaleType.ScaleToFit);
  220.             psv.SetPlotCentered(ps, true);
  221.             // We'll use the standard DWFx PC3, as
  222.             // this supports multiple sheets
  223.             psv.SetPlotConfigurationName(
  224.               ps,
  225.               "DWFx ePlot (XPS Compatible).pc3",
  226.               "ANSI_A_(8.50_x_11.00_Inches)"
  227.             );
  228.             // We need a PlotInfo object
  229.             // linked to the layout
  230.             PlotInfo pi = new PlotInfo();
  231.             pi.Layout = btr.LayoutId;
  232.             // Make the layout we're plotting current
  233.             LayoutManager.Current.CurrentLayout =
  234.               lo.LayoutName;
  235.             // We need to link the PlotInfo to the
  236.             // PlotSettings and then validate it
  237.             pi.OverrideSettings = ps;
  238.             PlotInfoValidator piv =
  239.               new PlotInfoValidator();
  240.             piv.MediaMatchingPolicy =
  241.               MatchingPolicy.MatchEnabled;
  242.             piv.Validate(pi);
  243.             // We set the sheet name per sheet
  244.             ppd.set_PlotMsgString(
  245.               PlotMessageIndex.SheetName,
  246.               doc.Name.Substring(
  247.                 doc.Name.LastIndexOf("\") + 1
  248.               ) +
  249.               " - " +
  250.               lo.LayoutName
  251.             );
  252.             if (numSheet == 1)
  253.             {
  254.               // All other messages get set once
  255.               ppd.set_PlotMsgString(
  256.                 PlotMessageIndex.DialogTitle,
  257.                 "Custom Preview Progress"
  258.               );
  259.               ppd.set_PlotMsgString(
  260.                 PlotMessageIndex.CancelJobButtonMessage,
  261.                 "Cancel Job"
  262.               );
  263.               ppd.set_PlotMsgString(
  264.                 PlotMessageIndex.CancelSheetButtonMessage,
  265.                 "Cancel Sheet"
  266.               );
  267.               ppd.set_PlotMsgString(
  268.                 PlotMessageIndex.SheetSetProgressCaption,
  269.                 "Sheet Set Progress"
  270.               );
  271.               ppd.set_PlotMsgString(
  272.                 PlotMessageIndex.SheetProgressCaption,
  273.                 "Sheet Progress"
  274.               );
  275.               ppd.LowerPlotProgressRange = 0;
  276.               ppd.UpperPlotProgressRange = 100;
  277.               ppd.PlotProgressPos = 0;
  278.               // Let's start the plot/preview, at last
  279.               ppd.OnBeginPlot();
  280.               ppd.IsVisible = true;
  281.               pe.BeginPlot(ppd, null);
  282.               // We'll be plotting a single document
  283.               pe.BeginDocument(
  284.                 pi,
  285.                 doc.Name,
  286.                 null,
  287.                 1,
  288.                 !isPreview,
  289.                 filename
  290.               );
  291.             }
  292.             // Which may contains multiple sheets
  293.             ppd.LowerSheetProgressRange = 0;
  294.             ppd.UpperSheetProgressRange = 100;
  295.             ppd.SheetProgressPos = 0;
  296.             PlotPageInfo ppi = new PlotPageInfo();
  297.             pe.BeginPage(
  298.               ppi,
  299.               pi,
  300.               (numSheet == layoutsToPlot.Count),
  301.               null
  302.             );
  303.             ppd.OnBeginSheet();
  304.             pe.BeginGenerateGraphics(null);
  305.             ppd.SheetProgressPos = 50;
  306.             pe.EndGenerateGraphics(null);
  307.             // Finish the sheet
  308.             PreviewEndPlotInfo pepi =
  309.               new PreviewEndPlotInfo();
  310.             pe.EndPage(pepi);
  311.             ret = pepi.Status;
  312.             ppd.SheetProgressPos = 100;
  313.             ppd.OnEndSheet();
  314.             numSheet++;
  315.             // Update the overall progress
  316.             ppd.PlotProgressPos +=
  317.               (100 / layoutsToPlot.Count);
  318.           }
  319.           // Finish the document
  320.           pe.EndDocument(null);
  321.           // And finish the plot
  322.           ppd.PlotProgressPos = 100;
  323.           ppd.OnEndPlot();
  324.           pe.EndPlot(null);
  325.         }
  326.       }
  327.       return ret;
  328.     }
  329.   }
  330. }
Here's what you see when you run the MPREV command:

Once you select the plot button, the plot gets driven as before:

本帖子中包含更多资源

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

x
 楼主| 发表于 2009-7-1 17:24 | 显示全部楼层
六、选择打印设备和打印介质
October 09, 2007
Allowing selection of an AutoCAD plot device and media name using .NET
A comment came in on this previous post regarding how best to know whether a media name is valid during your plot configuration.
There are a few approaches, other than the one I chose of hardcoding the device and media names. The first is to implement a user interface of some kind which allows the user to select the device and media names. Another approach for setting the media name is to use PlotSettingsValidator.SetClosestMediaName() to choose the media name that most closely matches the paper size you desire.
Today I'll focus on the first option, although I'm only going to implement a basic, command-line user interface. It should be straightforward to extend this to implement a WinForm with comboboxes for the device and media names.
I implemented a simple function called ChooseDeviceAndMedia() which queries the current device list, allows selection from it, and then gets the media name list and allows selection from that. I chose not to worry about displaying locale-specific names, for now - I'll leave that for a future post (let me know if you're interested :-).
Here's the function integrated into the C# code from this previous post, which defines a command called MPLOT:
  1. using Autodesk.AutoCAD.Runtime;
  2. using Autodesk.AutoCAD.ApplicationServices;
  3. using Autodesk.AutoCAD.DatabaseServices;
  4. using Autodesk.AutoCAD.EditorInput;
  5. using Autodesk.AutoCAD.Geometry;
  6. using Autodesk.AutoCAD.PlottingServices;
  7. using System.Collections.Specialized;
  8. namespace PlottingApplication
  9. {
  10.   public class PlottingCommands
  11.   {
  12.     static public string[] ChooseDeviceAndMedia()
  13.     {
  14.       Document doc =
  15.         Application.DocumentManager.MdiActiveDocument;
  16.       Editor ed = doc.Editor;
  17.       // Assign default return values
  18.       string devname = "", medname = "";
  19.       PlotSettingsValidator psv =
  20.         PlotSettingsValidator.Current;
  21.       // Let's first select the device
  22.       StringCollection devlist =
  23.         psv.GetPlotDeviceList();
  24.       for (int i = 0; i < devlist.Count; i++)
  25.       {
  26.         ed.WriteMessage(
  27.           "\n{0} {1}",
  28.           i + 1,
  29.           devlist[i]
  30.         );
  31.       }
  32.       PromptIntegerOptions opts =
  33.         new PromptIntegerOptions(
  34.           "\nEnter number of device to select: "
  35.         );
  36.       opts.LowerLimit = 1;
  37.       opts.UpperLimit = devlist.Count;
  38.       PromptIntegerResult pir =
  39.         ed.GetInteger(opts);
  40.       if (pir.Status == PromptStatus.OK)
  41.       {
  42.         devname = devlist[pir.Value - 1];
  43.         ed.WriteMessage(
  44.           "\nSelected: {0}\n",
  45.           devname
  46.         );
  47.         // Now let's select the media
  48.         PlotSettings ps = new PlotSettings(true);
  49.         using (ps)
  50.         {
  51.           // We should refresh the lists,
  52.           // in case setting the device impacts
  53.           // the available media
  54.           psv.SetPlotConfigurationName(
  55.             ps,
  56.             devname,
  57.             null
  58.           );
  59.           psv.RefreshLists(ps);
  60.           StringCollection medlist =
  61.             psv.GetCanonicalMediaNameList(ps);
  62.           for (int i = 0; i < medlist.Count; i++)
  63.           {
  64.             ed.WriteMessage(
  65.               "\n{0} {1}",
  66.               i + 1,
  67.               medlist[i]
  68.             );
  69.           }
  70.           opts.Message =
  71.             "\nEnter number of media to select: ";
  72.           opts.LowerLimit = 1;
  73.           opts.UpperLimit = medlist.Count;
  74.           pir = ed.GetInteger(opts);
  75.           if (pir.Status == PromptStatus.OK)
  76.           {
  77.             medname = medlist[pir.Value - 1];
  78.             ed.WriteMessage(
  79.               "\nSelected: {0}\n",
  80.               medname
  81.             );
  82.           }
  83.         }
  84.       }
  85.       return new string[2] { devname, medname };
  86.     }
  87.     [CommandMethod("mplot")]
  88.     static public void MultiSheetPlot()
  89.     {
  90.       Document doc =
  91.         Application.DocumentManager.MdiActiveDocument;
  92.       Editor ed = doc.Editor;
  93.       Database db = doc.Database;
  94.       Transaction tr =
  95.         db.TransactionManager.StartTransaction();
  96.       using (tr)
  97.       {
  98.         BlockTable bt =
  99.           (BlockTable)tr.GetObject(
  100.             db.BlockTableId,
  101.             OpenMode.ForRead
  102.           );
  103.         PlotInfo pi = new PlotInfo();
  104.         PlotInfoValidator piv =
  105.           new PlotInfoValidator();
  106.         piv.MediaMatchingPolicy =
  107.           MatchingPolicy.MatchEnabled;
  108.         // A PlotEngine does the actual plotting
  109.         // (can also create one for Preview)
  110.         if (PlotFactory.ProcessPlotState ==
  111.             ProcessPlotState.NotPlotting)
  112.         {
  113.           string[] devmed = ChooseDeviceAndMedia();
  114.           // Only proceed if we have values for both
  115.           if (devmed[0] != "" && devmed[1] != "")
  116.           {
  117.             string devname = devmed[0];
  118.             string medname = devmed[1];
  119.             PlotEngine pe =
  120.               PlotFactory.CreatePublishEngine();
  121.             using (pe)
  122.             {
  123.               // Collect all the paperspace layouts
  124.               // for plotting
  125.               ObjectIdCollection layoutsToPlot =
  126.                 new ObjectIdCollection();
  127.               foreach (ObjectId btrId in bt)
  128.               {
  129.                 BlockTableRecord btr =
  130.                   (BlockTableRecord)tr.GetObject(
  131.                     btrId,
  132.                     OpenMode.ForRead
  133.                   );
  134.                 if (btr.IsLayout &&
  135.                     btr.Name.ToUpper() !=
  136.                       BlockTableRecord.ModelSpace.ToUpper())
  137.                 {
  138.                   layoutsToPlot.Add(btrId);
  139.                 }
  140.               }
  141.               // Create a Progress Dialog to provide info
  142.               // and allow thej user to cancel
  143.               PlotProgressDialog ppd =
  144.                 new PlotProgressDialog(
  145.                   false,
  146.                   layoutsToPlot.Count,
  147.                   true
  148.                 );
  149.               using (ppd)
  150.               {
  151.                 int numSheet = 1;
  152.                 foreach (ObjectId btrId in layoutsToPlot)
  153.                 {
  154.                   BlockTableRecord btr =
  155.                     (BlockTableRecord)tr.GetObject(
  156.                       btrId,
  157.                       OpenMode.ForRead
  158.                     );
  159.                   Layout lo =
  160.                     (Layout)tr.GetObject(
  161.                       btr.LayoutId,
  162.                       OpenMode.ForRead
  163.                     );
  164.                   // We need a PlotSettings object
  165.                   // based on the layout settings
  166.                   // which we then customize
  167.                   PlotSettings ps =
  168.                     new PlotSettings(lo.ModelType);
  169.                   ps.CopyFrom(lo);
  170.                   // The PlotSettingsValidator helps
  171.                   // create a valid PlotSettings object
  172.                   PlotSettingsValidator psv =
  173.                     PlotSettingsValidator.Current;
  174.                   // We'll plot the extents, centered and
  175.                   // scaled to fit
  176.                   psv.SetPlotType(
  177.                     ps,
  178.                   Autodesk.AutoCAD.DatabaseServices.PlotType.Extents
  179.                   );
  180.                   psv.SetUseStandardScale(ps, true);
  181.                   psv.SetStdScaleType(ps, StdScaleType.ScaleToFit);
  182.                   psv.SetPlotCentered(ps, true);
  183.                   // We'll use the standard DWFx PC3, as
  184.                   // this supports multiple sheets
  185.                   psv.SetPlotConfigurationName(
  186.                     ps,
  187.                     devname,
  188.                     medname
  189.                   );
  190.                   // We need a PlotInfo object
  191.                   // linked to the layout
  192.                   pi.Layout = btr.LayoutId;
  193.                   // Make the layout we're plotting current
  194.                   LayoutManager.Current.CurrentLayout =
  195.                     lo.LayoutName;
  196.                   // We need to link the PlotInfo to the
  197.                   // PlotSettings and then validate it
  198.                   pi.OverrideSettings = ps;
  199.                   piv.Validate(pi);
  200.                   if (numSheet == 1)
  201.                   {
  202.                     ppd.set_PlotMsgString(
  203.                       PlotMessageIndex.DialogTitle,
  204.                       "Custom Plot Progress"
  205.                     );
  206.                     ppd.set_PlotMsgString(
  207.                       PlotMessageIndex.CancelJobButtonMessage,
  208.                       "Cancel Job"
  209.                     );
  210.                     ppd.set_PlotMsgString(
  211.                       PlotMessageIndex.CancelSheetButtonMessage,
  212.                       "Cancel Sheet"
  213.                     );
  214.                     ppd.set_PlotMsgString(
  215.                       PlotMessageIndex.SheetSetProgressCaption,
  216.                       "Sheet Set Progress"
  217.                     );
  218.                     ppd.set_PlotMsgString(
  219.                       PlotMessageIndex.SheetProgressCaption,
  220.                       "Sheet Progress"
  221.                     );
  222.                     ppd.LowerPlotProgressRange = 0;
  223.                     ppd.UpperPlotProgressRange = 100;
  224.                     ppd.PlotProgressPos = 0;
  225.                     // Let's start the plot, at last
  226.                     ppd.OnBeginPlot();
  227.                     ppd.IsVisible = true;
  228.                     pe.BeginPlot(ppd, null);
  229.                     // We'll be plotting a single document
  230.                     pe.BeginDocument(
  231.                       pi,
  232.                       doc.Name,
  233.                       null,
  234.                       1,
  235.                       true, // Let's plot to file
  236.                       "c:\\test-multi-sheet"
  237.                     );
  238.                   }
  239.                   // Which may contains multiple sheets
  240.                   ppd.set_PlotMsgString(
  241.                     PlotMessageIndex.SheetName,
  242.                     doc.Name.Substring(
  243.                       doc.Name.LastIndexOf("\") + 1
  244.                     ) +
  245.                     " - sheet " + numSheet.ToString() +
  246.                     " of " + layoutsToPlot.Count.ToString()
  247.                   );
  248.                   ppd.OnBeginSheet();
  249.                   ppd.LowerSheetProgressRange = 0;
  250.                   ppd.UpperSheetProgressRange = 100;
  251.                   ppd.SheetProgressPos = 0;
  252.                   PlotPageInfo ppi = new PlotPageInfo();
  253.                   pe.BeginPage(
  254.                     ppi,
  255.                     pi,
  256.                     (numSheet == layoutsToPlot.Count),
  257.                     null
  258.                   );
  259.                   pe.BeginGenerateGraphics(null);
  260.                   ppd.SheetProgressPos = 50;
  261.                   pe.EndGenerateGraphics(null);
  262.                   // Finish the sheet
  263.                   pe.EndPage(null);
  264.                   ppd.SheetProgressPos = 100;
  265.                   ppd.OnEndSheet();
  266.                   numSheet++;
  267.                   ppd.PlotProgressPos +=
  268.                     (100 / layoutsToPlot.Count);
  269.                 }
  270.                 // Finish the document
  271.                 pe.EndDocument(null);
  272.                 // And finish the plot
  273.                 ppd.PlotProgressPos = 100;
  274.                 ppd.OnEndPlot();
  275.                 pe.EndPlot(null);
  276.               }
  277.             }
  278.           }
  279.         }
  280.         else
  281.         {
  282.           ed.WriteMessage(
  283.             "\nAnother plot is in progress."
  284.           );
  285.         }
  286.       }
  287.     }
  288.   }
  289. }
Here's what I see at the command-line when I run the MPLOT command on my system (items 7-18 below are network printers in various Autodesk offices):
  1. Command: MPLOT
  2. 1 None
  3. 2 SnagIt 8
  4. 3 PDF-XChange 3.0
  5. 4 Microsoft XPS Document Writer
  6. 5 Microsoft Office Live Meeting Document Writer
  7. 6 Adobe PDF
  8. 7 \\adscctps1\cctprn000
  9. 8 \\adsneups2\neuprn304
  10. 9 \\adsneups2\neuprn306
  11. 10 \\adsneups2\neuprn307
  12. 11 \\adsneups2\neuprn317
  13. 12 \\banhpa001\banprn001
  14. 13 \\beihpa001\BEIPRN002
  15. 14 \\beihpa001\BEIPRN003
  16. 15 \\farhpa001\FARPRN101
  17. 16 \\pra-pc61237\Xerox WorkCentre Pro 35 PCL6
  18. 17 \\tokhpa001\tokprn401
  19. 18 \\tokhpa001\tokprn402
  20. 19 Default Windows System Printer.pc3
  21. 20 DWF6 ePlot.pc3
  22. 21 DWFx ePlot (XPS Compatible).pc3
  23. 22 DWG To PDF.pc3
  24. 23 PublishToWeb JPG.pc3
  25. 24 PublishToWeb PNG.pc3
  26. Enter number of device to select: 22
  27. Selected: DWG To PDF.pc3
  28. 1 ISO_expand_A0_(841.00_x_1189.00_MM)
  29. 2 ISO_A0_(841.00_x_1189.00_MM)
  30. 3 ISO_expand_A1_(841.00_x_594.00_MM)
  31. 4 ISO_expand_A1_(594.00_x_841.00_MM)
  32. 5 ISO_A1_(841.00_x_594.00_MM)
  33. 6 ISO_A1_(594.00_x_841.00_MM)
  34. 7 ISO_expand_A2_(594.00_x_420.00_MM)
  35. 8 ISO_expand_A2_(420.00_x_594.00_MM)
  36. 9 ISO_A2_(594.00_x_420.00_MM)
  37. 10 ISO_A2_(420.00_x_594.00_MM)
  38. 11 ISO_expand_A3_(420.00_x_297.00_MM)
  39. 12 ISO_expand_A3_(297.00_x_420.00_MM)
  40. 13 ISO_A3_(420.00_x_297.00_MM)
  41. 14 ISO_A3_(297.00_x_420.00_MM)
  42. 15 ISO_expand_A4_(297.00_x_210.00_MM)
  43. 16 ISO_expand_A4_(210.00_x_297.00_MM)
  44. 17 ISO_A4_(297.00_x_210.00_MM)
  45. 18 ISO_A4_(210.00_x_297.00_MM)
  46. 19 ARCH_expand_E1_(30.00_x_42.00_Inches)
  47. 20 ARCH_E1_(30.00_x_42.00_Inches)
  48. 21 ARCH_expand_E_(36.00_x_48.00_Inches)
  49. 22 ARCH_E_(36.00_x_48.00_Inches)
  50. 23 ARCH_expand_D_(36.00_x_24.00_Inches)
  51. 24 ARCH_expand_D_(24.00_x_36.00_Inches)
  52. 25 ARCH_D_(36.00_x_24.00_Inches)
  53. 26 ARCH_D_(24.00_x_36.00_Inches)
  54. 27 ARCH_expand_C_(24.00_x_18.00_Inches)
  55. 28 ARCH_expand_C_(18.00_x_24.00_Inches)
  56. 29 ARCH_C_(24.00_x_18.00_Inches)
  57. 30 ARCH_C_(18.00_x_24.00_Inches)
  58. 31 ANSI_expand_E_(34.00_x_44.00_Inches)
  59. 32 ANSI_E_(34.00_x_44.00_Inches)
  60. 33 ANSI_expand_D_(34.00_x_22.00_Inches)
  61. 34 ANSI_expand_D_(22.00_x_34.00_Inches)
  62. 35 ANSI_D_(34.00_x_22.00_Inches)
  63. 36 ANSI_D_(22.00_x_34.00_Inches)
  64. 37 ANSI_expand_C_(22.00_x_17.00_Inches)
  65. 38 ANSI_expand_C_(17.00_x_22.00_Inches)
  66. 39 ANSI_C_(22.00_x_17.00_Inches)
  67. 40 ANSI_C_(17.00_x_22.00_Inches)
  68. 41 ANSI_expand_B_(17.00_x_11.00_Inches)
  69. 42 ANSI_expand_B_(11.00_x_17.00_Inches)
  70. 43 ANSI_B_(17.00_x_11.00_Inches)
  71. 44 ANSI_B_(11.00_x_17.00_Inches)
  72. 45 ANSI_expand_A_(11.00_x_8.50_Inches)
  73. 46 ANSI_expand_A_(8.50_x_11.00_Inches)
  74. 47 ANSI_A_(11.00_x_8.50_Inches)
  75. 48 ANSI_A_(8.50_x_11.00_Inches)
  76. Enter number of media to select: 35
  77. Selected: ANSI_D_(34.00_x_22.00_Inches)
  78. Effective plotting area:  15.29 wide by 20.60 high
  79. Effective plotting area:  13.29 wide by 17.31 high
  80. Plotting viewport 2.
  81. Plotting viewport 1.
  82. Regenerating layout.
  83. Regenerating model.
  84. Effective plotting area:  15.69 wide by 20.60 high
  85. Effective plotting area:  15.69 wide by 20.59 high
  86. Plotting viewport 2.
  87. Plotting viewport 1.
  88. Regenerating layout.
  89. Regenerating model.
  90. Effective plotting area:  15.69 wide by 20.60 high
  91. Effective plotting area:  15.69 wide by 20.59 high
  92. Plotting viewport 2.
  93. Plotting viewport 1.
  94. Regenerating layout.
  95. Regenerating model.
  96. Effective plotting area:  15.69 wide by 20.60 high
  97. Effective plotting area:  14.07 wide by 18.34 high
  98. Plotting viewport 2.
  99. Plotting viewport 1.
  100. Regenerating layout.
  101. Regenerating model.
复制代码
 楼主| 发表于 2009-7-1 17:29 | 显示全部楼层
七、窗选打印
October 11, 2007
Plotting a window from AutoCAD using .NET
This post extends this previous post that dealt with driving a single-sheet AutoCAD plot by adding some code to handle selection and transformation of a window to plot.
First order of business was to allow the user to select the window to plot. For this I used the classic combination of Editor.GetPoint() for the first corner) and Editor.GetCorner() for the second. All well and good, but the points returned by these functions are in UCS (User Coordinate System) coordinates. Which meant that as it stood, the code would work just fine if (and only if) the view we were using to select the window was parallell with the World Coordinate System (and no additional UCS was in place). In order to deal with the very common scenario of either a UCS being used or the current modelspace view being orbited (etc.), we need to transform the current UCS coordinates into DCS, the Display Coordinate System.
Thankfully that's pretty easy: no need for matrices or anything, we simply use another old friend, acedTrans() (the ObjectARX equivalent of the (trans) function, for you LISPers out there). There isn't a direct equivalent for this function in the managed API (that I'm aware of), so we have to use P/Invoke to call the ObjectARX function. The technique is shown in this DevNote, for those of you that have access to the ADN website:
How to call acedTrans from .NET application?
Otherwise the changes to the original code are very minor: we need to set the extents of the window to plot and then set the plot type to "window", apparently in that order. AutoCAD complained when I initially made the calls in the opposite sequence.
Here's the C# code:
  1. using Autodesk.AutoCAD.Runtime;
  2. using Autodesk.AutoCAD.ApplicationServices;
  3. using Autodesk.AutoCAD.DatabaseServices;
  4. using Autodesk.AutoCAD.EditorInput;
  5. using Autodesk.AutoCAD.PlottingServices;
  6. using Autodesk.AutoCAD.Geometry;
  7. using System.Runtime.InteropServices;
  8. using System;
  9. namespace PlottingApplication
  10. {
  11.   public class SimplePlottingCommands
  12.   {
  13.     [DllImport("acad.exe",
  14.               CallingConvention = CallingConvention.Cdecl,
  15.               EntryPoint="acedTrans")
  16.     ]
  17.     static extern int acedTrans(
  18.       double[] point,
  19.       IntPtr fromRb,
  20.       IntPtr toRb,
  21.       int disp,
  22.       double[] result
  23.     );
  24.     [CommandMethod("winplot")]
  25.     static public void WindowPlot()
  26.     {
  27.       Document doc =
  28.         Application.DocumentManager.MdiActiveDocument;
  29.       Editor ed = doc.Editor;
  30.       Database db = doc.Database;
  31.       PromptPointOptions ppo =
  32.         new PromptPointOptions(
  33.           "\nSelect first corner of plot area: "
  34.         );
  35.       ppo.AllowNone = false;
  36.       PromptPointResult ppr =
  37.         ed.GetPoint(ppo);
  38.       if (ppr.Status != PromptStatus.OK)
  39.         return;
  40.       Point3d first = ppr.Value;
  41.       PromptCornerOptions pco =
  42.         new PromptCornerOptions(
  43.           "\nSelect second corner of plot area: ",
  44.           first
  45.         );
  46.       ppr = ed.GetCorner(pco);
  47.       if (ppr.Status != PromptStatus.OK)
  48.         return;
  49.       Point3d second = ppr.Value;
  50.       // Transform from UCS to DCS
  51.       ResultBuffer rbFrom =
  52.         new ResultBuffer(new TypedValue(5003, 1)),
  53.                   rbTo =
  54.         new ResultBuffer(new TypedValue(5003, 2));
  55.       double[] firres = new double[] { 0, 0, 0 };
  56.       double[] secres = new double[] { 0, 0, 0 };
  57.       // Transform the first point...
  58.       acedTrans(
  59.         first.ToArray(),
  60.         rbFrom.UnmanagedObject,
  61.         rbTo.UnmanagedObject,
  62.         0,
  63.         firres
  64.       );
  65.       // ... and the second
  66.       acedTrans(
  67.         second.ToArray(),
  68.         rbFrom.UnmanagedObject,
  69.         rbTo.UnmanagedObject,
  70.         0,
  71.         secres
  72.       );
  73.       // We can safely drop the Z-coord at this stage
  74.       Extents2d window =
  75.         new Extents2d(
  76.           firres[0],
  77.           firres[1],
  78.           secres[0],
  79.           secres[1]
  80.         );
  81.       Transaction tr =
  82.         db.TransactionManager.StartTransaction();
  83.       using (tr)
  84.       {
  85.         // We'll be plotting the current layout
  86.         BlockTableRecord btr =
  87.           (BlockTableRecord)tr.GetObject(
  88.             db.CurrentSpaceId,
  89.             OpenMode.ForRead
  90.           );
  91.         Layout lo =
  92.           (Layout)tr.GetObject(
  93.             btr.LayoutId,
  94.             OpenMode.ForRead
  95.           );
  96.         // We need a PlotInfo object
  97.         // linked to the layout
  98.         PlotInfo pi = new PlotInfo();
  99.         pi.Layout = btr.LayoutId;
  100.         // We need a PlotSettings object
  101.         // based on the layout settings
  102.         // which we then customize
  103.         PlotSettings ps =
  104.           new PlotSettings(lo.ModelType);
  105.         ps.CopyFrom(lo);
  106.         // The PlotSettingsValidator helps
  107.         // create a valid PlotSettings object
  108.         PlotSettingsValidator psv =
  109.           PlotSettingsValidator.Current;
  110.         // We'll plot the extents, centered and
  111.         // scaled to fit
  112.         psv.SetPlotWindowArea(ps, window);
  113.         psv.SetPlotType(
  114.           ps,
  115.         Autodesk.AutoCAD.DatabaseServices.PlotType.Window
  116.         );
  117.         psv.SetUseStandardScale(ps, true);
  118.         psv.SetStdScaleType(ps, StdScaleType.ScaleToFit);
  119.         psv.SetPlotCentered(ps, true);
  120.         // We'll use the standard DWF PC3, as
  121.         // for today we're just plotting to file
  122.         psv.SetPlotConfigurationName(
  123.           ps,
  124.           "DWF6 ePlot.pc3",
  125.           "ANSI_A_(8.50_x_11.00_Inches)"
  126.         );
  127.         // We need to link the PlotInfo to the
  128.         // PlotSettings and then validate it
  129.         pi.OverrideSettings = ps;
  130.         PlotInfoValidator piv =
  131.           new PlotInfoValidator();
  132.         piv.MediaMatchingPolicy =
  133.           MatchingPolicy.MatchEnabled;
  134.         piv.Validate(pi);
  135.         // A PlotEngine does the actual plotting
  136.         // (can also create one for Preview)
  137.         if (PlotFactory.ProcessPlotState ==
  138.             ProcessPlotState.NotPlotting)
  139.         {
  140.           PlotEngine pe =
  141.             PlotFactory.CreatePublishEngine();
  142.           using (pe)
  143.           {
  144.             // Create a Progress Dialog to provide info
  145.             // and allow thej user to cancel
  146.             PlotProgressDialog ppd =
  147.               new PlotProgressDialog(false, 1, true);
  148.             using (ppd)
  149.             {
  150.               ppd.set_PlotMsgString(
  151.                 PlotMessageIndex.DialogTitle,
  152.                 "Custom Plot Progress"
  153.               );
  154.               ppd.set_PlotMsgString(
  155.                 PlotMessageIndex.CancelJobButtonMessage,
  156.                 "Cancel Job"
  157.               );
  158.               ppd.set_PlotMsgString(
  159.                 PlotMessageIndex.CancelSheetButtonMessage,
  160.                 "Cancel Sheet"
  161.               );
  162.               ppd.set_PlotMsgString(
  163.                 PlotMessageIndex.SheetSetProgressCaption,
  164.                 "Sheet Set Progress"
  165.               );
  166.               ppd.set_PlotMsgString(
  167.                 PlotMessageIndex.SheetProgressCaption,
  168.                 "Sheet Progress"
  169.               );
  170.               ppd.LowerPlotProgressRange = 0;
  171.               ppd.UpperPlotProgressRange = 100;
  172.               ppd.PlotProgressPos = 0;
  173.               // Let's start the plot, at last
  174.               ppd.OnBeginPlot();
  175.               ppd.IsVisible = true;
  176.               pe.BeginPlot(ppd, null);
  177.               // We'll be plotting a single document
  178.               pe.BeginDocument(
  179.                 pi,
  180.                 doc.Name,
  181.                 null,
  182.                 1,
  183.                 true, // Let's plot to file
  184.                 "c:\\test-output"
  185.               );
  186.               // Which contains a single sheet
  187.               ppd.OnBeginSheet();
  188.               ppd.LowerSheetProgressRange = 0;
  189.               ppd.UpperSheetProgressRange = 100;
  190.               ppd.SheetProgressPos = 0;
  191.               PlotPageInfo ppi = new PlotPageInfo();
  192.               pe.BeginPage(
  193.                 ppi,
  194.                 pi,
  195.                 true,
  196.                 null
  197.               );
  198.               pe.BeginGenerateGraphics(null);
  199.               pe.EndGenerateGraphics(null);
  200.               // Finish the sheet
  201.               pe.EndPage(null);
  202.               ppd.SheetProgressPos = 100;
  203.               ppd.OnEndSheet();
  204.               // Finish the document
  205.               pe.EndDocument(null);
  206.               // And finish the plot
  207.               ppd.PlotProgressPos = 100;
  208.               ppd.OnEndPlot();
  209.               pe.EndPlot(null);
  210.             }
  211.           }
  212.         }
  213.         else
  214.         {
  215.           ed.WriteMessage(
  216.             "\nAnother plot is in progress."
  217.           );
  218.         }
  219.       }
  220.     }
  221.   }
  222. }
发表于 2015-12-9 23:41 | 显示全部楼层
有翻译过来的么,看着眼晕
发表于 2017-12-2 14:20 | 显示全部楼层
有自定义图幅的方法吗?
发表于 2019-1-23 09:24 | 显示全部楼层
打印预览有没有调过了的?为啥一直卡在预览界面?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-3-29 21:33 , Processed in 0.337094 second(s), 26 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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