|
|
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:
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: #ifndef _NTWIN
132: if (pdc->StartDoc(sz) < 0)
133: #else
134: DOCINFO di;
135: di.cbSize = sizeof(di);
136: di.lpszDocName = sz;
137: di.lpszOutput = NULL;
138: if (pdc->StartDoc(&di) < 0)
139: #endif
140: goto printFailed;
141:
142: return TRUE;
143:
144: printFailed:
145: delete pdc;
146: return FALSE;
147: }
148:
149: // EndJob:
150: // Do a final page-eject, shut down the printer context, and re-enable the
151: // application.
152: //
153: void CPrinter::EndJob()
154: {
155: if (pdc != NULL)
156: {
157: if (fAbort || pdc->EndPage() < 0 || pdc->EndDoc() < 0)
158: {
159: pdc->AbortDoc();
160: }
161: else
162: {
163: fError = FALSE;
164: }
165:
166: delete pdc;
167: pdc = NULL;
168: }
169:
170: if (pdlg != NULL)
171: {
172: AfxGetApp()->m_pMainWnd->EnableWindow(TRUE);
173:
174: delete pdlg;
175: pdlg = NULL;
176: hwndPDlg = NULL;
177:
178: }
179:
180: // Error? Make sure the user knows.
181: //
182: if (fError)
183: MPError(MB_OK | MB_ICONEXCLAMATION, IDS_PRINTERROR, (LPCSTR)szTitle);
184: }
185:
186: /////////////////////////////////////////////////////////////////////////////
187:
188: // PrintFile:
189: // This does all the work of printing the text buffer.
190: //
191: void CMPChild::PrintFile()
192: {
193: int yExtPage;
194: UINT cch;
195: UINT ich;
196: PSTR pch;
197: UINT iLine;
198: UINT nLinesEc;
199: HANDLE hT;
200: UINT dy;
201: int yExtSoFar;
202:
203: char szDocName[256];
204: GetWindowText(szDocName, sizeof (szDocName));
205:
206: if ( !thePrinter->StartJob(szDocName) )
207: return;
208:
209: dy = thePrinter->pdc->GetTextExtent("CC", 2).cy;
210: yExtPage = thePrinter->pdc->GetDeviceCaps(VERTRES);
211:
212: // Get the lines in document and and a handle to the text buffer.
213: //
214: iLine = 0;
215: yExtSoFar = 0;
216: nLinesEc = m_edit.GetLineCount();
217: hT = m_edit.GetHandle();
218:
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;
232: }
233:
234: // Get the length and position of the line in the buffer
235: // and lock from that offset into the buffer.
236: //
237: ich = m_edit.LineIndex(iLine);
238: cch = m_edit.LineLength(ich);
239: pch = (PSTR)LocalLock(hT) + ich;
240:
241: // Print the line and unlock the text handle.
242: //
243: thePrinter->pdc->TabbedTextOut(0, yExtSoFar, (LPCSTR)pch, cch,
244: 0, NULL, 0);
245: LocalUnlock(hT);
246:
247: // Test and see if the Abort flag has been set. If yes, exit.
248: //
249: if (thePrinter->fAbort)
250: break;
251:
252: // Move down the page.
253: //
254: yExtSoFar += dy;
255: iLine++;
256: }
257:
258: thePrinter->EndJob();
259: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.