求助!ARX2020打印问题
本帖最后由 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,即使手动先打印一次程序也是一闪而过,而且不报错。何解????
Acad::ErrorStatus es;
AcAxDocLock lock;
AcDbPlotSettingsValidator* pPSV = (AcDbPlotSettingsValidator*)acdbHostApplicationServices()->plotSettingsValidator();
AcDbLayoutManager *pLayoutManager = acdbHostApplicationServices()->layoutManager();
AcDbObjectId btrId = pLayoutManager->getActiveLayoutBTRId();
AcDbBlockTableRecord *pBTR;
es = acdbOpenObject(pBTR, btrId, AcDb::kForRead);
AcDbObjectId layoutId = pBTR->getLayoutId();
AcDbLayout *pLayout = NULL;
acdbOpenObject(pLayout, layoutId, AcDb::kForRead);
AcDbPlotSettings *pPlotSettings = NULL;
#pragma warning (disable: 4800)
pPlotSettings = new AcDbPlotSettings(pLayout->modelType());
#pragma warning (default: 4800)
pPlotSettings->copyFrom(pLayout);
pLayout->close();
pBTR->close();
// 打印机设置
ACHAR* sDevice = _T("DWG To PDF.pc3");
es = pPSV->setPlotCfgName(pPlotSettings, sDevice);
// 图纸名称
ACHAR* sMediaName = _T("ISO_A4_(210.00_x_297.00_MM)");
pPSV->setCanonicalMediaName(pPlotSettings, sMediaName);
// 设置打印样式表
pPSV->setCurrentStyleSheet(pPlotSettings, _T("monochrome.ctb"));
// 设置方向
pPSV->setPlotRotation(pPlotSettings, AcDbPlotSettings::k90degrees);
// 设置绘制范围为打印区域
es = pPSV->setPlotType(pPlotSettings, AcDbPlotSettings::kExtents);
// 使用使用标准比例为绘图比例
es = pPSV->setUseStandardScale(pPlotSettings, Adesk::kTrue);
// 布满
es = pPSV->setStdScaleType(pPlotSettings, AcDbPlotSettings::kScaleToFit);
// 设置绘图是否居中(true为居中)
es = pPSV->setPlotCentered(pPlotSettings, true);
// 设置绘图单位(以毫米为单位绘图)
es = pPSV->setPlotPaperUnits(pPlotSettings, AcDbPlotSettings::kMillimeters);
// 创建用于绘制到设备(或文件)的引擎
AcPlPlotEngine* pEngine = NULL;
if (Acad::eOk == AcPlPlotFactory::createPublishEngine(pEngine))
{
// 创建单页或多页打印进度对话框
AcPlPlotProgressDialog *pPlotProgDlg = acplCreatePlotProgressDialog(acedGetAcadFrame()->m_hWnd, false, 1);
// 创建的绘图进度对话框的不同UI控件中显示的字符串
pPlotProgDlg->setPlotMsgString(AcPlPlotProgressDialog::kDialogTitle, _T("Plot 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);
// 绘图引擎开始
es = pEngine->beginPlot(pPlotProgDlg);
// 绘制页面
AcPlPlotPageInfo pageInfo;
// 构建有关绘制方式和内容信息类
AcPlPlotInfo plotInfo;
// 将布局设置为指定的布局(必需的)
plotInfo.setLayout(layoutId);
// AcDbPlotSettings对象以代替布局上的设置
plotInfo.setOverrideSettings(pPlotSettings);
// 验证设置
AcPlPlotInfoValidator validator;
// 验证介质大小
validator.setMediaMatchingPolicy(AcPlPlotInfoValidator::kMatchEnabled);
// 布局验证
es = validator.validate(plotInfo);
// 当前文档的文件
const TCHAR *szDocName = acDocManager->curDocument()->fileName();
// 打印至文件
es = pEngine->beginDocument(plotInfo, szDocName, NULL, 1, true, _T("D:\\Test.pdf"));
// 继续向引擎发送命令,并向进度对话框发送通知.
pPlotProgDlg->onBeginSheet();
pPlotProgDlg->setSheetProgressRange(0, 100);
pPlotProgDlg->setSheetProgressPos(0);
// 页面信息的引用(布局必须处于活动状态)
es = pEngine->beginPage(pageInfo, plotInfo, true);
// 生成页面图形
es = pEngine->beginGenerateGraphics();
es = pEngine->endGenerateGraphics();
// 关闭页面信息的引用
es = pEngine->endPage();
// 关闭进度对话框
pPlotProgDlg->setSheetProgressPos(100);
pPlotProgDlg->onEndSheet();
pPlotProgDlg->setPlotProgressPos(100);
// 关闭绘图引擎
es = pEngine->endDocument();
es = pEngine->endPlot();
// 销毁绘图引擎
pEngine->destroy();
pEngine = NULL;
// 销毁进度对话框
pPlotProgDlg->destroy();
delete pPlotSettings;
}
gzxl 发表于 2020-2-28 18:33
好东西,你值得拥有!!!!! gzxl 发表于 2020-2-28 18:33
非常感谢提供解答!你的程序有几个值得参考的地方!非常值得学习!
昨天下午我自己改了几个地方后也能正常运行,完整代码如下:红色字就是改动的地方.还有一点程序里没有标成红色的内容是,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();
//////////////////////////////////////////////////////////////////////////
} 补充一点,//打开布局要改为
AcDbObjectPointer<AcDbLayout> pLayout(m_layoutId, AcDb::kForWrite);//如果用kForRead会报错 学习中,一直搞不定 谢谢分享,学习一下
页:
[1]