2016-03-05 123 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