OLD | NEW |
| (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__ | |
OLD | NEW |