Win32 PrintDlg、PrintDlgEx、崩溃和古怪
Posted
技术标签:
【中文标题】Win32 PrintDlg、PrintDlgEx、崩溃和古怪【英文标题】:Win32 PrintDlg, PrintDlgEx, Crashing and quirkiness 【发布时间】:2011-09-11 22:18:21 【问题描述】:我的任务是解决以下问题:当调用PrintDlg() 函数时,我的应用程序在 64 位机器上运行时崩溃。
在挖掘和拉扯头发之后,我决定最好的解决方案是将 PrintDlg() 的原始调用替换为它的大哥PrintDlgEx()。
这样做可以解决一个问题(它不再崩溃!),但会导致另一个问题。当我执行代码时,它不显示打印对话框,只是返回一个成功代码,并为我提供默认打印机的所有信息。我需要这个功能来显示标准的“打印设置”窗口,我不知道它是如何实现的。下面显示的是我试图用来显示我的对话框的示例值。
有什么想法吗?提前致谢。
// Initialize the PRINTDLGEX structure.
pd2.lStructSize = sizeof(PRINTDLGEX);
pd2.hwndOwner = wnddata->wnd.hnd;
pd2.hDevMode = NULL;
pd2.hDevNames = NULL;
pd2.hDC = NULL;
pd2.Flags = PD_RETURNDC | PD_COLLATE;
pd2.Flags2 = 0;
pd2.ExclusionFlags = 0;
pd2.nPageRanges = 0;
pd2.nMaxPageRanges = 10;
pd2.lpPageRanges = NULL;
pd2.nMinPage = 1;
pd2.nMaxPage = 1000;
pd2.nCopies = 1;
pd2.hInstance = 0;
pd2.lpPrintTemplateName = NULL;
pd2.lpCallback = NULL;
pd2.nPropertyPages = 0;
pd2.lphpropertyPages = NULL;
pd2.nStartPage = START_PAGE_GENERAL;
pd2.dwResultAction = 0;
pdrc = PrintDlgEx (&pd2);
【问题讨论】:
PrintDlgEx
的返回值是多少?
这是一个负值,我正在测试一种解决方法;如果它不起作用,我会将代码放回原处并获取确切的数字。
负 HRESULT 返回码是失败,而不是成功。
为什么不修复对 PrintDlg 的调用?
对 PrintDlg 的调用与它一直以来的代码相同。在我的 64 位机器上,当您调用它时,它只会出现段错误(这是新的,我们“相信”根本原因是我们的应用程序有一个不同的入口点,这会出于某种随机原因将扳手扔进打印中)。在查看了 PrintDlg 的文档后,它说“使用 PrintDlgEx ... 更好”。现在使用 PrintDlgEx 确实没有崩溃,这是一个很大的改进。我只需要弄清楚如何让对话框显示
【参考方案1】:
由于未能读取PRINTDLGEX 结构上的细则,您很可能会收到 E_INVALIDARG 的返回代码。具体来说,它表示“如果未指定 PD_NOPAGENUMS 标志,则 lpPageRanges 必须为非 NULL。”
PrintDlg / PrintDlgEx 的根本问题是由于 WinMain 上缺少属性。您需要将 WinMain 标记为 [STAThreadAttribute] 以表明您的 COM 线程模型是单线程单元。其他线程模型可能有效,但我不能肯定。
【讨论】:
我希望我能再投票 1000 次。我只是在他们身上扔了 PD_NOPAGENUMS 标志(我是打印图表,不需要分页)。谢谢! 好吧,我撒谎了,它现在也崩溃了。错误代码为:0x000006E4 我并不感到非常惊讶。无论 PrintDlg 出了什么问题,PrintDlgEx 都可能发生。我不确定你是如何得到代码 0x000006E4 的,但它经常映射到 RPC_S_CANNOT_SUPPORT。当您看到此崩溃时,您是否正在编译为 32 位并在 64 位机器上运行?是否跨多台 64 位机器? 我最近的评论无关紧要 - 它是基于对您的 .net 代码的错误假设。 好的,从头开始 - 我想我找到了:您很可能在 .net 库中对 WinMain 的定义中缺少[STAThreadAttribute]
。以上是关于Win32 PrintDlg、PrintDlgEx、崩溃和古怪的主要内容,如果未能解决你的问题,请参考以下文章