home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgLangD.iso / C++-7 / DISK8 / MFC / SAMPLES / MULTIPAD / MPPRINT.CP$ / mpprint
Encoding:
Text File  |  1992-03-17  |  5.5 KB  |  252 lines

  1. // mpprint.cpp : Defines the printing logic.
  2. //
  3. // This is a part of the Microsoft Foundation Classes C++ library.
  4. // Copyright (C) 1992 Microsoft Corporation
  5. // All rights reserved.
  6. //
  7. // This source code is only intended as a supplement to the
  8. // Microsoft Foundation Classes Reference and Microsoft
  9. // QuickHelp documentation provided with the library.
  10. // See these sources for detailed information regarding the
  11. // Microsoft Foundation Classes product.
  12.  
  13. #include "multipad.h"
  14.  
  15. #include <commdlg.h>
  16.  
  17. #pragma code_seg("_MPPRINT")
  18.  
  19. CPrinter* thePrinter;
  20. char BASED_CODE szExtDeviceMode[] = "EXTDEVICEMODE";
  21.  
  22. /////////////////////////////////////////////////////////////////////////////
  23.  
  24. // AbortProc:
  25. // While printing, this replaces the normal message receiver loop.
  26. // This provides simplified message routing until the modeless "Abort"
  27. // dialog can be closed.
  28. //
  29. BOOL FAR PASCAL EXPORT AbortProc(HDC, int)
  30. {
  31.     MSG msg;
  32.     
  33.     // Allow other apps to run, while polling the abort status.
  34.     //
  35.     while (!thePrinter->fAbort &&
  36.         PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE))
  37.     {
  38.         if (!thePrinter->hwndPDlg ||
  39.             !IsDialogMessage(thePrinter->hwndPDlg, &msg))
  40.         {
  41.             TranslateMessage(&msg);
  42.             DispatchMessage(&msg);
  43.         }
  44.     }
  45.     
  46.     return !thePrinter->fAbort;
  47. }
  48.  
  49. class CPrintCanDlg : public CDialog
  50. {
  51. public:
  52.     CPrintCanDlg();
  53.     
  54.     BOOL OnInitDialog();
  55.     afx_msg void OnCancel();
  56.     
  57.     DECLARE_MESSAGE_MAP();
  58. };
  59.  
  60. BEGIN_MESSAGE_MAP(CPrintCanDlg, CDialog)
  61.     ON_COMMAND(IDOK, OnCancel)
  62. END_MESSAGE_MAP()
  63.  
  64. CPrintCanDlg::CPrintCanDlg()
  65. {
  66.     VERIFY( Create(IDD_PRINT) );
  67. }
  68.  
  69. BOOL CPrintCanDlg::OnInitDialog()
  70. {
  71.     SetDlgItemText(IDD_PRINTDEVICE, thePrinter->printDlg.GetDeviceName());
  72.     SetDlgItemText(IDD_PRINTPORT, thePrinter->printDlg.GetPortName());
  73.     SetDlgItemText(IDD_PRINTTITLE, thePrinter->szTitle);
  74.     return TRUE;
  75. }
  76.  
  77. void CPrintCanDlg::OnCancel()
  78. {
  79.     thePrinter->fAbort = TRUE;
  80. }
  81.  
  82. // StartJob:
  83. // Prepare the printer DC and open the Cancel dialog, ready for printing.
  84. // The application's frame is disabled, mostly to protect the data while
  85. // printing is in progress.
  86. //
  87. BOOL CPrinter::StartJob(char* szDocName)
  88. {
  89.     char sz [32];
  90.  
  91.     fAbort = FALSE;
  92.     fError = TRUE; // Assume an error until done.
  93.     pdc = NULL;
  94.     pdlg = NULL;
  95.     
  96.     // Create the job title by loading the title string from STRINGTABLE.
  97.     //
  98.     int cch = LoadString(AfxGetInstanceHandle(), IDS_PRINTJOB,
  99.         sz, sizeof(sz));
  100.     strncpy(sz + cch, szDocName, sizeof (sz) - cch - 1);
  101.     sz[sizeof(sz)-1] = '\0';
  102.     strncpy(szTitle, szDocName, sizeof (szTitle) - 1);
  103.     
  104.     // Use standard PrintDlg to get printer DC
  105.     //
  106.     //If DoModalPrint returns 0 then user canceled or an error happened.
  107.     if ( printDlg.DoModal() == IDCANCEL)
  108.         return FALSE;
  109.  
  110.     pdc = new CDC;
  111.     pdc->Attach(printDlg.GetPrinterDC());
  112.  
  113.     pdlg = new CPrintCanDlg;
  114.     
  115.     hwndPDlg = pdlg->m_hWnd;
  116.     
  117.     // Disable the main application window and create the Cancel dialog.
  118.     //
  119.     AfxGetApp()->m_pMainWnd->EnableWindow(FALSE);
  120.  
  121.     // Allow the app to inform GDI of the escape function to call.
  122.     //
  123.     if (pdc->SetAbortProc(AbortProc) < 0)
  124.         goto printFailed;
  125.     
  126.     pdlg->ShowWindow(SW_SHOW);
  127.     pdlg->UpdateWindow();
  128.     
  129.     // Initialize the document.
  130.     //
  131.     if (pdc->StartDoc(sz) < 0)
  132.         goto printFailed;
  133.     
  134.     return TRUE;
  135.  
  136.     printFailed: 
  137.         delete pdc;
  138.         return FALSE;
  139. }
  140.  
  141. // EndJob:
  142. // Do a final page-eject, shut down the printer context, and re-enable the
  143. // application.
  144. //
  145. void CPrinter::EndJob()
  146. {
  147.     if (pdc != NULL)
  148.     {
  149.         if (fAbort || pdc->EndPage() < 0 || pdc->EndDoc() < 0)
  150.         {
  151.             pdc->AbortDoc();
  152.         }
  153.         else
  154.         {
  155.             fError = FALSE;
  156.         }
  157.         
  158.         delete pdc;
  159.         pdc = NULL;
  160.     }
  161.  
  162.     if (pdlg != NULL)
  163.     {
  164.         AfxGetApp()->m_pMainWnd->EnableWindow(TRUE);
  165.         
  166.         delete pdlg;
  167.         pdlg = NULL;
  168.         hwndPDlg = NULL;
  169.         
  170.     }
  171.     
  172.     // Error? Make sure the user knows.
  173.     //
  174.     if (fError)
  175.         MPError(MB_OK | MB_ICONEXCLAMATION, IDS_PRINTERROR, (LPCSTR)szTitle);
  176. }
  177.  
  178. /////////////////////////////////////////////////////////////////////////////
  179.  
  180. // PrintFile:
  181. // This does all the work of printing the text buffer.
  182. //
  183. void CMPChild::PrintFile()
  184. {
  185.     int     yExtPage;
  186.     UINT    cch;
  187.     UINT    ich;
  188.     PSTR    pch;
  189.     UINT    iLine;
  190.     UINT    nLinesEc;
  191.     HANDLE  hT;
  192.     UINT    dy;
  193.     int     yExtSoFar;
  194.     
  195.     char szDocName[256];
  196.     GetWindowText(szDocName, sizeof (szDocName));
  197.     
  198.     if ( !thePrinter->StartJob(szDocName) )
  199.         return;
  200.     
  201.     dy = thePrinter->pdc->GetTextExtent("CC", 2).cy;
  202.     yExtPage = thePrinter->pdc->GetDeviceCaps(VERTRES);
  203.     
  204.     // Get the lines in document and and a handle to the text buffer.
  205.     //
  206.     iLine = 0;
  207.     yExtSoFar = 0;
  208.     nLinesEc = m_edit.GetLineCount();
  209.     hT = m_edit.GetHandle();
  210.  
  211.     // While more lines, print out the text.
  212.     //
  213.     while (iLine < nLinesEc)
  214.     {
  215.         if (yExtSoFar + (int)dy > yExtPage)
  216.         {
  217.             // Reached the end of a page. Tell the device driver to eject a
  218.             // page.
  219.             //
  220.             if (thePrinter->pdc->EndPage() < 0 || thePrinter->fAbort)
  221.                 break;
  222.             
  223.             yExtSoFar = 0;
  224.         }
  225.         
  226.         // Get the length and position of the line in the buffer
  227.         // and lock from that offset into the buffer.
  228.         //
  229.         ich = m_edit.LineIndex(iLine);
  230.         cch = m_edit.LineLength(ich);
  231.         pch = (PSTR)LocalLock(hT) + ich;
  232.         
  233.         // Print the line and unlock the text handle.
  234.         //
  235.         thePrinter->pdc->TabbedTextOut(0, yExtSoFar, (LPCSTR)pch, cch,
  236.             0, NULL, 0);
  237.         LocalUnlock(hT);
  238.         
  239.         // Test and see if the Abort flag has been set. If yes, exit.
  240.         //
  241.         if (thePrinter->fAbort)
  242.             break;
  243.         
  244.         // Move down the page.
  245.         //
  246.         yExtSoFar += dy;
  247.         iLine++;
  248.     }
  249.     
  250.     thePrinter->EndJob();
  251. }
  252.