home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c480 / 19.ddi / MFC / SRC / VIEWPRNT.CP_ / VIEWPRNT.CP
Encoding:
Text File  |  1993-02-08  |  7.1 KB  |  267 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and Microsoft
  7. // QuickHelp and/or WinHelp documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10.  
  11. #include "stdafx.h"
  12.  
  13. #ifdef AFX_PRINT_SEG
  14. #pragma code_seg(AFX_PRINT_SEG)
  15. #endif
  16.  
  17. #ifdef _DEBUG
  18. #undef THIS_FILE
  19. static char BASED_CODE THIS_FILE[] = __FILE__;
  20. #endif
  21.  
  22. /////////////////////////////////////////////////////////////////////////////
  23. // Printing Dialog
  24.  
  25. #ifndef _AFXDLL
  26. static BOOL NEAR _afxUserAbort = FALSE;
  27. #else
  28. #define _afxUserAbort _AfxGetAppData()->appUserAbort
  29. #endif
  30.  
  31. class CPrintingDialog : public CDialog
  32. {
  33. public:
  34.     //{{AFX_DATA(CPrintingDialog)
  35.     enum { IDD = AFX_IDD_PRINTDLG };
  36.     //}}AFX_DATA
  37.     CPrintingDialog::CPrintingDialog(CWnd* pParent)
  38.         {
  39.             Create(CPrintingDialog::IDD, pParent);      // modeless !
  40.             _afxUserAbort = FALSE;
  41.         }
  42.  
  43.     virtual BOOL OnInitDialog();
  44.     virtual void OnCancel();
  45.  
  46. protected:
  47.  
  48. #if 0 // for ClassWizard's use only
  49.     //{{AFX_MSG(CPrintingDialog)
  50.     //}}AFX_MSG
  51.     DECLARE_MESSAGE_MAP()
  52. #endif
  53. };
  54.  
  55. #if 0 // for ClassWizard's use only
  56. BEGIN_MESSAGE_MAP(CPrintingDialog, CDialog)
  57.     //{{AFX_MSG_MAP(CPrintingDialog)
  58.     //}}AFX_MSG_MAP
  59. END_MESSAGE_MAP()
  60. #endif
  61.  
  62. BOOL CALLBACK AFX_EXPORT _AfxAbortProc(HDC, int)
  63. {
  64.     MSG msg;
  65.     while (!_afxUserAbort &&
  66.             ::PeekMessage(&msg, NULL, NULL, NULL, PM_NOREMOVE))
  67.     {
  68.         if (!AfxGetApp()->PumpMessage())
  69.             return FALSE;               // Bag out if WM_QUIT received
  70.     }
  71.     return !_afxUserAbort;
  72. }
  73.  
  74.  
  75. BOOL CPrintingDialog::OnInitDialog()
  76. {
  77.     SetWindowText(AfxGetAppName());
  78.     CenterWindow();
  79.     return CDialog::OnInitDialog();
  80. }
  81.  
  82. void CPrintingDialog::OnCancel()
  83. {
  84.     _afxUserAbort = TRUE;       // flag that user aborted print
  85.     CDialog::OnCancel();
  86. }
  87.  
  88. /////////////////////////////////////////////////////////////////////////////
  89. // CView printing commands
  90.  
  91. BOOL CView::DoPreparePrinting(CPrintInfo* pInfo)
  92. {
  93.     ASSERT(pInfo != NULL);
  94.     ASSERT(pInfo->m_pPD != NULL);
  95.  
  96.     if (pInfo->m_bPreview)
  97.     {
  98.         // if preview, get default printer DC and create DC without calling
  99.         //   print dialog.
  100.         if (!AfxGetApp()->GetPrinterDeviceDefaults(&pInfo->m_pPD->m_pd))
  101.         {
  102.             // bring up dialog to alert the user they need to install a printer.
  103.             if (!AfxGetApp()->DoPrintDialog(pInfo->m_pPD) != IDOK)
  104.                 return FALSE;
  105.         }
  106.  
  107.         if (pInfo->m_pPD->m_pd.hDC == NULL)
  108.         {
  109.             // call CreatePrinterDC if DC was not created by above
  110.             if (pInfo->m_pPD->CreatePrinterDC() == NULL)
  111.                 return FALSE;
  112.         }
  113.  
  114.         // set up From and To page range from Min and Max
  115.         pInfo->m_pPD->m_pd.nFromPage = pInfo->GetMinPage();
  116.         pInfo->m_pPD->m_pd.nToPage = pInfo->GetMaxPage();
  117.  
  118.     }
  119.     else
  120.     {
  121.         // otherwise, bring up the print dialog and allow user to change things
  122.  
  123.         // preset From-To range same as Min-Max range
  124.         pInfo->m_pPD->m_pd.nFromPage = pInfo->GetMinPage();
  125.         pInfo->m_pPD->m_pd.nToPage = pInfo->GetMaxPage();
  126.  
  127.         if (AfxGetApp()->DoPrintDialog(pInfo->m_pPD) != IDOK)
  128.             return FALSE;       // do not print
  129.     }
  130.  
  131.     ASSERT(pInfo->m_pPD != NULL);
  132.     ASSERT(pInfo->m_pPD->m_pd.hDC != NULL);
  133.  
  134.     pInfo->m_nNumPreviewPages = AfxGetApp()->m_nNumPreviewPages;
  135.     VERIFY(pInfo->m_strPageDesc.LoadString(AFX_IDS_PREVIEWPAGEDESC));
  136.     return TRUE;
  137. }
  138.  
  139. void CView::OnFilePrint()
  140. {
  141.     CPrintInfo printInfo;           // Get Default print info
  142.     ASSERT(printInfo.m_pPD != NULL);    // must be set
  143.  
  144.     if (OnPreparePrinting(&printInfo))
  145.     {       // print if OK
  146.  
  147.         ASSERT(printInfo.m_pPD->m_pd.hDC != NULL);
  148.                 // must be set (did you remember to call DoPreparePrinting?)
  149.  
  150.         CDC dcPrint;
  151.         dcPrint.Attach(printInfo.m_pPD->m_pd.hDC);          // attach printer dc
  152.         dcPrint.m_bPrinting = TRUE;
  153.  
  154.         OnBeginPrinting(&dcPrint, &printInfo);
  155.  
  156.         CPrintingDialog dlgPrintStatus(this);
  157.  
  158.         CString docTitle = GetDocument()->GetTitle();
  159.  
  160.         dlgPrintStatus.SetDlgItemText(AFX_IDC_PRINT_DOCNAME, docTitle);
  161.         dlgPrintStatus.SetDlgItemText(AFX_IDC_PRINT_PRINTERNAME,
  162.             printInfo.m_pPD->GetDeviceName());
  163.  
  164.         CString strPort;
  165.         AfxFormatString1(strPort, AFX_IDS_PRINTONPORT,
  166.             printInfo.m_pPD->GetPortName());
  167.         dlgPrintStatus.SetDlgItemText(AFX_IDC_PRINT_PORTNAME, strPort);
  168.         dlgPrintStatus.ShowWindow(SW_SHOW);
  169.  
  170.         AfxGetApp()->m_pMainWnd->EnableWindow(FALSE);   // Disable main window
  171.  
  172.         dcPrint.SetAbortProc(_AfxAbortProc);
  173.  
  174.         if (docTitle.GetLength() > 31)
  175.             docTitle.ReleaseBuffer(31);
  176.  
  177.         DOCINFO docInfo;
  178.         docInfo.cbSize = sizeof(DOCINFO);
  179.         docInfo.lpszDocName = docTitle;
  180.         docInfo.lpszOutput = NULL;
  181.  
  182.         if (dcPrint.StartDoc(&docInfo) == SP_ERROR)
  183.         {
  184.             AfxMessageBox(AFX_IDP_FAILED_TO_START_PRINT);
  185.             return;
  186.         }
  187.  
  188.         UINT nEndPage = printInfo.GetToPage();
  189.         UINT nStartPage = printInfo.GetFromPage();
  190.  
  191.         // Guarantee values are in the valid range
  192.         if (nEndPage < printInfo.GetMinPage())
  193.             nEndPage = printInfo.GetMinPage();
  194.         if (nEndPage > printInfo.GetMaxPage())
  195.             nEndPage = printInfo.GetMaxPage();
  196.  
  197.         if (nStartPage < printInfo.GetMinPage())
  198.             nStartPage = printInfo.GetMinPage();
  199.         if (nStartPage > printInfo.GetMaxPage())
  200.             nStartPage = printInfo.GetMaxPage();
  201.  
  202.         int nStep = (nEndPage >= nStartPage) ? 1 : -1;
  203.         nEndPage = (nEndPage == 0xffff) ? 0xffff : nEndPage + nStep;
  204.  
  205.         BOOL bError = FALSE;
  206.         for (printInfo.m_nCurPage = nStartPage;
  207.             !bError && printInfo.m_nCurPage != nEndPage;
  208.             printInfo.m_nCurPage += nStep)
  209.         {
  210.             OnPrepareDC(&dcPrint, &printInfo);
  211.  
  212.             if (!printInfo.m_bContinuePrinting)
  213.                 break;          // reached end of print
  214.  
  215.             // Set up drawing rect to entire page (in logical coordinates)
  216.             printInfo.m_rectDraw.SetRect(0, 0, dcPrint.GetDeviceCaps(HORZRES),
  217.                                                dcPrint.GetDeviceCaps(VERTRES));
  218.             dcPrint.DPtoLP(&printInfo.m_rectDraw);
  219.  
  220.             CString strFmt;
  221.             VERIFY(strFmt.LoadString(AFX_IDS_PRINTPAGENUM));
  222.             char szBuf[80];
  223.             wsprintf(szBuf, strFmt, printInfo.m_nCurPage);
  224.             dlgPrintStatus.SetDlgItemText(AFX_IDC_PRINT_PAGENUM, szBuf);
  225.  
  226.             VERIFY(dcPrint.StartPage());
  227.             OnPrint(&dcPrint, &printInfo);
  228.             if (dcPrint.EndPage() < 0)
  229.                 bError = TRUE;
  230.         }
  231.  
  232.         if (!bError)
  233.             dcPrint.EndDoc();
  234.  
  235.         AfxGetApp()->m_pMainWnd->EnableWindow(TRUE);    // Enable main window
  236.  
  237.         OnEndPrinting(&dcPrint, &printInfo);        // Clean up after printing
  238.  
  239.         dlgPrintStatus.DestroyWindow();
  240.     }
  241. }
  242.  
  243. /////////////////////////////////////////////////////////////////////////////
  244. // CPrintInfo helper structure
  245.  
  246. CPrintInfo::CPrintInfo()
  247. {
  248.     m_pPD = new CPrintDialog(FALSE, PD_ALLPAGES | PD_USEDEVMODECOPIES |
  249.                                         PD_HIDEPRINTTOFILE | PD_NOSELECTION);
  250.  
  251.     SetMinPage(1);              // one based page numbers
  252.     SetMaxPage(0xffff);         // unknown how many pages
  253.  
  254.     m_nCurPage = 1;
  255.  
  256.     m_lpUserData = NULL;        // Initialize to no user data
  257.     m_bPreview = FALSE;         // initialize to not preview
  258.     m_bContinuePrinting = TRUE; // Assume it is OK to print
  259. }
  260.  
  261. CPrintInfo::~CPrintInfo()
  262. {
  263.     delete m_pPD;
  264. }
  265.  
  266. /////////////////////////////////////////////////////////////////////////////
  267.