Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(548)

Side by Side Diff: third_party/wtl/include/atlprint.h

Issue 703753005: More Windows build fixes. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: remove generated files Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/wtl/include/atlmisc.h ('k') | third_party/wtl/include/atlres.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Windows Template Library - WTL version 8.0
2 // Copyright (C) Microsoft Corporation. All rights reserved.
3 //
4 // This file is a part of the Windows Template Library.
5 // The use and distribution terms for this software are covered by the
6 // Microsoft Permissive License (Ms-PL) which can be found in the file
7 // Ms-PL.txt at the root of this distribution.
8
9 #ifndef __ATLPRINT_H__
10 #define __ATLPRINT_H__
11
12 #pragma once
13
14 #ifndef __cplusplus
15 #error ATL requires C++ compilation (use a .cpp suffix)
16 #endif
17
18 #ifdef _WIN32_WCE
19 #error atlprint.h is not supported on Windows CE
20 #endif
21
22 #ifndef __ATLAPP_H__
23 #error atlprint.h requires atlapp.h to be included first
24 #endif
25
26 #ifndef __ATLWIN_H__
27 #error atlprint.h requires atlwin.h to be included first
28 #endif
29
30
31 ///////////////////////////////////////////////////////////////////////////////
32 // Classes in this file:
33 //
34 // CPrinterInfo<t_nInfo>
35 // CPrinterT<t_bManaged>
36 // CDevModeT<t_bManaged>
37 // CPrinterDC
38 // CPrintJobInfo
39 // CPrintJob
40 // CPrintPreview
41 // CPrintPreviewWindowImpl<T, TBase, TWinTraits>
42 // CPrintPreviewWindow
43 // CZoomPrintPreviewWindowImpl<T, TBase, TWinTraits>
44 // CZoomPrintPreviewWindow
45
46 namespace WTL
47 {
48
49 ///////////////////////////////////////////////////////////////////////////////
50 // CPrinterInfo - This class wraps all of the PRINTER_INFO_* structures
51 // and provided by ::GetPrinter.
52
53 template <unsigned int t_nInfo>
54 class _printer_info
55 {
56 public:
57 typedef void infotype;
58 };
59
60 template <> class _printer_info<1> { public: typedef PRINTER_INFO_1 infotype; };
61 template <> class _printer_info<2> { public: typedef PRINTER_INFO_2 infotype; };
62 template <> class _printer_info<3> { public: typedef PRINTER_INFO_3 infotype; };
63 template <> class _printer_info<4> { public: typedef PRINTER_INFO_4 infotype; };
64 template <> class _printer_info<5> { public: typedef PRINTER_INFO_5 infotype; };
65 template <> class _printer_info<6> { public: typedef PRINTER_INFO_6 infotype; };
66 template <> class _printer_info<7> { public: typedef PRINTER_INFO_7 infotype; };
67 // these are not in the old (vc6.0) headers
68 #ifdef _ATL_USE_NEW_PRINTER_INFO
69 template <> class _printer_info<8> { public: typedef PRINTER_INFO_8 infotype; };
70 template <> class _printer_info<9> { public: typedef PRINTER_INFO_9 infotype; };
71 #endif // _ATL_USE_NEW_PRINTER_INFO
72
73
74 template <unsigned int t_nInfo>
75 class CPrinterInfo
76 {
77 public:
78 // Data members
79 typename _printer_info<t_nInfo>::infotype* m_pi;
80
81 // Constructor/destructor
82 CPrinterInfo() : m_pi(NULL)
83 { }
84
85 CPrinterInfo(HANDLE hPrinter) : m_pi(NULL)
86 {
87 GetPrinterInfo(hPrinter);
88 }
89
90 ~CPrinterInfo()
91 {
92 Cleanup();
93 }
94
95 // Operations
96 bool GetPrinterInfo(HANDLE hPrinter)
97 {
98 Cleanup();
99 return GetPrinterInfoHelper(hPrinter, (BYTE**)&m_pi, t_nInfo);
100 }
101
102 // Implementation
103 void Cleanup()
104 {
105 delete [] (BYTE*)m_pi;
106 m_pi = NULL;
107 }
108
109 static bool GetPrinterInfoHelper(HANDLE hPrinter, BYTE** pi, int nIndex)
110 {
111 ATLASSERT(pi != NULL);
112 DWORD dw = 0;
113 BYTE* pb = NULL;
114 ::GetPrinter(hPrinter, nIndex, NULL, 0, &dw);
115 if (dw > 0)
116 {
117 ATLTRY(pb = new BYTE[dw]);
118 if (pb != NULL)
119 {
120 memset(pb, 0, dw);
121 DWORD dwNew;
122 if (!::GetPrinter(hPrinter, nIndex, pb, dw, &dwN ew))
123 {
124 delete [] pb;
125 pb = NULL;
126 }
127 }
128 }
129 *pi = pb;
130 return (pb != NULL);
131 }
132 };
133
134
135 ///////////////////////////////////////////////////////////////////////////////
136 // CPrinter - Wrapper class for a HANDLE to a printer
137
138 template <bool t_bManaged>
139 class CPrinterT
140 {
141 public:
142 // Data members
143 HANDLE m_hPrinter;
144
145 // Constructor/destructor
146 CPrinterT(HANDLE hPrinter = NULL) : m_hPrinter(hPrinter)
147 { }
148
149 ~CPrinterT()
150 {
151 ClosePrinter();
152 }
153
154 // Operations
155 CPrinterT& operator =(HANDLE hPrinter)
156 {
157 if (hPrinter != m_hPrinter)
158 {
159 ClosePrinter();
160 m_hPrinter = hPrinter;
161 }
162 return *this;
163 }
164
165 bool IsNull() const { return (m_hPrinter == NULL); }
166
167 bool OpenPrinter(HANDLE hDevNames, const DEVMODE* pDevMode = NULL)
168 {
169 bool b = false;
170 DEVNAMES* pdn = (DEVNAMES*)::GlobalLock(hDevNames);
171 if (pdn != NULL)
172 {
173 LPTSTR lpszPrinterName = (LPTSTR)pdn + pdn->wDeviceOffse t;
174 b = OpenPrinter(lpszPrinterName, pDevMode);
175 ::GlobalUnlock(hDevNames);
176 }
177 return b;
178 }
179
180 bool OpenPrinter(LPCTSTR lpszPrinterName, const DEVMODE* pDevMode = NULL )
181 {
182 ClosePrinter();
183 PRINTER_DEFAULTS pdefs = { NULL, (DEVMODE*)pDevMode, PRINTER_ACC ESS_USE };
184 ::OpenPrinter((LPTSTR) lpszPrinterName, &m_hPrinter, (pDevMode = = NULL) ? NULL : &pdefs);
185
186 return (m_hPrinter != NULL);
187 }
188
189 bool OpenPrinter(LPCTSTR lpszPrinterName, PRINTER_DEFAULTS* pprintdefs)
190 {
191 ClosePrinter();
192 ::OpenPrinter((LPTSTR) lpszPrinterName, &m_hPrinter, pprintdefs) ;
193 return (m_hPrinter != NULL);
194 }
195
196 bool OpenDefaultPrinter(const DEVMODE* pDevMode = NULL)
197 {
198 ClosePrinter();
199 const int cchBuff = 512;
200 TCHAR buffer[cchBuff];
201 buffer[0] = 0;
202 ::GetProfileString(_T("windows"), _T("device"), _T(",,,"), buffe r, cchBuff);
203 int nLen = lstrlen(buffer);
204 if (nLen != 0)
205 {
206 LPTSTR lpsz = buffer;
207 while (*lpsz)
208 {
209 if (*lpsz == _T(','))
210 {
211 *lpsz = 0;
212 break;
213 }
214 lpsz = CharNext(lpsz);
215 }
216 PRINTER_DEFAULTS pdefs = { NULL, (DEVMODE*)pDevMode, PRI NTER_ACCESS_USE };
217 ::OpenPrinter(buffer, &m_hPrinter, (pDevMode == NULL) ? NULL : &pdefs);
218 }
219 return m_hPrinter != NULL;
220 }
221
222 void ClosePrinter()
223 {
224 if (m_hPrinter != NULL)
225 {
226 if (t_bManaged)
227 ::ClosePrinter(m_hPrinter);
228 m_hPrinter = NULL;
229 }
230 }
231
232 bool PrinterProperties(HWND hWnd = NULL)
233 {
234 if (hWnd == NULL)
235 hWnd = ::GetActiveWindow();
236 return !!::PrinterProperties(hWnd, m_hPrinter);
237 }
238
239 HANDLE CopyToHDEVNAMES() const
240 {
241 HANDLE h = NULL;
242 CPrinterInfo<5> pinfon5;
243 CPrinterInfo<2> pinfon2;
244 LPTSTR lpszPrinterName = NULL;
245 // Some printers fail for PRINTER_INFO_5 in some situations
246 if (pinfon5.GetPrinterInfo(m_hPrinter))
247 lpszPrinterName = pinfon5.m_pi->pPrinterName;
248 else if (pinfon2.GetPrinterInfo(m_hPrinter))
249 lpszPrinterName = pinfon2.m_pi->pPrinterName;
250 if (lpszPrinterName != NULL)
251 {
252 int nLen = sizeof(DEVNAMES) + (lstrlen(lpszPrinterName) + 1) * sizeof(TCHAR);
253 h = ::GlobalAlloc(GMEM_MOVEABLE, nLen);
254 BYTE* pv = (BYTE*)::GlobalLock(h);
255 DEVNAMES* pdev = (DEVNAMES*)pv;
256 if (pv != NULL)
257 {
258 memset(pv, 0, nLen);
259 pdev->wDeviceOffset = sizeof(DEVNAMES) / sizeof( TCHAR);
260 pv = pv + sizeof(DEVNAMES); // now points to end
261 SecureHelper::strcpy_x((LPTSTR)pv, lstrlen(lpszP rinterName) + 1, lpszPrinterName);
262 ::GlobalUnlock(h);
263 }
264 }
265 return h;
266 }
267
268 HDC CreatePrinterDC(const DEVMODE* pdm = NULL) const
269 {
270 CPrinterInfo<5> pinfo5;
271 CPrinterInfo<2> pinfo2;
272 HDC hDC = NULL;
273 LPTSTR lpszPrinterName = NULL;
274 // Some printers fail for PRINTER_INFO_5 in some situations
275 if (pinfo5.GetPrinterInfo(m_hPrinter))
276 lpszPrinterName = pinfo5.m_pi->pPrinterName;
277 else if (pinfo2.GetPrinterInfo(m_hPrinter))
278 lpszPrinterName = pinfo2.m_pi->pPrinterName;
279 if (lpszPrinterName != NULL)
280 hDC = ::CreateDC(NULL, lpszPrinterName, NULL, pdm);
281 return hDC;
282 }
283
284 HDC CreatePrinterIC(const DEVMODE* pdm = NULL) const
285 {
286 CPrinterInfo<5> pinfo5;
287 CPrinterInfo<2> pinfo2;
288 HDC hDC = NULL;
289 LPTSTR lpszPrinterName = NULL;
290 // Some printers fail for PRINTER_INFO_5 in some situations
291 if (pinfo5.GetPrinterInfo(m_hPrinter))
292 lpszPrinterName = pinfo5.m_pi->pPrinterName;
293 else if (pinfo2.GetPrinterInfo(m_hPrinter))
294 lpszPrinterName = pinfo2.m_pi->pPrinterName;
295 if (lpszPrinterName != NULL)
296 hDC = ::CreateIC(NULL, lpszPrinterName, NULL, pdm);
297 return hDC;
298 }
299
300 void Attach(HANDLE hPrinter)
301 {
302 ClosePrinter();
303 m_hPrinter = hPrinter;
304 }
305
306 HANDLE Detach()
307 {
308 HANDLE hPrinter = m_hPrinter;
309 m_hPrinter = NULL;
310 return hPrinter;
311 }
312
313 operator HANDLE() const { return m_hPrinter; }
314 };
315
316 typedef CPrinterT<false> CPrinterHandle;
317 typedef CPrinterT<true> CPrinter;
318
319
320 ///////////////////////////////////////////////////////////////////////////////
321 // CDevMode - Wrapper class for DEVMODE
322
323 template <bool t_bManaged>
324 class CDevModeT
325 {
326 public:
327 // Data members
328 HANDLE m_hDevMode;
329 DEVMODE* m_pDevMode;
330
331 // Constructor/destructor
332 CDevModeT(HANDLE hDevMode = NULL) : m_hDevMode(hDevMode)
333 {
334 m_pDevMode = (m_hDevMode != NULL) ? (DEVMODE*)::GlobalLock(m_hDe vMode) : NULL;
335 }
336
337 ~CDevModeT()
338 {
339 Cleanup();
340 }
341
342 // Operations
343 CDevModeT<t_bManaged>& operator =(HANDLE hDevMode)
344 {
345 Attach(hDevMode);
346 return *this;
347 }
348
349 void Attach(HANDLE hDevModeNew)
350 {
351 Cleanup();
352 m_hDevMode = hDevModeNew;
353 m_pDevMode = (m_hDevMode != NULL) ? (DEVMODE*)::GlobalLock(m_hDe vMode) : NULL;
354 }
355
356 HANDLE Detach()
357 {
358 if (m_hDevMode != NULL)
359 ::GlobalUnlock(m_hDevMode);
360 HANDLE hDevMode = m_hDevMode;
361 m_hDevMode = NULL;
362 return hDevMode;
363 }
364
365 bool IsNull() const { return (m_hDevMode == NULL); }
366
367 bool CopyFromPrinter(HANDLE hPrinter)
368 {
369 CPrinterInfo<2> pinfo;
370 bool b = pinfo.GetPrinterInfo(hPrinter);
371 if (b)
372 b = CopyFromDEVMODE(pinfo.m_pi->pDevMode);
373 return b;
374 }
375
376 bool CopyFromDEVMODE(const DEVMODE* pdm)
377 {
378 if (pdm == NULL)
379 return false;
380 int nSize = pdm->dmSize + pdm->dmDriverExtra;
381 HANDLE h = ::GlobalAlloc(GMEM_MOVEABLE, nSize);
382 if (h != NULL)
383 {
384 void* p = ::GlobalLock(h);
385 SecureHelper::memcpy_x(p, nSize, pdm, nSize);
386 ::GlobalUnlock(h);
387 }
388 Attach(h);
389 return (h != NULL);
390 }
391
392 bool CopyFromHDEVMODE(HANDLE hdm)
393 {
394 bool b = false;
395 if (hdm != NULL)
396 {
397 DEVMODE* pdm = (DEVMODE*)::GlobalLock(hdm);
398 b = CopyFromDEVMODE(pdm);
399 ::GlobalUnlock(hdm);
400 }
401 return b;
402 }
403
404 HANDLE CopyToHDEVMODE()
405 {
406 if ((m_hDevMode == NULL) || (m_pDevMode == NULL))
407 return NULL;
408 int nSize = m_pDevMode->dmSize + m_pDevMode->dmDriverExtra;
409 HANDLE h = ::GlobalAlloc(GMEM_MOVEABLE, nSize);
410 if (h != NULL)
411 {
412 void* p = ::GlobalLock(h);
413 SecureHelper::memcpy_x(p, nSize, m_pDevMode, nSize);
414 ::GlobalUnlock(h);
415 }
416 return h;
417 }
418
419 // If this devmode was for another printer, this will create a new devmo de
420 // based on the existing devmode, but retargeted at the new printer
421 bool UpdateForNewPrinter(HANDLE hPrinter)
422 {
423 bool bRet = false;
424 LONG nLen = ::DocumentProperties(NULL, hPrinter, NULL, NULL, NUL L, 0);
425 CTempBuffer<DEVMODE, _WTL_STACK_ALLOC_THRESHOLD> buff;
426 DEVMODE* pdm = buff.AllocateBytes(nLen);
427 if(pdm != NULL)
428 {
429 memset(pdm, 0, nLen);
430 LONG l = ::DocumentProperties(NULL, hPrinter, NULL, pdm, m_pDevMode, DM_IN_BUFFER | DM_OUT_BUFFER);
431 if (l == IDOK)
432 bRet = CopyFromDEVMODE(pdm);
433 }
434
435 return bRet;
436 }
437
438 bool DocumentProperties(HANDLE hPrinter, HWND hWnd = NULL)
439 {
440 CPrinterInfo<1> pi;
441 pi.GetPrinterInfo(hPrinter);
442 if (hWnd == NULL)
443 hWnd = ::GetActiveWindow();
444
445 bool bRet = false;
446 LONG nLen = ::DocumentProperties(hWnd, hPrinter, pi.m_pi->pName, NULL, NULL, 0);
447 CTempBuffer<DEVMODE, _WTL_STACK_ALLOC_THRESHOLD> buff;
448 DEVMODE* pdm = buff.AllocateBytes(nLen);
449 if(pdm != NULL)
450 {
451 memset(pdm, 0, nLen);
452 LONG l = ::DocumentProperties(hWnd, hPrinter, pi.m_pi->p Name, pdm, m_pDevMode, DM_IN_BUFFER | DM_OUT_BUFFER | DM_PROMPT);
453 if (l == IDOK)
454 bRet = CopyFromDEVMODE(pdm);
455 }
456
457 return bRet;
458 }
459
460 operator HANDLE() const { return m_hDevMode; }
461
462 operator DEVMODE*() const { return m_pDevMode; }
463
464 // Implementation
465 void Cleanup()
466 {
467 if (m_hDevMode != NULL)
468 {
469 ::GlobalUnlock(m_hDevMode);
470 if(t_bManaged)
471 ::GlobalFree(m_hDevMode);
472 m_hDevMode = NULL;
473 }
474 }
475 };
476
477 typedef CDevModeT<false> CDevModeHandle;
478 typedef CDevModeT<true> CDevMode;
479
480
481 ///////////////////////////////////////////////////////////////////////////////
482 // CPrinterDC
483
484 class CPrinterDC : public CDC
485 {
486 public:
487 // Constructors/destructor
488 CPrinterDC()
489 {
490 CPrinter printer;
491 printer.OpenDefaultPrinter();
492 Attach(printer.CreatePrinterDC());
493 ATLASSERT(m_hDC != NULL);
494 }
495
496 CPrinterDC(HANDLE hPrinter, const DEVMODE* pdm = NULL)
497 {
498 CPrinterHandle p;
499 p.Attach(hPrinter);
500 Attach(p.CreatePrinterDC(pdm));
501 ATLASSERT(m_hDC != NULL);
502 }
503
504 ~CPrinterDC()
505 {
506 DeleteDC();
507 }
508 };
509
510
511 ///////////////////////////////////////////////////////////////////////////////
512 // CPrintJob - Wraps a set of tasks for a specific printer (StartDoc/EndDoc)
513 // Handles aborting, background printing
514
515 // Defines callbacks used by CPrintJob (not a COM interface)
516 class ATL_NO_VTABLE IPrintJobInfo
517 {
518 public:
519 virtual void BeginPrintJob(HDC hDC) = 0; // allocate hand les needed, etc.
520 virtual void EndPrintJob(HDC hDC, bool bAborted) = 0; // free handles, etc.
521 virtual void PrePrintPage(UINT nPage, HDC hDC) = 0;
522 virtual bool PrintPage(UINT nPage, HDC hDC) = 0;
523 virtual void PostPrintPage(UINT nPage, HDC hDC) = 0;
524 // If you want per page devmodes, return the DEVMODE* to use for nPage.
525 // You can optimize by only returning a new DEVMODE* when it is differen t
526 // from the one for nLastPage, otherwise return NULL.
527 // When nLastPage==0, the current DEVMODE* will be the default passed to
528 // StartPrintJob.
529 // Note: During print preview, nLastPage will always be "0".
530 virtual DEVMODE* GetNewDevModeForPage(UINT nLastPage, UINT nPage) = 0;
531 virtual bool IsValidPage(UINT nPage) = 0;
532 };
533
534 // Provides a default implementatin for IPrintJobInfo
535 // Typically, MI'd into a document or view class
536 class ATL_NO_VTABLE CPrintJobInfo : public IPrintJobInfo
537 {
538 public:
539 virtual void BeginPrintJob(HDC /*hDC*/) // allocate handles needed, et c
540 {
541 }
542
543 virtual void EndPrintJob(HDC /*hDC*/, bool /*bAborted*/) // free handl es, etc
544 {
545 }
546
547 virtual void PrePrintPage(UINT /*nPage*/, HDC hDC)
548 {
549 m_nPJState = ::SaveDC(hDC);
550 }
551
552 virtual bool PrintPage(UINT /*nPage*/, HDC /*hDC*/) = 0;
553
554 virtual void PostPrintPage(UINT /*nPage*/, HDC hDC)
555 {
556 RestoreDC(hDC, m_nPJState);
557 }
558
559 virtual DEVMODE* GetNewDevModeForPage(UINT /*nLastPage*/, UINT /*nPage*/ )
560 {
561 return NULL;
562 }
563
564 virtual bool IsValidPage(UINT /*nPage*/)
565 {
566 return true;
567 }
568
569 // Implementation - data
570 int m_nPJState;
571 };
572
573
574 class CPrintJob
575 {
576 public:
577 // Data members
578 CPrinterHandle m_printer;
579 IPrintJobInfo* m_pInfo;
580 DEVMODE* m_pDefDevMode;
581 DOCINFO m_docinfo;
582 int m_nJobID;
583 bool m_bCancel;
584 bool m_bComplete;
585 unsigned long m_nStartPage;
586 unsigned long m_nEndPage;
587
588 // Constructor/destructor
589 CPrintJob() : m_nJobID(0), m_bCancel(false), m_bComplete(true)
590 { }
591
592 ~CPrintJob()
593 {
594 ATLASSERT(IsJobComplete()); // premature destruction?
595 }
596
597 // Operations
598 bool IsJobComplete() const
599 {
600 return m_bComplete;
601 }
602
603 bool StartPrintJob(bool bBackground, HANDLE hPrinter, DEVMODE* pDefaultD evMode,
604 IPrintJobInfo* pInfo, LPCTSTR lpszDocName,
605 unsigned long nStartPage, unsigned long nEndPage,
606 bool bPrintToFile = false, LPCTSTR lpstrOutputFile = NUL L)
607 {
608 ATLASSERT(m_bComplete); // previous job not done yet?
609 if (pInfo == NULL)
610 return false;
611
612 memset(&m_docinfo, 0, sizeof(m_docinfo));
613 m_docinfo.cbSize = sizeof(m_docinfo);
614 m_docinfo.lpszDocName = lpszDocName;
615 m_pInfo = pInfo;
616 m_nStartPage = nStartPage;
617 m_nEndPage = nEndPage;
618 m_printer.Attach(hPrinter);
619 m_pDefDevMode = pDefaultDevMode;
620 m_bComplete = false;
621
622 if(bPrintToFile)
623 m_docinfo.lpszOutput = (lpstrOutputFile != NULL) ? lpstr OutputFile : _T("FILE:");
624
625 if (!bBackground)
626 {
627 m_bComplete = true;
628 return StartHelper();
629 }
630
631 // Create a thread and return
632 DWORD dwThreadID = 0;
633 #if !defined(_ATL_MIN_CRT) && defined(_MT)
634 HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, (UINT (WINAPI*) (void*))StartProc, this, 0, (UINT*)&dwThreadID);
635 #else
636 HANDLE hThread = ::CreateThread(NULL, 0, StartProc, (void*)this, 0, &dwThreadID);
637 #endif
638 if (hThread == NULL)
639 return false;
640
641 ::CloseHandle(hThread);
642
643 return true;
644 }
645
646 // Implementation
647 static DWORD WINAPI StartProc(void* p)
648 {
649 CPrintJob* pThis = (CPrintJob*)p;
650 pThis->StartHelper();
651 pThis->m_bComplete = true;
652 return 0;
653 }
654
655 bool StartHelper()
656 {
657 CDC dcPrinter;
658 dcPrinter.Attach(m_printer.CreatePrinterDC(m_pDefDevMode));
659 if (dcPrinter.IsNull())
660 return false;
661
662 m_nJobID = ::StartDoc(dcPrinter, &m_docinfo);
663 if (m_nJobID <= 0)
664 return false;
665
666 m_pInfo->BeginPrintJob(dcPrinter);
667
668 // print all the pages now
669 unsigned long nLastPage = 0;
670 for (unsigned long nPage = m_nStartPage; nPage <= m_nEndPage; nP age++)
671 {
672 if (!m_pInfo->IsValidPage(nPage))
673 break;
674 DEVMODE* pdm = m_pInfo->GetNewDevModeForPage(nLastPage, nPage);
675 if (pdm != NULL)
676 dcPrinter.ResetDC(pdm);
677 dcPrinter.StartPage();
678 m_pInfo->PrePrintPage(nPage, dcPrinter);
679 if (!m_pInfo->PrintPage(nPage, dcPrinter))
680 m_bCancel = true;
681 m_pInfo->PostPrintPage(nPage, dcPrinter);
682 dcPrinter.EndPage();
683 if (m_bCancel)
684 break;
685 nLastPage = nPage;
686 }
687
688 m_pInfo->EndPrintJob(dcPrinter, m_bCancel);
689 if (m_bCancel)
690 ::AbortDoc(dcPrinter);
691 else
692 ::EndDoc(dcPrinter);
693 m_nJobID = 0;
694 return true;
695 }
696
697 // Cancels a print job. Can be called asynchronously.
698 void CancelPrintJob()
699 {
700 m_bCancel = true;
701 }
702 };
703
704
705 ///////////////////////////////////////////////////////////////////////////////
706 // CPrintPreview - Adds print preview support to an existing window
707
708 class CPrintPreview
709 {
710 public:
711 // Data members
712 IPrintJobInfo* m_pInfo;
713 CPrinterHandle m_printer;
714 CEnhMetaFile m_meta;
715 DEVMODE* m_pDefDevMode;
716 DEVMODE* m_pCurDevMode;
717 SIZE m_sizeCurPhysOffset;
718
719 // Constructor
720 CPrintPreview() : m_pInfo(NULL), m_pDefDevMode(NULL), m_pCurDevMode(NULL )
721 {
722 m_sizeCurPhysOffset.cx = 0;
723 m_sizeCurPhysOffset.cy = 0;
724 }
725
726 // Operations
727 void SetPrintPreviewInfo(HANDLE hPrinter, DEVMODE* pDefaultDevMode, IPri ntJobInfo* pji)
728 {
729 m_printer.Attach(hPrinter);
730 m_pDefDevMode = pDefaultDevMode;
731 m_pInfo = pji;
732 m_nCurPage = 0;
733 m_pCurDevMode = NULL;
734 }
735
736 void SetEnhMetaFile(HENHMETAFILE hEMF)
737 {
738 m_meta = hEMF;
739 }
740
741 void SetPage(int nPage)
742 {
743 if (!m_pInfo->IsValidPage(nPage))
744 return;
745 m_nCurPage = nPage;
746 m_pCurDevMode = m_pInfo->GetNewDevModeForPage(0, nPage);
747 if (m_pCurDevMode == NULL)
748 m_pCurDevMode = m_pDefDevMode;
749 CDC dcPrinter = m_printer.CreatePrinterDC(m_pCurDevMode);
750
751 int iWidth = dcPrinter.GetDeviceCaps(PHYSICALWIDTH);
752 int iHeight = dcPrinter.GetDeviceCaps(PHYSICALHEIGHT);
753 int nLogx = dcPrinter.GetDeviceCaps(LOGPIXELSX);
754 int nLogy = dcPrinter.GetDeviceCaps(LOGPIXELSY);
755
756 RECT rcMM = { 0, 0, ::MulDiv(iWidth, 2540, nLogx), ::MulDiv(iHei ght, 2540, nLogy) };
757
758 m_sizeCurPhysOffset.cx = dcPrinter.GetDeviceCaps(PHYSICALOFFSETX );
759 m_sizeCurPhysOffset.cy = dcPrinter.GetDeviceCaps(PHYSICALOFFSETY );
760
761 CEnhMetaFileDC dcMeta(dcPrinter, &rcMM);
762 m_pInfo->PrePrintPage(nPage, dcMeta);
763 m_pInfo->PrintPage(nPage, dcMeta);
764 m_pInfo->PostPrintPage(nPage, dcMeta);
765 m_meta.Attach(dcMeta.Close());
766 }
767
768 void GetPageRect(RECT& rc, LPRECT prc)
769 {
770 int x1 = rc.right-rc.left;
771 int y1 = rc.bottom - rc.top;
772 if ((x1 < 0) || (y1 < 0))
773 return;
774
775 CEnhMetaFileInfo emfinfo(m_meta);
776 ENHMETAHEADER* pmh = emfinfo.GetEnhMetaFileHeader();
777
778 // Compute whether we are OK vertically or horizontally
779 int x2 = pmh->szlDevice.cx;
780 int y2 = pmh->szlDevice.cy;
781 int y1p = MulDiv(x1, y2, x2);
782 int x1p = MulDiv(y1, x2, y2);
783 ATLASSERT((x1p <= x1) || (y1p <= y1));
784 if (x1p <= x1)
785 {
786 prc->left = rc.left + (x1 - x1p) / 2;
787 prc->right = prc->left + x1p;
788 prc->top = rc.top;
789 prc->bottom = rc.bottom;
790 }
791 else
792 {
793 prc->left = rc.left;
794 prc->right = rc.right;
795 prc->top = rc.top + (y1 - y1p) / 2;
796 prc->bottom = prc->top + y1p;
797 }
798 }
799
800 // Painting helpers
801 void DoPaint(CDCHandle dc)
802 {
803 // this one is not used
804 }
805
806 void DoPaint(CDCHandle dc, RECT& rc)
807 {
808 CEnhMetaFileInfo emfinfo(m_meta);
809 ENHMETAHEADER* pmh = emfinfo.GetEnhMetaFileHeader();
810 int nOffsetX = MulDiv(m_sizeCurPhysOffset.cx, rc.right-rc.left, pmh->szlDevice.cx);
811 int nOffsetY = MulDiv(m_sizeCurPhysOffset.cy, rc.bottom-rc.top, pmh->szlDevice.cy);
812
813 dc.OffsetWindowOrg(-nOffsetX, -nOffsetY);
814 dc.PlayMetaFile(m_meta, &rc);
815 }
816
817 // Implementation - data
818 int m_nCurPage;
819 };
820
821
822 ///////////////////////////////////////////////////////////////////////////////
823 // CPrintPreviewWindow - Implements a print preview window
824
825 template <class T, class TBase = ATL::CWindow, class TWinTraits = ATL::CControlW inTraits>
826 class ATL_NO_VTABLE CPrintPreviewWindowImpl : public ATL::CWindowImpl<T, TBase, TWinTraits>, public CPrintPreview
827 {
828 public:
829 DECLARE_WND_CLASS_EX(NULL, CS_VREDRAW | CS_HREDRAW, -1)
830
831 enum { m_cxOffset = 10, m_cyOffset = 10 };
832
833 // Constructor
834 CPrintPreviewWindowImpl() : m_nMaxPage(0), m_nMinPage(0)
835 { }
836
837 // Operations
838 void SetPrintPreviewInfo(HANDLE hPrinter, DEVMODE* pDefaultDevMode,
839 IPrintJobInfo* pji, int nMinPage, int nMaxPage)
840 {
841 CPrintPreview::SetPrintPreviewInfo(hPrinter, pDefaultDevMode, pj i);
842 m_nMinPage = nMinPage;
843 m_nMaxPage = nMaxPage;
844 }
845
846 bool NextPage()
847 {
848 if (m_nCurPage == m_nMaxPage)
849 return false;
850 SetPage(m_nCurPage + 1);
851 Invalidate();
852 return true;
853 }
854
855 bool PrevPage()
856 {
857 if (m_nCurPage == m_nMinPage)
858 return false;
859 if (m_nCurPage == 0)
860 return false;
861 SetPage(m_nCurPage - 1);
862 Invalidate();
863 return true;
864 }
865
866 // Message map and handlers
867 BEGIN_MSG_MAP(CPrintPreviewWindowImpl)
868 MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
869 MESSAGE_HANDLER(WM_PAINT, OnPaint)
870 MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint)
871 END_MSG_MAP()
872
873 LRESULT OnEraseBkgnd(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/ , BOOL& /*bHandled*/)
874 {
875 return 1; // no need for the background
876 }
877
878 LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& / *bHandled*/)
879 {
880 T* pT = static_cast<T*>(this);
881 RECT rc = { 0 };
882
883 if(wParam != NULL)
884 {
885 pT->DoPrePaint((HDC)wParam, rc);
886 pT->DoPaint((HDC)wParam, rc);
887 }
888 else
889 {
890 CPaintDC dc(m_hWnd);
891 pT->DoPrePaint(dc.m_hDC, rc);
892 pT->DoPaint(dc.m_hDC, rc);
893 }
894
895 return 0;
896 }
897
898 // Painting helper
899 void DoPrePaint(CDCHandle dc, RECT& rc)
900 {
901 RECT rcClient = { 0 };
902 GetClientRect(&rcClient);
903 RECT rcArea = rcClient;
904 T* pT = static_cast<T*>(this);
905 pT; // avoid level 4 warning
906 ::InflateRect(&rcArea, -pT->m_cxOffset, -pT->m_cyOffset);
907 if (rcArea.left > rcArea.right)
908 rcArea.right = rcArea.left;
909 if (rcArea.top > rcArea.bottom)
910 rcArea.bottom = rcArea.top;
911 GetPageRect(rcArea, &rc);
912 CRgn rgn1, rgn2;
913 rgn1.CreateRectRgnIndirect(&rc);
914 rgn2.CreateRectRgnIndirect(&rcClient);
915 rgn2.CombineRgn(rgn1, RGN_DIFF);
916 dc.SelectClipRgn(rgn2);
917 dc.FillRect(&rcClient, COLOR_BTNSHADOW);
918 dc.SelectClipRgn(NULL);
919 dc.FillRect(&rc, (HBRUSH)::GetStockObject(WHITE_BRUSH));
920 }
921
922 // Implementation - data
923 int m_nMinPage;
924 int m_nMaxPage;
925 };
926
927
928 class CPrintPreviewWindow : public CPrintPreviewWindowImpl<CPrintPreviewWindow>
929 {
930 public:
931 DECLARE_WND_CLASS_EX(_T("WTL_PrintPreview"), CS_VREDRAW | CS_HREDRAW, -1 )
932 };
933
934
935 ///////////////////////////////////////////////////////////////////////////////
936 // CZoomPrintPreviewWindowImpl - Implements print preview window with zooming
937
938 #ifdef __ATLSCRL_H__
939
940 template <class T, class TBase = ATL::CWindow, class TWinTraits = ATL::CControlW inTraits>
941 class ATL_NO_VTABLE CZoomPrintPreviewWindowImpl : public CPrintPreviewWindowImpl < T, TBase, TWinTraits >, public CZoomScrollImpl< T >
942 {
943 public:
944 bool m_bSized;
945
946 CZoomPrintPreviewWindowImpl()
947 {
948 SetScrollExtendedStyle(SCRL_DISABLENOSCROLL);
949 InitZoom();
950 }
951
952 // should be called to reset data members before recreating window
953 void InitZoom()
954 {
955 m_bSized = false;
956 m_nZoomMode = ZOOMMODE_OFF;
957 m_fZoomScaleMin = 1.0;
958 m_fZoomScale = 1.0;
959 }
960
961 BEGIN_MSG_MAP(CZoomPrintPreviewWindowImpl)
962 MESSAGE_HANDLER(WM_SETCURSOR, CZoomScrollImpl< T >::OnSetCursor)
963 MESSAGE_HANDLER(WM_VSCROLL, CScrollImpl< T >::OnVScroll)
964 MESSAGE_HANDLER(WM_HSCROLL, CScrollImpl< T >::OnHScroll)
965 MESSAGE_HANDLER(WM_MOUSEWHEEL, CScrollImpl< T >::OnMouseWheel)
966 #if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
967 MESSAGE_HANDLER(m_uMsgMouseWheel, CScrollImpl< T >::OnMouseWheel )
968 #endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
969 MESSAGE_HANDLER(WM_SETTINGCHANGE, CScrollImpl< T >::OnSettingCha nge)
970 MESSAGE_HANDLER(WM_LBUTTONDOWN, CZoomScrollImpl< T >::OnLButtonD own)
971 MESSAGE_HANDLER(WM_MOUSEMOVE, CZoomScrollImpl< T >::OnMouseMove)
972 MESSAGE_HANDLER(WM_LBUTTONUP, CZoomScrollImpl< T >::OnLButtonUp)
973 MESSAGE_HANDLER(WM_CAPTURECHANGED, CZoomScrollImpl< T >::OnCaptu reChanged)
974 MESSAGE_HANDLER(WM_SIZE, OnSize)
975 MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
976 MESSAGE_HANDLER(WM_PAINT, OnPaint)
977 MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint)
978 ALT_MSG_MAP(1)
979 COMMAND_ID_HANDLER(ID_SCROLL_UP, CScrollImpl< T >::OnScrollUp)
980 COMMAND_ID_HANDLER(ID_SCROLL_DOWN, CScrollImpl< T >::OnScrollDow n)
981 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_UP, CScrollImpl< T >::OnScroll PageUp)
982 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_DOWN, CScrollImpl< T >::OnScro llPageDown)
983 COMMAND_ID_HANDLER(ID_SCROLL_TOP, CScrollImpl< T >::OnScrollTop)
984 COMMAND_ID_HANDLER(ID_SCROLL_BOTTOM, CScrollImpl< T >::OnScrollB ottom)
985 COMMAND_ID_HANDLER(ID_SCROLL_LEFT, CScrollImpl< T >::OnScrollLef t)
986 COMMAND_ID_HANDLER(ID_SCROLL_RIGHT, CScrollImpl< T >::OnScrollRi ght)
987 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_LEFT, CScrollImpl< T >::OnScro llPageLeft)
988 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_RIGHT, CScrollImpl< T >::OnScr ollPageRight)
989 COMMAND_ID_HANDLER(ID_SCROLL_ALL_LEFT, CScrollImpl< T >::OnScrol lAllLeft)
990 COMMAND_ID_HANDLER(ID_SCROLL_ALL_RIGHT, CScrollImpl< T >::OnScro llAllRight)
991 END_MSG_MAP()
992
993 LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
994 {
995 SIZE sizeClient = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
996 POINT ptOffset = m_ptOffset;
997 SIZE sizeAll = m_sizeAll;
998 SetScrollSize(sizeClient);
999 if(sizeAll.cx > 0)
1000 ptOffset.x = ::MulDiv(ptOffset.x, m_sizeAll.cx, sizeAll. cx);
1001 if(sizeAll.cy > 0)
1002 ptOffset.y = ::MulDiv(ptOffset.y, m_sizeAll.cy, sizeAll. cy);
1003 SetScrollOffset(ptOffset);
1004 CScrollImpl< T >::OnSize(uMsg, wParam, lParam, bHandled);
1005 if(!m_bSized)
1006 {
1007 m_bSized = true;
1008 T* pT = static_cast<T*>(this);
1009 pT->ShowScrollBar(SB_HORZ, TRUE);
1010 pT->ShowScrollBar(SB_VERT, TRUE);
1011 }
1012 return 0;
1013 }
1014
1015 LRESULT OnEraseBkgnd(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/ , BOOL& /*bHandled*/)
1016 {
1017 return 1;
1018 }
1019
1020 LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& / *bHandled*/)
1021 {
1022 T* pT = static_cast<T*>(this);
1023 RECT rc = { 0 };
1024
1025 if(wParam != NULL)
1026 {
1027 CDCHandle dc = (HDC)wParam;
1028 int nMapModeSav = dc.GetMapMode();
1029 dc.SetMapMode(MM_ANISOTROPIC);
1030 SIZE szWindowExt = { 0, 0 };
1031 dc.SetWindowExt(m_sizeLogAll, &szWindowExt);
1032 SIZE szViewportExt = { 0, 0 };
1033 dc.SetViewportExt(m_sizeAll, &szViewportExt);
1034 POINT ptViewportOrg = { 0, 0 };
1035 dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y, &ptViewp ortOrg);
1036
1037 pT->DoPrePaint(dc, rc);
1038 pT->DoPaint(dc, rc);
1039
1040 dc.SetMapMode(nMapModeSav);
1041 dc.SetWindowExt(szWindowExt);
1042 dc.SetViewportExt(szViewportExt);
1043 dc.SetViewportOrg(ptViewportOrg);
1044 }
1045 else
1046 {
1047 CPaintDC dc(pT->m_hWnd);
1048 pT->PrepareDC(dc.m_hDC);
1049 pT->DoPrePaint(dc.m_hDC, rc);
1050 pT->DoPaint(dc.m_hDC, rc);
1051 }
1052
1053 return 0;
1054 }
1055
1056 // Painting helpers
1057 void DoPaint(CDCHandle dc)
1058 {
1059 // this one is not used
1060 }
1061
1062 void DoPrePaint(CDCHandle dc, RECT& rc)
1063 {
1064 RECT rcClient;
1065 GetClientRect(&rcClient);
1066 RECT rcArea = rcClient;
1067 T* pT = static_cast<T*>(this);
1068 pT; // avoid level 4 warning
1069 ::InflateRect(&rcArea, -pT->m_cxOffset, -pT->m_cyOffset);
1070 if (rcArea.left > rcArea.right)
1071 rcArea.right = rcArea.left;
1072 if (rcArea.top > rcArea.bottom)
1073 rcArea.bottom = rcArea.top;
1074 GetPageRect(rcArea, &rc);
1075 HBRUSH hbrOld = dc.SelectBrush(::GetSysColorBrush(COLOR_BTNSHADO W));
1076 dc.PatBlt(rcClient.left, rcClient.top, rc.left - rcClient.left, rcClient.bottom - rcClient.top, PATCOPY);
1077 dc.PatBlt(rc.left, rcClient.top, rc.right - rc.left, rc.top - rc Client.top, PATCOPY);
1078 dc.PatBlt(rc.right, rcClient.top, rcClient.right - rc.right, rcC lient.bottom - rcClient.top, PATCOPY);
1079 dc.PatBlt(rc.left, rc.bottom, rc.right - rc.left, rcClient.botto m - rc.bottom, PATCOPY);
1080 dc.SelectBrush((HBRUSH)::GetStockObject(WHITE_BRUSH));
1081 dc.PatBlt(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.to p, PATCOPY);
1082 dc.SelectBrush(::GetSysColorBrush(COLOR_3DDKSHADOW));
1083 dc.PatBlt(rc.right, rc.top + 4, 4, rc.bottom - rc.top, PATCOPY);
1084 dc.PatBlt(rc.left + 4, rc.bottom, rc.right - rc.left, 4, PATCOPY );
1085 dc.SelectBrush(hbrOld);
1086 }
1087
1088 void DoPaint(CDCHandle dc, RECT& rc)
1089 {
1090 CEnhMetaFileInfo emfinfo(m_meta);
1091 ENHMETAHEADER* pmh = emfinfo.GetEnhMetaFileHeader();
1092 int nOffsetX = MulDiv(m_sizeCurPhysOffset.cx, rc.right-rc.left, pmh->szlDevice.cx);
1093 int nOffsetY = MulDiv(m_sizeCurPhysOffset.cy, rc.bottom-rc.top, pmh->szlDevice.cy);
1094
1095 dc.OffsetWindowOrg(-nOffsetX, -nOffsetY);
1096 dc.PlayMetaFile(m_meta, &rc);
1097 }
1098 };
1099
1100 class CZoomPrintPreviewWindow : public CZoomPrintPreviewWindowImpl<CZoomPrintPre viewWindow>
1101 {
1102 public:
1103 DECLARE_WND_CLASS_EX(_T("WTL_ZoomPrintPreview"), CS_VREDRAW | CS_HREDRAW , -1)
1104 };
1105
1106 #endif // __ATLSCRL_H__
1107
1108 }; // namespace WTL
1109
1110 #endif // __ATLPRINT_H__
OLDNEW
« no previous file with comments | « third_party/wtl/include/atlmisc.h ('k') | third_party/wtl/include/atlres.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698