2016-03-05 172 views
1

下面是以下代码。0xC0000005打印功能中出现错误

void SignalView::OnFilePrintPreview() 
{ 
if(RcursorPosX-LcursorPosX<=0){ 
    AfxMessageBox(_T("Please set cursor positions.\nYou can only print out the area between left and right cursors")); 
    return; 
} 
CScrollView::OnFilePrintPreview(); 
} 

BOOL SignalView::OnPreparePrinting(CPrintInfo* pInfo) 
{ 
if(RcursorPosX-LcursorPosX>100*4*2) 
RcursorPosX = LcursorPosX+100*4*2; //800 = 100 cursor x 4(gridX) x 2(zoomX) 

pInfo->SetMinPage(1); 
pInfo->SetMaxPage(1); 

return DoPreparePrinting(pInfo);  //<=========== 
} 

void SignalView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo) 
{ 
PRINTDLG* pPrintDlg = new PRINTDLG; 
AfxGetApp()->GetPrinterDeviceDefaults(pPrintDlg); 
DEVMODE* lpDevMode = (DEVMODE*)::GlobalLock(pPrintDlg->hDevMode);   

lpDevMode->dmOrientation = DMORIENT_LANDSCAPE; 

while(!pDC->ResetDC(lpDevMode)); 
::GlobalUnlock(pPrintDlg->hDevMode);  
delete pPrintDlg; 
} 

我正在尝试使用打印功能。但我重拍了它,因为我删除了它,并重新创建了一个新的类,它来自CScrollView,所以我不使用从一开始就制作的原始视图。

现在,我达到了我想要的,但问题是当我尝试打电话并关闭打印事件OnFilePrintPreview()约30-40次时发生错误,然后它将关闭并显示错误消息0xC0000005

它发生在功能DoPreparePrinting(pInfo),然后它COMMDLG_AFXCTXFUNC(BOOL ,PrintDlgW,(LPPRINTDLGW unnamed1),(unnamed1))afxcomctl32.inl文件,然后它引发一个错误消息。

为什么会发生这个问题?代码似乎朝着正确的方向发展?

P.S. 在反汇编模式下发生错误。

COMMDLG_AFXCTXFUNC(BOOL ,PrintDlgW,(LPPRINTDLGW unnamed1),(unnamed1)) 
7824CD80 mov   edi,edi 
7824CD82 push  ebp 
7824CD83 mov   ebp,esp 
7824CD85 mov   eax,dword ptr [unnamed1] 
7824CD88 push  eax 
7824CD89 call  AfxGetModuleState (780F3320h) 
7824CD8E mov   ecx,dword ptr [eax+94h] 
7824CD94 mov   ecx,dword ptr [ecx+4] 
7824CD97 call  CCommDlgWrapper::_PrintDlgW (7824CDB0h) 
7824CD9C pop   ebp   //<======= it's stopped at this point. 
7824CD9D ret   4 
+0

使用调试器通过查看调用堆栈来找出崩溃发生的位置。 –

+0

谢谢你的评论。我评论了上面的代码。请检查一下。 – Sean

回答

1
while(!pDC->ResetDC(lpDevMode)); 
    ::GlobalUnlock(pPrintDlg->hDevMode); 

这看起来像麻烦。如果第一次和第二次循环条件为真,则不能保证它最终会停止。

以下内容可能不是您错误的原因,但您应该尝试遵循这些程序。

宣布在新的变量其设置为0,那么所有结构成员均为零:

PRINTDLG* pPrintDlg = new PRINTDLG; 
memset(pPrintDlg, 0, sizeof(pPrintDlg)); 

一些结构需要知道的大小。这与微软的版本控制做的事:

pPrintDlg->lStructSize = sizeof(PRINTDLG); 

在这种情况下,你不需要使用new分配pPrintDlg(但如果你这样做会不会产生问题)

你应该能够拦截打印请求(在创建打印机设备上下文之前)并切换到横向模式,因此打印对话框以横向模式显示。

void SignalView::OnFilePrint() 
{ 
    PRINTDLG printDlg = { 0 }; 
    printDlg.lStructSize = sizeof(PRINTDLG); 
    if (AfxGetApp()->GetPrinterDeviceDefaults(&printDlg)) 
    { 
     if (printDlg.hDevMode) 
     { 
      DEVMODE *dm = (DEVMODE*)::GlobalLock(printDlg.hDevMode); 
      if (dm) 
      { 
       dm->dmFields |= DM_ORIENTATION; 
       dm->dmOrientation = DMORIENT_LANDSCAPE; 
       ::GlobalUnlock(printDlg.hDevMode); 
      } 
     } 
    } 

    CScrollView::OnFilePrint(); 
} 

消息映射应该是这样的:

BEGIN_MESSAGE_MAP(SignalView, CScrollView) 
    ON_COMMAND(ID_FILE_PRINT, OnFilePrint) 
    ON_COMMAND(ID_FILE_PRINT_DIRECT, OnFilePrint) 
    //************************************************** 
    ON_COMMAND(ID_FILE_PRINT_PREVIEW, OnFilePrintPreview) 
    //************************************************** 
END_MESSAGE_MAP() 

用户可以更改打印模式回纵向打印对话框。如果要强制横向,则可以在OnBeginPrinting中重复相同的代码。

+0

谢谢你的帮助。但我必须进行打印预览。我已经用打印对话框做了,但是我删除了它,因为如果我继续使用打印对话框,我找不到打印预览模式。此外,预览应该向用户显示横向视图,这就是为什么我在设置之前使用横向模式的原因。有没有一种使用打印对话框的打印预览?如果没有,我怎样才能使用正常的打印视图功能。 – Sean

+0

如果有帮助,请参阅编辑。它应该强制景观。你应该也可以在'void CMyView :: OnFilePrintPreview()' –

+0

中做到这一点谢谢你的编辑。但是,它没有显示任何预览。如果我想在对话框之前显示预览,我应该如何从代码中修复它? – Sean