明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 946|回复: 6

求助!ARX2020打印问题

[复制链接]
发表于 2020-2-28 10:54 | 显示全部楼层 |阅读模式
本帖最后由 wjf83223 于 2020-2-28 10:54 编辑

static void test(void)
        {
                //////////////////////////////////////////////////////////////////////////
                //批量打印
            // 取得当前布局layoutId
                AcDbLayoutManager *pLayoutManager = acdbHostApplicationServices()->layoutManager(); //取得布局管理器对象
                AcDbObjectId m_layoutId = pLayoutManager->findLayoutNamed(pLayoutManager->findActiveLayout(TRUE), NULL);////获得布局的Id
                //打开布局
                AcDbObjectPointer<AcDbLayout> pLayout(m_layoutId, AcDb::kForRead);
                //获得打印机验证器对象
                AcDbPlotSettingsValidator *pPSV = acdbHostApplicationServices()->plotSettingsValidator();
                //更新打印设备列表
                AcDbPlotSettings* pPlotSet = new AcDbPlotSettings;
                pPSV->refreshLists(pPlotSet);
                //delete pPlotSet;
                //打印机设置
                ACHAR* m_strDevice = _T("pdfFactory Pro");//打印机名字
                pPSV->setPlotCfgName(pLayout, m_strDevice);//设置打印设备
                ACHAR* m_mediaName = _T("ISO A4");//图纸名称
                pPSV->setCanonicalMediaName(pLayout, m_mediaName);//设置图纸尺寸
                pPSV->setPlotType(pLayout, AcDbPlotSettings::kWindow);//设置打印范围为窗口
                pPSV->setPlotWindowArea(pLayout, 0, 0, 210, 297);//设置打印范围,超出给范围的将打不出来
               

                pPSV->setCurrentStyleSheet(pLayout, _T("acad.ctb"));//设置打印样式表
                pPSV->setPlotCentered(pLayout, true);//是否居中打印
                pPSV->setUseStandardScale(pLayout, true);//设置是否采用标准比例
                pPSV->setStdScaleType(pLayout, AcDbPlotSettings::kScaleToFit);//布满图纸               
                pPSV->setPlotRotation(pLayout, AcDbPlotSettings::k90degrees);//设置打印方向


                //pPSV->setPlotViewName(pLayout, _T("打印1"));

                //准备打印/////////////////////////////////////////////////////////////////////////
                AcPlPlotEngine* pEngine = NULL;//创建打印引擎
                if (AcPlPlotFactory::createPublishEngine(pEngine) != Acad::eOk)
                {
                        acedAlert(_T("打印失败!"));
                        return;
                }
                Acad::ErrorStatus es;
                // 打印进度对话框
                AcPlPlotProgressDialog *pPlotProgDlg = acplCreatePlotProgressDialog(acedGetAcadFrame()->m_hWnd, false, 1);
                pPlotProgDlg->setPlotMsgString(AcPlPlotProgressDialog::kDialogTitle, _T("lot API Progress"));
                pPlotProgDlg->setPlotMsgString(AcPlPlotProgressDialog::kCancelJobBtnMsg, _T("Cancel Job"));
                pPlotProgDlg->setPlotMsgString(AcPlPlotProgressDialog::kCancelSheetBtnMsg, _T("Cancel Sheet"));
                pPlotProgDlg->setPlotMsgString(AcPlPlotProgressDialog::kSheetSetProgressCaption, _T("Job Progress"));
                pPlotProgDlg->setPlotMsgString(AcPlPlotProgressDialog::kSheetProgressCaption, _T("Sheet Progress"));
                pPlotProgDlg->setPlotProgressRange(0, 100);
                pPlotProgDlg->onBeginPlot();
                pPlotProgDlg->setIsVisible(true);
                //begin plot
                es = pEngine->beginPlot(pPlotProgDlg);
                AcPlPlotPageInfo pageInfo;//打印页信息
                AcPlPlotInfo plotInfo; //打印信息
                // 设置布局
                plotInfo.setLayout(m_layoutId);
                // 重置参数
                plotInfo.setOverrideSettings(pLayout);
                AcPlPlotInfoValidator validator;//创建打印信息验证器
                validator.setMediaMatchingPolicy(AcPlPlotInfoValidator::kMatchEnabled);
                es = validator.validate(plotInfo);
                // begin document
                const TCHAR *szDocName = acDocManager->curDocument()->fileName();//获得当前的文件名

                //最后一个参数需要传入文件名
                es = pEngine->beginDocument(plotInfo, szDocName, NULL, 1, true, _T("D:\\test_result.pdf"));
                //给打印机和进度对话框发送消息
                pPlotProgDlg->onBeginSheet();
                pPlotProgDlg->setSheetProgressRange(0, 100);
                pPlotProgDlg->setSheetProgressPos(0);
                //begin page
                es = pEngine->beginPage(pageInfo, plotInfo, true);
                es = pEngine->beginGenerateGraphics();
                es = pEngine->endGenerateGraphics();
                //end page
                es = pEngine->endPage();
                pPlotProgDlg->setSheetProgressPos(100);
                pPlotProgDlg->onEndSheet();
                pPlotProgDlg->setPlotProgressPos(100);
                //end document
                es = pEngine->endDocument();
                //end plot
                es = pEngine->endPlot();
                //返回资源
                pEngine->destroy();
                pEngine = NULL;
                pPlotProgDlg->destroy();
                //////////////////////////////////////////////////////////////////////////
        }

这是网上的一个打印例子,我修改了一下可以在ARX2020里编译运行,但必须要自己先打印一次,程序才运行出结果。否则程序一闪而过打印不出来,而且并不报错。我猜测可能是一些必要的参数我程序里没有设置到,所以要手动先打印一次,CAD系统里把必要参数都设置了,然后我程序就能正常运行了,但找了几天都没找到哪些参数是非设不可的,故发贴求助,请各位大神帮忙,先谢谢啦!
另外,我发现一个很奇怪的地方
箭头所指的地方,ARX2020版的帮助说明里应该传入AcDbPlotSettings* pPlotSet才对,如果传入AcDbPlotSettings* pPlotSet,即使手动先打印一次程序也是一闪而过,而且不报错。何解????


本帖子中包含更多资源

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

x
发表于 2020-2-28 18:33 | 显示全部楼层
  1. Acad::ErrorStatus es;
  2. AcAxDocLock lock;
  3. AcDbPlotSettingsValidator* pPSV = (AcDbPlotSettingsValidator*)acdbHostApplicationServices()->plotSettingsValidator();
  4. AcDbLayoutManager *pLayoutManager = acdbHostApplicationServices()->layoutManager();
  5. AcDbObjectId btrId = pLayoutManager->getActiveLayoutBTRId();
  6. AcDbBlockTableRecord *pBTR;
  7. es = acdbOpenObject(pBTR, btrId, AcDb::kForRead);
  8. AcDbObjectId layoutId = pBTR->getLayoutId();
  9. AcDbLayout *pLayout = NULL;
  10. acdbOpenObject(pLayout, layoutId, AcDb::kForRead);
  11. AcDbPlotSettings *pPlotSettings = NULL;
  12. #pragma warning (disable: 4800)
  13. pPlotSettings = new AcDbPlotSettings(pLayout->modelType());
  14. #pragma warning (default: 4800)
  15. pPlotSettings->copyFrom(pLayout);
  16. pLayout->close();
  17. pBTR->close();

  18. // 打印机设置
  19. ACHAR* sDevice = _T("DWG To PDF.pc3");
  20. es = pPSV->setPlotCfgName(pPlotSettings, sDevice);
  21. // 图纸名称
  22. ACHAR* sMediaName = _T("ISO_A4_(210.00_x_297.00_MM)");
  23. pPSV->setCanonicalMediaName(pPlotSettings, sMediaName);
  24. // 设置打印样式表
  25. pPSV->setCurrentStyleSheet(pPlotSettings, _T("monochrome.ctb"));
  26. // 设置方向
  27. pPSV->setPlotRotation(pPlotSettings, AcDbPlotSettings::k90degrees);
  28. // 设置绘制范围为打印区域
  29. es = pPSV->setPlotType(pPlotSettings, AcDbPlotSettings::kExtents);
  30. // 使用使用标准比例为绘图比例
  31. es = pPSV->setUseStandardScale(pPlotSettings, Adesk::kTrue);
  32. // 布满
  33. es = pPSV->setStdScaleType(pPlotSettings, AcDbPlotSettings::kScaleToFit);
  34. // 设置绘图是否居中(true为居中)
  35. es = pPSV->setPlotCentered(pPlotSettings, true);
  36. // 设置绘图单位(以毫米为单位绘图)
  37. es = pPSV->setPlotPaperUnits(pPlotSettings, AcDbPlotSettings::kMillimeters);
  38. // 创建用于绘制到设备(或文件)的引擎
  39. AcPlPlotEngine* pEngine = NULL;
  40. if (Acad::eOk == AcPlPlotFactory::createPublishEngine(pEngine))
  41. {
  42.     // 创建单页或多页打印进度对话框
  43.     AcPlPlotProgressDialog *pPlotProgDlg = acplCreatePlotProgressDialog(acedGetAcadFrame()->m_hWnd, false, 1);
  44.     // 创建的绘图进度对话框的不同UI控件中显示的字符串
  45.     pPlotProgDlg->setPlotMsgString(AcPlPlotProgressDialog::kDialogTitle, _T("Plot API Progress"));
  46.     pPlotProgDlg->setPlotMsgString(AcPlPlotProgressDialog::kCancelJobBtnMsg, _T("Cancel Job"));
  47.     pPlotProgDlg->setPlotMsgString(AcPlPlotProgressDialog::kCancelSheetBtnMsg, _T("Cancel Sheet"));
  48.     pPlotProgDlg->setPlotMsgString(AcPlPlotProgressDialog::kSheetSetProgressCaption, _T("Job Progress"));
  49.     pPlotProgDlg->setPlotMsgString(AcPlPlotProgressDialog::kSheetProgressCaption, _T("Sheet Progress"));
  50.     // 绘图进度范围的下限和上限
  51.     pPlotProgDlg->setPlotProgressRange(0, 100);
  52.     // 开始绘图通知是否成功
  53.     pPlotProgDlg->onBeginPlot();
  54.     // 绘图进度对话框可见
  55.     pPlotProgDlg->setIsVisible(true);
  56.     // 绘图引擎开始
  57.     es = pEngine->beginPlot(pPlotProgDlg);
  58.     // 绘制页面
  59.     AcPlPlotPageInfo pageInfo;
  60.     // 构建有关绘制方式和内容信息类
  61.     AcPlPlotInfo plotInfo;
  62.     // 将布局设置为指定的布局(必需的)
  63.     plotInfo.setLayout(layoutId);
  64.     // AcDbPlotSettings对象以代替布局上的设置
  65.     plotInfo.setOverrideSettings(pPlotSettings);
  66.     // 验证设置
  67.     AcPlPlotInfoValidator validator;
  68.     // 验证介质大小
  69.     validator.setMediaMatchingPolicy(AcPlPlotInfoValidator::kMatchEnabled);
  70.     // 布局验证
  71.     es = validator.validate(plotInfo);
  72.     // 当前文档的文件
  73.     const TCHAR *szDocName = acDocManager->curDocument()->fileName();
  74.     // 打印至文件
  75.     es = pEngine->beginDocument(plotInfo, szDocName, NULL, 1, true, _T("D:\\Test.pdf"));
  76.     // 继续向引擎发送命令,并向进度对话框发送通知.
  77.     pPlotProgDlg->onBeginSheet();
  78.     pPlotProgDlg->setSheetProgressRange(0, 100);
  79.     pPlotProgDlg->setSheetProgressPos(0);
  80.     // 页面信息的引用(布局必须处于活动状态)
  81.     es = pEngine->beginPage(pageInfo, plotInfo, true);
  82.     // 生成页面图形
  83.     es = pEngine->beginGenerateGraphics();
  84.     es = pEngine->endGenerateGraphics();
  85.     // 关闭页面信息的引用
  86.     es = pEngine->endPage();
  87.     // 关闭进度对话框
  88.     pPlotProgDlg->setSheetProgressPos(100);
  89.     pPlotProgDlg->onEndSheet();
  90.     pPlotProgDlg->setPlotProgressPos(100);
  91.     // 关闭绘图引擎
  92.     es = pEngine->endDocument();
  93.     es = pEngine->endPlot();
  94.     // 销毁绘图引擎
  95.     pEngine->destroy();
  96.     pEngine = NULL;
  97.     // 销毁进度对话框
  98.     pPlotProgDlg->destroy();
  99.     delete pPlotSettings;
  100. }
复制代码


回复 支持 1 反对 0

使用道具 举报

发表于 2020-2-28 19:52 | 显示全部楼层

好东西,你值得拥有!!!!!
 楼主| 发表于 2020-2-29 10:36 | 显示全部楼层

非常感谢提供解答!你的程序有几个值得参考的地方!非常值得学习!
昨天下午我自己改了几个地方后也能正常运行,完整代码如下:红色字就是改动的地方.还有一点程序里没有标成红色的内容是,CAD官方说明里,页面设置函数传入的是 AcDbPlotSettings* pPlotSet,如果传入pLayout程序也能运行,如果改成pPlotSet当然也没问题,只是在网页里不好标成红色字,所以以说明形式表达。


static void test(void)
        {
                //////////////////////////////////////////////////////////////////////////
                //批量打印
            // 取得当前布局layoutId
                AcDbLayoutManager *pLayoutManager = acdbHostApplicationServices()->layoutManager(); //取得布局管理器对象
                AcDbObjectId m_layoutId = pLayoutManager->findLayoutNamed(pLayoutManager->findActiveLayout(TRUE), NULL);////获得布局的Id
                //打开布局
                AcDbObjectPointer<AcDbLayout> pLayout(m_layoutId, AcDb::kForRead);
                //获得打印机验证器对象
                AcDbPlotSettingsValidator *pPSV = acdbHostApplicationServices()->plotSettingsValidator();
                //更新打印设备列表
                AcDbPlotSettings* pPlotSet = (AcDbPlotSettings*)pLayout;
                pPSV->refreshLists(pPlotSet);
                //delete pPlotSet;
                //打印机设置
                ACHAR* m_strDevice = _T("pdfFactory Pro");//打印机名字
                pPSV->setPlotCfgName(pLayout, m_strDevice);//设置打印设备
                ACHAR* m_mediaName = _T("ISO A4");//图纸名称
                pPSV->setCanonicalMediaName(pLayout, m_mediaName);//设置图纸尺寸
            
                pPSV->setPlotWindowArea(pLayout, 0, 0, 210, 297);//顺序1,设置打印范围,超出给范围的将打不出来
                pPSV->setPlotOrigin(pPlotSettings, 0, 0);//顺序2
                pPSV->setPlotType(pLayout, AcDbPlotSettings::kWindow);//顺序3,设置打印范围为窗口


                pPSV->setCurrentStyleSheet(pLayout, _T("acad.ctb"));//设置打印样式表
                pPSV->setPlotCentered(pLayout, true);//是否居中打印
                pPSV->setUseStandardScale(pLayout, true);//设置是否采用标准比例
                pPSV->setStdScaleType(pLayout, AcDbPlotSettings::kScaleToFit);//布满图纸               
                pPSV->setPlotRotation(pLayout, AcDbPlotSettings::k90degrees);//设置打印方向


                //pPSV->setPlotViewName(pLayout, _T("打印1"));
                pLayout->close();//此句必须保留,否则程序一闪而过而且不报错
                //准备打印/////////////////////////////////////////////////////////////////////////
                AcPlPlotEngine* pEngine = NULL;//创建打印引擎
                if (AcPlPlotFactory::createPublishEngine(pEngine) != Acad::eOk)
                {
                        acedAlert(_T("打印失败!"));
                        return;
                }
                Acad::ErrorStatus es;
                // 打印进度对话框
                AcPlPlotProgressDialog *pPlotProgDlg = acplCreatePlotProgressDialog(acedGetAcadFrame()->m_hWnd, false, 1);
                pPlotProgDlg->setPlotMsgString(AcPlPlotProgressDialog::kDialogTitle, _T("lot API Progress"));
                pPlotProgDlg->setPlotMsgString(AcPlPlotProgressDialog::kCancelJobBtnMsg, _T("Cancel Job"));
                pPlotProgDlg->setPlotMsgString(AcPlPlotProgressDialog::kCancelSheetBtnMsg, _T("Cancel Sheet"));
                pPlotProgDlg->setPlotMsgString(AcPlPlotProgressDialog::kSheetSetProgressCaption, _T("Job Progress"));
                pPlotProgDlg->setPlotMsgString(AcPlPlotProgressDialog::kSheetProgressCaption, _T("Sheet Progress"));
                pPlotProgDlg->setPlotProgressRange(0, 100);
                pPlotProgDlg->onBeginPlot();
                pPlotProgDlg->setIsVisible(true);
                //begin plot
                es = pEngine->beginPlot(pPlotProgDlg);
                AcPlPlotPageInfo pageInfo;//打印页信息
                AcPlPlotInfo plotInfo; //打印信息
                // 设置布局
                plotInfo.setLayout(m_layoutId);
                // 重置参数
                plotInfo.setOverrideSettings(pLayout);
                AcPlPlotInfoValidator validator;//创建打印信息验证器
                validator.setMediaMatchingPolicy(AcPlPlotInfoValidator::kMatchEnabled);
                es = validator.validate(plotInfo);
                // begin document
                const TCHAR *szDocName = acDocManager->curDocument()->fileName();//获得当前的文件名

                //最后一个参数需要传入文件名
                es = pEngine->beginDocument(plotInfo, szDocName, NULL, 1, true, _T("D:\\test_result.pdf"));
                //给打印机和进度对话框发送消息
                pPlotProgDlg->onBeginSheet();
                pPlotProgDlg->setSheetProgressRange(0, 100);
                pPlotProgDlg->setSheetProgressPos(0);
                //begin page
                es = pEngine->beginPage(pageInfo, plotInfo, true);
                es = pEngine->beginGenerateGraphics();
                es = pEngine->endGenerateGraphics();
                //end page
                es = pEngine->endPage();
                pPlotProgDlg->setSheetProgressPos(100);
                pPlotProgDlg->onEndSheet();
                pPlotProgDlg->setPlotProgressPos(100);
                //end document
                es = pEngine->endDocument();
                //end plot
                es = pEngine->endPlot();
                //返回资源
                pEngine->destroy();
                pEngine = NULL;
                pPlotProgDlg->destroy();
                //////////////////////////////////////////////////////////////////////////
        }
 楼主| 发表于 2020-2-29 10:42 | 显示全部楼层
补充一点,//打开布局要改为
AcDbObjectPointer<AcDbLayout> pLayout(m_layoutId, AcDb::kForWrite);//如果用kForRead会报错
发表于 2023-6-7 10:49 | 显示全部楼层
学习中,一直搞不定
发表于 2023-6-8 08:49 | 显示全部楼层
谢谢分享,学习一下
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-5-3 13:48 , Processed in 0.342244 second(s), 25 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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