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