【问题标题】:What could cause PrintDlgEx to crash for a particular printer choice?什么可能导致 PrintDlgEx 因特定打印机选择而崩溃?
【发布时间】:2014-09-24 20:18:34
【问题描述】:

当特定打印机是默认打印机时,每当用户通过 PrintDlgEx 调出 Windows 打印对话框时,我们的程序就会崩溃。如果该打印机不是默认打印机,一切都很好,除非用户从对话框中选择该打印机,在这种情况下对话框立即崩溃。

打印机是 HP LaserJet Pro 400 M451nw,同一网络上的多台计算机尝试访问该打印机时会出现此问题。但是,其他程序可以打印到该打印机,包括记事本。计算机运行 32 位 Windows 7;该程序是用 VS C++ 编写的。

代码如下:

PRINTDLGEX printer = { 0 }; 
printer.lStructSize = sizeof( printer );
printer.hwndOwner = my_win;
printer.Flags = PD_RETURNDC | PD_NOPAGENUMS | PD_NOCURRENTPAGE | PD_USEDEVMODECOPIES;   
printer.nCopies = 1;                                        
printer.nStartPage = START_PAGE_GENERAL;
PrintDlgEx( &printer );

这是客户发给我的:

关于什么可能导致这样的崩溃,或者我们将如何解决这个问题的任何想法?

【问题讨论】:

  • 您是否尝试过使用这些标志来查看其中一个是否会触发它?
  • 可能与 COM 状态有关?例如,也许您正在使用多线程单元模型并且打印机驱动程序无法处理? (你记得初始化 COM 吗?)
  • @Jonathan Potter:我玩过很多标志(将其简化为 PD_RETURNDC 并添加其他成员变量,以及添加标志。不开心。
  • this question 是否适用?听起来很相似。
  • 告诉我们有关“崩溃”的信息。至少是异常代码和堆栈跟踪。

标签: c++ winapi printing


【解决方案1】:

事件日志详细信息提供了关键线索:异常代码0xC0000093,转换为STATUS_FLOAT_UNDERFLOW,表示涉及FPU。因为浮点非常复杂,所以 FPU 有很多不同的配置,不幸的是代码可能对此很敏感。

在这种特殊情况下,打印机驱动程序似乎希望 FP 异常报告关闭(我想这并非不合理),但将调用托管到驱动程序的应用程序已将其打开。在调用 PrintDlgEx 之前屏蔽 FP 异常消除了崩溃。

(从中可以吸取两点教训:第一,调用第三方代码时,需要尽量提供干净的环境;第二,打印机驱动程序不应该使用浮点数。它还指出Windows,IMO 中的一个设计弱点,尽管在旧计算机上可能是必需的。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 2012-12-04
    • 1970-01-01
    • 2012-11-07
    • 1970-01-01
    相关资源
    最近更新 更多