MFC打印问题 - 访问冲突异常

时间:2012-09-11 14:13:56

标签: visual-studio printing mfc

我最近遇到了一些MFC打印代码的问题。为了在高级别描述问题,当我们尝试两次打印同一文档时,我们遇到了问题。 (实际上,它不一定是SAME文档。它似乎发生在打印两个文档并且子窗口没有被销毁并在它们之间创建时。)第一次,文档打印正常。第二次,程序因未捕获的异常而崩溃。

这也是在最近升级后才开始发生的。这是我从未触及过的代码。当我们使用VS2005和MFC8时,它在第5版中运行良好。但是,当我们升级到VS2008和MFC9时,这种情况就开始发生了。

以下是问题代码:

void CReportWnd::OnPrint() 
{
    CDC dc;
    CPrintDialog dlg (FALSE);
    CPrintDialog defaults(FALSE);
    DEVMODE *ldev_printinfo;
    int li_first = 0;
    int li_last;


    int ret = defaults.GetDefaults();
    ldev_printinfo = defaults.GetDevMode();
    //ldev_printinfo->dmOrientation = DMORIENT_LANDSCAPE;
    dc.Attach (defaults.GetPrinterDC ());
    dc.ResetDC(ldev_printinfo);

    PROPrint(1, NULL, &dc, NULL, &li_last, true);

    dlg.m_pd.hDevMode = ldev_printinfo;
    dlg.m_pd.Flags &= ~PD_NOPAGENUMS;
    dlg.m_pd.nMinPage = 1;
    dlg.m_pd.nFromPage = 1;
    dlg.m_pd.nMaxPage = li_last;
    dlg.m_pd.nToPage = li_last;     

    if (dlg.DoModal () == IDOK) {
        dc.DeleteDC();
        dc.Detach();
        dc.Attach (dlg.GetPrinterDC ());        
    } else {
        return;
    }

    //Set up document info (need to set the name)
    DOCINFO di;
    ::ZeroMemory (&di, sizeof (DOCINFO));
    di.cbSize = sizeof (DOCINFO);
    di.lpszDocName = "Report";

    if(dc.StartDoc(&di) <= 0) {
        return;
    }


    if(dlg.PrintRange()) {
        li_first = dlg.m_pd.nFromPage - 1;
        li_last = dlg.m_pd.nToPage - 1;
    }

    //Now do the actual print job to the printing device
    PROPrint(1, NULL, &dc, &li_first, &li_last, false);
}

在顶部附近的int ret = ...行是抛出异常的地方。 GetDefaults()抛出访问冲突异常。但同样,只是第二次调用此函数。在我看来,这似乎是某种资源问题。就像资源没有被正确释放和分配一样。但我对印刷缺乏经验,可能是任何东西。

如果有人可以提供任何帮助,我会非常感激。

另外,是的,我知道我可以抓住异常。我的问题是,如何处理异常并仍然打印文档?

编辑: 好像我们的程序在多个地方都有这个问题,而不仅仅是这个特定的代码集。这让我觉得这个问题可能不是专门针对此代码的。我现在正在研究它,我有点必须修复它,所以当我找到解决方案时,我一定会回复。在那之前,我总是乐于接受建议。

1 个答案:

答案 0 :(得分:0)

不确定,但可能是因为代码正在删除与默认打印机关联的默认设备上下文?请尝试删除dc.DeleteDC()行,以便:

if (dlg.DoModal() == IDOK) 
{
   dc.Detach();
   dc.Attach(dlg.GetPrinterDC());        
} 
else
   return;