crashrpt
atlgdi.h
1 // Windows Template Library - WTL version 8.1
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 // Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php)
7 // which can be found in the file CPL.TXT at the root of this distribution.
8 // By using this software in any fashion, you are agreeing to be bound by
9 // the terms of this license. You must not remove this notice, or
10 // any other, from this software.
11 
12 #ifndef __ATLGDI_H__
13 #define __ATLGDI_H__
14 
15 #pragma once
16 
17 #ifndef __ATLAPP_H__
18  #error atlgdi.h requires atlapp.h to be included first
19 #endif
20 
21 
22 // protect template members from windowsx.h macros
23 #ifdef _INC_WINDOWSX
24  #undef CopyRgn
25  #undef CreateBrush
26  #undef CreatePen
27  #undef SelectBrush
28  #undef SelectPen
29  #undef SelectFont
30  #undef SelectBitmap
31 #endif // _INC_WINDOWSX
32 
33 // required libraries
34 #if !defined(_ATL_NO_MSIMG) && !defined(_WIN32_WCE)
35  #pragma comment(lib, "msimg32.lib")
36 #endif // !defined(_ATL_NO_MSIMG) && !defined(_WIN32_WCE)
37 #if !defined(_ATL_NO_OPENGL) && !defined(_WIN32_WCE)
38  #pragma comment(lib, "opengl32.lib")
39 #endif // !defined(_ATL_NO_OPENGL) && !defined(_WIN32_WCE)
40 
41 
43 // Classes in this file:
44 //
45 // CPenT<t_bManaged>
46 // CBrushT<t_bManaged>
47 // CLogFont
48 // CFontT<t_bManaged>
49 // CBitmapT<t_bManaged>
50 // CPaletteT<t_bManaged>
51 // CRgnT<t_bManaged>
52 // CDCT<t_bManaged>
53 // CPaintDC
54 // CClientDC
55 // CWindowDC
56 // CMemoryDC
57 // CEnhMetaFileInfo
58 // CEnhMetaFileT<t_bManaged>
59 // CEnhMetaFileDC
60 //
61 // Global functions:
62 // AtlGetBitmapResourceInfo()
63 // AtlGetBitmapResourceBitsPerPixel()
64 // AtlIsAlphaBitmapResource()
65 // AtlIsDib16()
66 // AtlGetDibColorTableSize()
67 // AtlGetDibNumColors(),
68 // AtlGetDibBitmap()
69 // AtlCopyBitmap()
70 // AtlCreatePackedDib16()
71 // AtlSetClipboardDib16()
72 // AtlGetClipboardDib()
73 
74 
75 namespace WTL
76 {
77 
79 // Bitmap resource helpers to extract bitmap information for a bitmap resource
80 
81 inline LPBITMAPINFOHEADER AtlGetBitmapResourceInfo(HMODULE hModule, ATL::_U_STRINGorID image)
82 {
83  HRSRC hResource = ::FindResource(hModule, image.m_lpstr, RT_BITMAP);
84  ATLASSERT(hResource != NULL);
85  HGLOBAL hGlobal = ::LoadResource(hModule, hResource);
86  ATLASSERT(hGlobal != NULL);
87  LPBITMAPINFOHEADER pBitmapInfoHeader = (LPBITMAPINFOHEADER)::LockResource(hGlobal);
88  ATLASSERT(pBitmapInfoHeader != NULL);
89  return pBitmapInfoHeader;
90 }
91 
92 inline WORD AtlGetBitmapResourceBitsPerPixel(HMODULE hModule, ATL::_U_STRINGorID image)
93 {
94  LPBITMAPINFOHEADER pBitmapInfoHeader = AtlGetBitmapResourceInfo(hModule, image);
95  ATLASSERT(pBitmapInfoHeader != NULL);
96  return pBitmapInfoHeader->biBitCount;
97 }
98 
99 inline WORD AtlGetBitmapResourceBitsPerPixel(ATL::_U_STRINGorID image)
100 {
101  return AtlGetBitmapResourceBitsPerPixel(ModuleHelper::GetResourceInstance(), image);
102 }
103 
105 // 32-bit (alpha channel) bitmap resource helper
106 
107 // Note: 32-bit (alpha channel) images work only on Windows XP with Common Controls version 6.
108 // If you want your app to work on older version of Windows, load non-alpha images if Common
109 // Controls version is less than 6.
110 
111 inline bool AtlIsAlphaBitmapResource(ATL::_U_STRINGorID image)
112 {
113  return (AtlGetBitmapResourceBitsPerPixel(image) == 32);
114 }
115 
116 
118 // CPen
119 
120 template <bool t_bManaged>
121 class CPenT
122 {
123 public:
124 // Data members
125  HPEN m_hPen;
126 
127 // Constructor/destructor/operators
128  CPenT(HPEN hPen = NULL) : m_hPen(hPen)
129  { }
130 
131  ~CPenT()
132  {
133  if(t_bManaged && m_hPen != NULL)
134  DeleteObject();
135  }
136 
137  CPenT<t_bManaged>& operator =(HPEN hPen)
138  {
139  Attach(hPen);
140  return *this;
141  }
142 
143  void Attach(HPEN hPen)
144  {
145  if(t_bManaged && m_hPen != NULL && m_hPen != hPen)
146  ::DeleteObject(m_hPen);
147  m_hPen = hPen;
148  }
149 
150  HPEN Detach()
151  {
152  HPEN hPen = m_hPen;
153  m_hPen = NULL;
154  return hPen;
155  }
156 
157  operator HPEN() const { return m_hPen; }
158 
159  bool IsNull() const { return (m_hPen == NULL); }
160 
161 // Create methods
162  HPEN CreatePen(int nPenStyle, int nWidth, COLORREF crColor)
163  {
164  ATLASSERT(m_hPen == NULL);
165  m_hPen = ::CreatePen(nPenStyle, nWidth, crColor);
166  return m_hPen;
167  }
168 
169 #ifndef _WIN32_WCE
170  HPEN CreatePen(int nPenStyle, int nWidth, const LOGBRUSH* pLogBrush, int nStyleCount = 0, const DWORD* lpStyle = NULL)
171  {
172  ATLASSERT(m_hPen == NULL);
173  m_hPen = ::ExtCreatePen(nPenStyle, nWidth, pLogBrush, nStyleCount, lpStyle);
174  return m_hPen;
175  }
176 #endif // !_WIN32_WCE
177 
178  HPEN CreatePenIndirect(LPLOGPEN lpLogPen)
179  {
180  ATLASSERT(m_hPen == NULL);
181  m_hPen = ::CreatePenIndirect(lpLogPen);
182  return m_hPen;
183  }
184 
185  BOOL DeleteObject()
186  {
187  ATLASSERT(m_hPen != NULL);
188  BOOL bRet = ::DeleteObject(m_hPen);
189  if(bRet)
190  m_hPen = NULL;
191  return bRet;
192  }
193 
194 // Attributes
195  int GetLogPen(LOGPEN* pLogPen) const
196  {
197  ATLASSERT(m_hPen != NULL);
198  return ::GetObject(m_hPen, sizeof(LOGPEN), pLogPen);
199  }
200 
201  bool GetLogPen(LOGPEN& LogPen) const
202  {
203  ATLASSERT(m_hPen != NULL);
204  return (::GetObject(m_hPen, sizeof(LOGPEN), &LogPen) == sizeof(LOGPEN));
205  }
206 
207 #ifndef _WIN32_WCE
208  int GetExtLogPen(EXTLOGPEN* pLogPen) const
209  {
210  ATLASSERT(m_hPen != NULL);
211  return ::GetObject(m_hPen, sizeof(EXTLOGPEN), pLogPen);
212  }
213 
214  bool GetExtLogPen(EXTLOGPEN& ExtLogPen) const
215  {
216  ATLASSERT(m_hPen != NULL);
217  return (::GetObject(m_hPen, sizeof(EXTLOGPEN), &ExtLogPen) == sizeof(EXTLOGPEN));
218  }
219 #endif // !_WIN32_WCE
220 };
221 
222 typedef CPenT<false> CPenHandle;
223 typedef CPenT<true> CPen;
224 
225 
227 // CBrush
228 
229 template <bool t_bManaged>
230 class CBrushT
231 {
232 public:
233 // Data members
234  HBRUSH m_hBrush;
235 
236 // Constructor/destructor/operators
237  CBrushT(HBRUSH hBrush = NULL) : m_hBrush(hBrush)
238  { }
239 
240  ~CBrushT()
241  {
242  if(t_bManaged && m_hBrush != NULL)
243  DeleteObject();
244  }
245 
246  CBrushT<t_bManaged>& operator =(HBRUSH hBrush)
247  {
248  Attach(hBrush);
249  return *this;
250  }
251 
252  void Attach(HBRUSH hBrush)
253  {
254  if(t_bManaged && m_hBrush != NULL && m_hBrush != hBrush)
255  ::DeleteObject(m_hBrush);
256  m_hBrush = hBrush;
257  }
258 
259  HBRUSH Detach()
260  {
261  HBRUSH hBrush = m_hBrush;
262  m_hBrush = NULL;
263  return hBrush;
264  }
265 
266  operator HBRUSH() const { return m_hBrush; }
267 
268  bool IsNull() const { return (m_hBrush == NULL); }
269 
270 // Create methods
271  HBRUSH CreateSolidBrush(COLORREF crColor)
272  {
273  ATLASSERT(m_hBrush == NULL);
274  m_hBrush = ::CreateSolidBrush(crColor);
275  return m_hBrush;
276  }
277 
278 #ifndef _WIN32_WCE
279  HBRUSH CreateHatchBrush(int nIndex, COLORREF crColor)
280  {
281  ATLASSERT(m_hBrush == NULL);
282  m_hBrush = ::CreateHatchBrush(nIndex, crColor);
283  return m_hBrush;
284  }
285 #endif // !_WIN32_WCE
286 
287 #if !defined(_WIN32_WCE) || (_ATL_VER >= 0x0800)
288  HBRUSH CreateBrushIndirect(const LOGBRUSH* lpLogBrush)
289  {
290  ATLASSERT(m_hBrush == NULL);
291 #ifndef _WIN32_WCE
292  m_hBrush = ::CreateBrushIndirect(lpLogBrush);
293 #else // CE specific
294  m_hBrush = ATL::CreateBrushIndirect(lpLogBrush);
295 #endif // _WIN32_WCE
296  return m_hBrush;
297  }
298 #endif // !defined(_WIN32_WCE) || (_ATL_VER >= 0x0800)
299 
300  HBRUSH CreatePatternBrush(HBITMAP hBitmap)
301  {
302  ATLASSERT(m_hBrush == NULL);
303  m_hBrush = ::CreatePatternBrush(hBitmap);
304  return m_hBrush;
305  }
306 
307  HBRUSH CreateDIBPatternBrush(HGLOBAL hPackedDIB, UINT nUsage)
308  {
309  ATLASSERT(hPackedDIB != NULL);
310  const void* lpPackedDIB = GlobalLock(hPackedDIB);
311  ATLASSERT(lpPackedDIB != NULL);
312  m_hBrush = ::CreateDIBPatternBrushPt(lpPackedDIB, nUsage);
313  GlobalUnlock(hPackedDIB);
314  return m_hBrush;
315  }
316 
317  HBRUSH CreateDIBPatternBrush(const void* lpPackedDIB, UINT nUsage)
318  {
319  ATLASSERT(m_hBrush == NULL);
320  m_hBrush = ::CreateDIBPatternBrushPt(lpPackedDIB, nUsage);
321  return m_hBrush;
322  }
323 
324  HBRUSH CreateSysColorBrush(int nIndex)
325  {
326  ATLASSERT(m_hBrush == NULL);
327  m_hBrush = ::GetSysColorBrush(nIndex);
328  return m_hBrush;
329  }
330 
331  BOOL DeleteObject()
332  {
333  ATLASSERT(m_hBrush != NULL);
334  BOOL bRet = ::DeleteObject(m_hBrush);
335  if(bRet)
336  m_hBrush = NULL;
337  return bRet;
338  }
339 
340 // Attributes
341  int GetLogBrush(LOGBRUSH* pLogBrush) const
342  {
343  ATLASSERT(m_hBrush != NULL);
344  return ::GetObject(m_hBrush, sizeof(LOGBRUSH), pLogBrush);
345  }
346 
347  bool GetLogBrush(LOGBRUSH& LogBrush) const
348  {
349  ATLASSERT(m_hBrush != NULL);
350  return (::GetObject(m_hBrush, sizeof(LOGBRUSH), &LogBrush) == sizeof(LOGBRUSH));
351  }
352 };
353 
355 typedef CBrushT<true> CBrush;
356 
357 
359 // CFont
360 
361 class CLogFont : public LOGFONT
362 {
363 public:
364  CLogFont()
365  {
366  memset(this, 0, sizeof(LOGFONT));
367  }
368 
369  CLogFont(const LOGFONT& lf)
370  {
371  Copy(&lf);
372  }
373 
374  CLogFont(HFONT hFont)
375  {
376  ATLASSERT(::GetObjectType(hFont) == OBJ_FONT);
377  ::GetObject(hFont, sizeof(LOGFONT), (LOGFONT*)this);
378  }
379 
380  HFONT CreateFontIndirect()
381  {
382  return ::CreateFontIndirect(this);
383  }
384 
385  void SetBold()
386  {
387  lfWeight = FW_BOLD;
388  }
389 
390  bool IsBold() const
391  {
392  return (lfWeight >= FW_BOLD);
393  }
394 
395  void MakeBolder(int iScale = 1)
396  {
397  lfWeight += FW_BOLD * iScale;
398  }
399 
400  void MakeLarger(int iScale)
401  {
402  if(lfHeight > 0)
403  lfHeight += iScale;
404  else
405  lfHeight -= iScale;
406  }
407 
408  void SetHeight(LONG nPointSize, HDC hDC = NULL)
409  {
410  HDC hDC1 = (hDC != NULL) ? hDC : ::GetDC(NULL);
411  // For MM_TEXT mapping mode
412  lfHeight = -::MulDiv(nPointSize, ::GetDeviceCaps(hDC1, LOGPIXELSY), 72);
413  if(hDC == NULL)
414  ::ReleaseDC(NULL, hDC1);
415  }
416 
417  LONG GetHeight(HDC hDC = NULL) const
418  {
419  HDC hDC1 = (hDC != NULL) ? hDC : ::GetDC(NULL);
420  // For MM_TEXT mapping mode
421  LONG nPointSize = ::MulDiv(-lfHeight, 72, ::GetDeviceCaps(hDC1, LOGPIXELSY));
422  if(hDC == NULL)
423  ::ReleaseDC(NULL, hDC1);
424 
425  return nPointSize;
426  }
427 
428  LONG GetDeciPointHeight(HDC hDC = NULL) const
429  {
430  HDC hDC1 = (hDC != NULL) ? hDC : ::GetDC(NULL);
431 #ifndef _WIN32_WCE
432  POINT ptOrg = { 0, 0 };
433  ::DPtoLP(hDC1, &ptOrg, 1);
434  POINT pt = { 0, 0 };
435  pt.y = abs(lfHeight) + ptOrg.y;
436  ::LPtoDP(hDC1, &pt,1);
437  LONG nDeciPoint = ::MulDiv(pt.y, 720, ::GetDeviceCaps(hDC1, LOGPIXELSY)); // 72 points/inch, 10 decipoints/point
438 #else // CE specific
439  // DP and LP are always the same on CE
440  LONG nDeciPoint = ::MulDiv(abs(lfHeight), 720, ::GetDeviceCaps(hDC1, LOGPIXELSY)); // 72 points/inch, 10 decipoints/point
441 #endif // _WIN32_WCE
442  if(hDC == NULL)
443  ::ReleaseDC(NULL, hDC1);
444 
445  return nDeciPoint;
446  }
447 
448  void SetHeightFromDeciPoint(LONG nDeciPtHeight, HDC hDC = NULL)
449  {
450  HDC hDC1 = (hDC != NULL) ? hDC : ::GetDC(NULL);
451 #ifndef _WIN32_WCE
452  POINT pt = { 0, 0 };
453  pt.y = ::MulDiv(::GetDeviceCaps(hDC1, LOGPIXELSY), nDeciPtHeight, 720); // 72 points/inch, 10 decipoints/point
454  ::DPtoLP(hDC1, &pt, 1);
455  POINT ptOrg = { 0, 0 };
456  ::DPtoLP(hDC1, &ptOrg, 1);
457  lfHeight = -abs(pt.y - ptOrg.y);
458 #else // CE specific
459  // DP and LP are always the same on CE
460  lfHeight = -abs(::MulDiv(::GetDeviceCaps(hDC1, LOGPIXELSY), nDeciPtHeight, 720)); // 72 points/inch, 10 decipoints/point
461 #endif // _WIN32_WCE
462  if(hDC == NULL)
463  ::ReleaseDC(NULL, hDC1);
464  }
465 
466 #ifndef _WIN32_WCE
467  void SetCaptionFont()
468  {
469  NONCLIENTMETRICS ncm = { RunTimeHelper::SizeOf_NONCLIENTMETRICS() };
470  ATLVERIFY(::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0));
471  Copy(&ncm.lfCaptionFont);
472  }
473 
474  void SetMenuFont()
475  {
476  NONCLIENTMETRICS ncm = { RunTimeHelper::SizeOf_NONCLIENTMETRICS() };
477  ATLVERIFY(::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0));
478  Copy(&ncm.lfMenuFont);
479  }
480 
481  void SetStatusFont()
482  {
483  NONCLIENTMETRICS ncm = { RunTimeHelper::SizeOf_NONCLIENTMETRICS() };
484  ATLVERIFY(::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0));
485  Copy(&ncm.lfStatusFont);
486  }
487 
488  void SetMessageBoxFont()
489  {
490  NONCLIENTMETRICS ncm = { RunTimeHelper::SizeOf_NONCLIENTMETRICS() };
491  ATLVERIFY(::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0));
492  Copy(&ncm.lfMessageFont);
493  }
494 #endif // !_WIN32_WCE
495 
496  void Copy(const LOGFONT* pLogFont)
497  {
498  ATLASSERT(pLogFont != NULL);
499  *(LOGFONT*)this = *pLogFont;
500  }
501 
502  CLogFont& operator =(const CLogFont& src)
503  {
504  Copy(&src);
505  return *this;
506  }
507 
508  CLogFont& operator =(const LOGFONT& src)
509  {
510  Copy(&src);
511  return *this;
512  }
513 
514  CLogFont& operator =(HFONT hFont)
515  {
516  ATLASSERT(::GetObjectType(hFont) == OBJ_FONT);
517  ::GetObject(hFont, sizeof(LOGFONT), (LOGFONT*)this);
518  return *this;
519  }
520 
521  bool operator ==(const LOGFONT& logfont) const
522  {
523  return(logfont.lfHeight == lfHeight &&
524  logfont.lfWidth == lfWidth &&
525  logfont.lfEscapement == lfEscapement &&
526  logfont.lfOrientation == lfOrientation &&
527  logfont.lfWeight == lfWeight &&
528  logfont.lfItalic == lfItalic &&
529  logfont.lfUnderline == lfUnderline &&
530  logfont.lfStrikeOut == lfStrikeOut &&
531  logfont.lfCharSet == lfCharSet &&
532  logfont.lfOutPrecision == lfOutPrecision &&
533  logfont.lfClipPrecision == lfClipPrecision &&
534  logfont.lfQuality == lfQuality &&
535  logfont.lfPitchAndFamily == lfPitchAndFamily &&
536  lstrcmp(logfont.lfFaceName, lfFaceName) == 0);
537  }
538 };
539 
540 
541 template <bool t_bManaged>
542 class CFontT
543 {
544 public:
545 // Data members
546  HFONT m_hFont;
547 
548 // Constructor/destructor/operators
549  CFontT(HFONT hFont = NULL) : m_hFont(hFont)
550  { }
551 
552  ~CFontT()
553  {
554  if(t_bManaged && m_hFont != NULL)
555  DeleteObject();
556  }
557 
558  CFontT<t_bManaged>& operator =(HFONT hFont)
559  {
560  Attach(hFont);
561  return *this;
562  }
563 
564  void Attach(HFONT hFont)
565  {
566  if(t_bManaged && m_hFont != NULL && m_hFont != hFont)
567  ::DeleteObject(m_hFont);
568  m_hFont = hFont;
569  }
570 
571  HFONT Detach()
572  {
573  HFONT hFont = m_hFont;
574  m_hFont = NULL;
575  return hFont;
576  }
577 
578  operator HFONT() const { return m_hFont; }
579 
580  bool IsNull() const { return (m_hFont == NULL); }
581 
582 // Create methods
583  HFONT CreateFontIndirect(const LOGFONT* lpLogFont)
584  {
585  ATLASSERT(m_hFont == NULL);
586  m_hFont = ::CreateFontIndirect(lpLogFont);
587  return m_hFont;
588  }
589 
590 #if !defined(_WIN32_WCE) && (_WIN32_WINNT >= 0x0500)
591  HFONT CreateFontIndirectEx(CONST ENUMLOGFONTEXDV* penumlfex)
592  {
593  ATLASSERT(m_hFont == NULL);
594  m_hFont = ::CreateFontIndirectEx(penumlfex);
595  return m_hFont;
596  }
597 #endif // !defined(_WIN32_WCE) && (_WIN32_WINNT >= 0x0500)
598 
599 #if !defined(_WIN32_WCE) || (_ATL_VER >= 0x0800)
600  HFONT CreateFont(int nHeight, int nWidth, int nEscapement,
601  int nOrientation, int nWeight, BYTE bItalic, BYTE bUnderline,
602  BYTE cStrikeOut, BYTE nCharSet, BYTE nOutPrecision,
603  BYTE nClipPrecision, BYTE nQuality, BYTE nPitchAndFamily,
604  LPCTSTR lpszFacename)
605  {
606  ATLASSERT(m_hFont == NULL);
607 #ifndef _WIN32_WCE
608  m_hFont = ::CreateFont(nHeight, nWidth, nEscapement,
609  nOrientation, nWeight, bItalic, bUnderline, cStrikeOut,
610  nCharSet, nOutPrecision, nClipPrecision, nQuality,
611  nPitchAndFamily, lpszFacename);
612 #else // CE specific
613  m_hFont = ATL::CreateFont(nHeight, nWidth, nEscapement,
614  nOrientation, nWeight, bItalic, bUnderline, cStrikeOut,
615  nCharSet, nOutPrecision, nClipPrecision, nQuality,
616  nPitchAndFamily, lpszFacename);
617 #endif // _WIN32_WCE
618  return m_hFont;
619  }
620 #endif // !defined(_WIN32_WCE) || (_ATL_VER >= 0x0800)
621 
622  HFONT CreatePointFont(int nPointSize, LPCTSTR lpszFaceName, HDC hDC = NULL, bool bBold = false, bool bItalic = false)
623  {
624  LOGFONT logFont = { 0 };
625  logFont.lfCharSet = DEFAULT_CHARSET;
626  logFont.lfHeight = nPointSize;
627  SecureHelper::strncpy_x(logFont.lfFaceName, _countof(logFont.lfFaceName), lpszFaceName, _TRUNCATE);
628 
629  if(bBold)
630  logFont.lfWeight = FW_BOLD;
631  if(bItalic)
632  logFont.lfItalic = (BYTE)TRUE;
633 
634  return CreatePointFontIndirect(&logFont, hDC);
635  }
636 
637  HFONT CreatePointFontIndirect(const LOGFONT* lpLogFont, HDC hDC = NULL)
638  {
639  HDC hDC1 = (hDC != NULL) ? hDC : ::GetDC(NULL);
640 
641  // convert nPointSize to logical units based on hDC
642  LOGFONT logFont = *lpLogFont;
643 #ifndef _WIN32_WCE
644  POINT pt = { 0, 0 };
645  pt.y = ::MulDiv(::GetDeviceCaps(hDC1, LOGPIXELSY), logFont.lfHeight, 720); // 72 points/inch, 10 decipoints/point
646  ::DPtoLP(hDC1, &pt, 1);
647  POINT ptOrg = { 0, 0 };
648  ::DPtoLP(hDC1, &ptOrg, 1);
649  logFont.lfHeight = -abs(pt.y - ptOrg.y);
650 #else // CE specific
651  // DP and LP are always the same on CE
652  logFont.lfHeight = -abs(::MulDiv(::GetDeviceCaps(hDC1, LOGPIXELSY), logFont.lfHeight, 720)); // 72 points/inch, 10 decipoints/point
653 #endif // _WIN32_WCE
654 
655  if(hDC == NULL)
656  ::ReleaseDC(NULL, hDC1);
657 
658  return CreateFontIndirect(&logFont);
659  }
660 
661  BOOL DeleteObject()
662  {
663  ATLASSERT(m_hFont != NULL);
664  BOOL bRet = ::DeleteObject(m_hFont);
665  if(bRet)
666  m_hFont = NULL;
667  return bRet;
668  }
669 
670 // Attributes
671  int GetLogFont(LOGFONT* pLogFont) const
672  {
673  ATLASSERT(m_hFont != NULL);
674  return ::GetObject(m_hFont, sizeof(LOGFONT), pLogFont);
675  }
676 
677  bool GetLogFont(LOGFONT& LogFont) const
678  {
679  ATLASSERT(m_hFont != NULL);
680  return (::GetObject(m_hFont, sizeof(LOGFONT), &LogFont) == sizeof(LOGFONT));
681  }
682 };
683 
684 typedef CFontT<false> CFontHandle;
685 typedef CFontT<true> CFont;
686 
687 
689 // CBitmap
690 
691 template <bool t_bManaged>
692 class CBitmapT
693 {
694 public:
695 // Data members
696  HBITMAP m_hBitmap;
697 
698 // Constructor/destructor/operators
699  CBitmapT(HBITMAP hBitmap = NULL) : m_hBitmap(hBitmap)
700  { }
701 
702  ~CBitmapT()
703  {
704  if(t_bManaged && m_hBitmap != NULL)
705  DeleteObject();
706  }
707 
708  CBitmapT<t_bManaged>& operator =(HBITMAP hBitmap)
709  {
710  Attach(hBitmap);
711  return *this;
712  }
713 
714  void Attach(HBITMAP hBitmap)
715  {
716  if(t_bManaged && m_hBitmap != NULL&& m_hBitmap != hBitmap)
717  ::DeleteObject(m_hBitmap);
718  m_hBitmap = hBitmap;
719  }
720 
721  HBITMAP Detach()
722  {
723  HBITMAP hBitmap = m_hBitmap;
724  m_hBitmap = NULL;
725  return hBitmap;
726  }
727 
728  operator HBITMAP() const { return m_hBitmap; }
729 
730  bool IsNull() const { return (m_hBitmap == NULL); }
731 
732 // Create and load methods
733  HBITMAP LoadBitmap(ATL::_U_STRINGorID bitmap)
734  {
735  ATLASSERT(m_hBitmap == NULL);
736  m_hBitmap = ::LoadBitmap(ModuleHelper::GetResourceInstance(), bitmap.m_lpstr);
737  return m_hBitmap;
738  }
739 
740  HBITMAP LoadOEMBitmap(UINT nIDBitmap) // for OBM_/OCR_/OIC_
741  {
742  ATLASSERT(m_hBitmap == NULL);
743  m_hBitmap = ::LoadBitmap(NULL, MAKEINTRESOURCE(nIDBitmap));
744  return m_hBitmap;
745  }
746 
747 #ifndef _WIN32_WCE
748  HBITMAP LoadMappedBitmap(UINT nIDBitmap, UINT nFlags = 0, LPCOLORMAP lpColorMap = NULL, int nMapSize = 0)
749  {
750  ATLASSERT(m_hBitmap == NULL);
751  m_hBitmap = ::CreateMappedBitmap(ModuleHelper::GetResourceInstance(), nIDBitmap, (WORD)nFlags, lpColorMap, nMapSize);
752  return m_hBitmap;
753  }
754 #endif // !_WIN32_WCE
755 
756  HBITMAP CreateBitmap(int nWidth, int nHeight, UINT nPlanes, UINT nBitsPerPixel, const void* lpBits)
757  {
758  ATLASSERT(m_hBitmap == NULL);
759  m_hBitmap = ::CreateBitmap(nWidth, nHeight, nPlanes, nBitsPerPixel, lpBits);
760  return m_hBitmap;
761  }
762 
763 #ifndef _WIN32_WCE
764  HBITMAP CreateBitmapIndirect(LPBITMAP lpBitmap)
765  {
766  ATLASSERT(m_hBitmap == NULL);
767  m_hBitmap = ::CreateBitmapIndirect(lpBitmap);
768  return m_hBitmap;
769  }
770 #endif // !_WIN32_WCE
771 
772  HBITMAP CreateCompatibleBitmap(HDC hDC, int nWidth, int nHeight)
773  {
774  ATLASSERT(m_hBitmap == NULL);
775  m_hBitmap = ::CreateCompatibleBitmap(hDC, nWidth, nHeight);
776  return m_hBitmap;
777  }
778 
779 #ifndef _WIN32_WCE
780  HBITMAP CreateDiscardableBitmap(HDC hDC, int nWidth, int nHeight)
781  {
782  ATLASSERT(m_hBitmap == NULL);
783  m_hBitmap = ::CreateDiscardableBitmap(hDC, nWidth, nHeight);
784  return m_hBitmap;
785  }
786 #endif // !_WIN32_WCE
787 
788  BOOL DeleteObject()
789  {
790  ATLASSERT(m_hBitmap != NULL);
791  BOOL bRet = ::DeleteObject(m_hBitmap);
792  if(bRet)
793  m_hBitmap = NULL;
794  return bRet;
795  }
796 
797 // Attributes
798  int GetBitmap(BITMAP* pBitMap) const
799  {
800  ATLASSERT(m_hBitmap != NULL);
801  return ::GetObject(m_hBitmap, sizeof(BITMAP), pBitMap);
802  }
803 
804  bool GetBitmap(BITMAP& bm) const
805  {
806  ATLASSERT(m_hBitmap != NULL);
807  return (::GetObject(m_hBitmap, sizeof(BITMAP), &bm) == sizeof(BITMAP));
808  }
809 
810  bool GetSize(SIZE& size) const
811  {
812  ATLASSERT(m_hBitmap != NULL);
813  BITMAP bm = { 0 };
814  if(!GetBitmap(&bm))
815  return false;
816  size.cx = bm.bmWidth;
817  size.cy = bm.bmHeight;
818  return true;
819  }
820 
821 #ifndef _WIN32_WCE
822  DWORD GetBitmapBits(DWORD dwCount, LPVOID lpBits) const
823  {
824  ATLASSERT(m_hBitmap != NULL);
825  return ::GetBitmapBits(m_hBitmap, dwCount, lpBits);
826  }
827 #endif // !_WIN32_WCE
828 
829 #if !defined(_WIN32_WCE) || (_WIN32_WCE >= 410)
830  DWORD SetBitmapBits(DWORD dwCount, const void* lpBits)
831  {
832  ATLASSERT(m_hBitmap != NULL);
833  return ::SetBitmapBits(m_hBitmap, dwCount, lpBits);
834  }
835 #endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 410)
836 
837 #ifndef _WIN32_WCE
838  BOOL GetBitmapDimension(LPSIZE lpSize) const
839  {
840  ATLASSERT(m_hBitmap != NULL);
841  return ::GetBitmapDimensionEx(m_hBitmap, lpSize);
842  }
843 
844  BOOL SetBitmapDimension(int nWidth, int nHeight, LPSIZE lpSize = NULL)
845  {
846  ATLASSERT(m_hBitmap != NULL);
847  return ::SetBitmapDimensionEx(m_hBitmap, nWidth, nHeight, lpSize);
848  }
849 
850 // DIB support
851  HBITMAP CreateDIBitmap(HDC hDC, CONST BITMAPINFOHEADER* lpbmih, DWORD dwInit, CONST VOID* lpbInit, CONST BITMAPINFO* lpbmi, UINT uColorUse)
852  {
853  ATLASSERT(m_hBitmap == NULL);
854  m_hBitmap = ::CreateDIBitmap(hDC, lpbmih, dwInit, lpbInit, lpbmi, uColorUse);
855  return m_hBitmap;
856  }
857 #endif // !_WIN32_WCE
858 
859  HBITMAP CreateDIBSection(HDC hDC, CONST BITMAPINFO* lpbmi, UINT uColorUse, VOID** ppvBits, HANDLE hSection, DWORD dwOffset)
860  {
861  ATLASSERT(m_hBitmap == NULL);
862  m_hBitmap = ::CreateDIBSection(hDC, lpbmi, uColorUse, ppvBits, hSection, dwOffset);
863  return m_hBitmap;
864  }
865 
866 #ifndef _WIN32_WCE
867  int GetDIBits(HDC hDC, UINT uStartScan, UINT cScanLines, LPVOID lpvBits, LPBITMAPINFO lpbmi, UINT uColorUse) const
868  {
869  ATLASSERT(m_hBitmap != NULL);
870  return ::GetDIBits(hDC, m_hBitmap, uStartScan, cScanLines, lpvBits, lpbmi, uColorUse);
871  }
872 
873  int SetDIBits(HDC hDC, UINT uStartScan, UINT cScanLines, CONST VOID* lpvBits, CONST BITMAPINFO* lpbmi, UINT uColorUse)
874  {
875  ATLASSERT(m_hBitmap != NULL);
876  return ::SetDIBits(hDC, m_hBitmap, uStartScan, cScanLines, lpvBits, lpbmi, uColorUse);
877  }
878 #endif // !_WIN32_WCE
879 };
880 
882 typedef CBitmapT<true> CBitmap;
883 
884 
886 // CPalette
887 
888 template <bool t_bManaged>
890 {
891 public:
892 // Data members
893  HPALETTE m_hPalette;
894 
895 // Constructor/destructor/operators
896  CPaletteT(HPALETTE hPalette = NULL) : m_hPalette(hPalette)
897  { }
898 
899  ~CPaletteT()
900  {
901  if(t_bManaged && m_hPalette != NULL)
902  DeleteObject();
903  }
904 
905  CPaletteT<t_bManaged>& operator =(HPALETTE hPalette)
906  {
907  Attach(hPalette);
908  return *this;
909  }
910 
911  void Attach(HPALETTE hPalette)
912  {
913  if(t_bManaged && m_hPalette != NULL && m_hPalette != hPalette)
914  ::DeleteObject(m_hPalette);
915  m_hPalette = hPalette;
916  }
917 
918  HPALETTE Detach()
919  {
920  HPALETTE hPalette = m_hPalette;
921  m_hPalette = NULL;
922  return hPalette;
923  }
924 
925  operator HPALETTE() const { return m_hPalette; }
926 
927  bool IsNull() const { return (m_hPalette == NULL); }
928 
929 // Create methods
930  HPALETTE CreatePalette(LPLOGPALETTE lpLogPalette)
931  {
932  ATLASSERT(m_hPalette == NULL);
933  m_hPalette = ::CreatePalette(lpLogPalette);
934  return m_hPalette;
935  }
936 
937 #ifndef _WIN32_WCE
938  HPALETTE CreateHalftonePalette(HDC hDC)
939  {
940  ATLASSERT(m_hPalette == NULL);
941  ATLASSERT(hDC != NULL);
942  m_hPalette = ::CreateHalftonePalette(hDC);
943  return m_hPalette;
944  }
945 #endif // !_WIN32_WCE
946 
947  BOOL DeleteObject()
948  {
949  ATLASSERT(m_hPalette != NULL);
950  BOOL bRet = ::DeleteObject(m_hPalette);
951  if(bRet)
952  m_hPalette = NULL;
953  return bRet;
954  }
955 
956 // Attributes
957  int GetEntryCount() const
958  {
959  ATLASSERT(m_hPalette != NULL);
960  WORD nEntries = 0;
961  ::GetObject(m_hPalette, sizeof(WORD), &nEntries);
962  return (int)nEntries;
963  }
964 
965  UINT GetPaletteEntries(UINT nStartIndex, UINT nNumEntries, LPPALETTEENTRY lpPaletteColors) const
966  {
967  ATLASSERT(m_hPalette != NULL);
968  return ::GetPaletteEntries(m_hPalette, nStartIndex, nNumEntries, lpPaletteColors);
969  }
970 
971  UINT SetPaletteEntries(UINT nStartIndex, UINT nNumEntries, LPPALETTEENTRY lpPaletteColors)
972  {
973  ATLASSERT(m_hPalette != NULL);
974  return ::SetPaletteEntries(m_hPalette, nStartIndex, nNumEntries, lpPaletteColors);
975  }
976 
977 // Operations
978 #ifndef _WIN32_WCE
979  void AnimatePalette(UINT nStartIndex, UINT nNumEntries, LPPALETTEENTRY lpPaletteColors)
980  {
981  ATLASSERT(m_hPalette != NULL);
982  ::AnimatePalette(m_hPalette, nStartIndex, nNumEntries, lpPaletteColors);
983  }
984 
985  BOOL ResizePalette(UINT nNumEntries)
986  {
987  ATLASSERT(m_hPalette != NULL);
988  return ::ResizePalette(m_hPalette, nNumEntries);
989  }
990 #endif // !_WIN32_WCE
991 
992  UINT GetNearestPaletteIndex(COLORREF crColor) const
993  {
994  ATLASSERT(m_hPalette != NULL);
995  return ::GetNearestPaletteIndex(m_hPalette, crColor);
996  }
997 };
998 
1000 typedef CPaletteT<true> CPalette;
1001 
1002 
1004 // CRgn
1005 
1006 template <bool t_bManaged>
1007 class CRgnT
1008 {
1009 public:
1010 // Data members
1011  HRGN m_hRgn;
1012 
1013 // Constructor/destructor/operators
1014  CRgnT(HRGN hRgn = NULL) : m_hRgn(hRgn)
1015  { }
1016 
1017  ~CRgnT()
1018  {
1019  if(t_bManaged && m_hRgn != NULL)
1020  DeleteObject();
1021  }
1022 
1023  CRgnT<t_bManaged>& operator =(HRGN hRgn)
1024  {
1025  Attach(hRgn);
1026  return *this;
1027  }
1028 
1029  void Attach(HRGN hRgn)
1030  {
1031  if(t_bManaged && m_hRgn != NULL && m_hRgn != hRgn)
1032  ::DeleteObject(m_hRgn);
1033  m_hRgn = hRgn;
1034  }
1035 
1036  HRGN Detach()
1037  {
1038  HRGN hRgn = m_hRgn;
1039  m_hRgn = NULL;
1040  return hRgn;
1041  }
1042 
1043  operator HRGN() const { return m_hRgn; }
1044 
1045  bool IsNull() const { return (m_hRgn == NULL); }
1046 
1047 // Create methods
1048  HRGN CreateRectRgn(int x1, int y1, int x2, int y2)
1049  {
1050  ATLASSERT(m_hRgn == NULL);
1051  m_hRgn = ::CreateRectRgn(x1, y1, x2, y2);
1052  return m_hRgn;
1053  }
1054 
1055  HRGN CreateRectRgnIndirect(LPCRECT lpRect)
1056  {
1057  ATLASSERT(m_hRgn == NULL);
1058  m_hRgn = ::CreateRectRgnIndirect(lpRect);
1059  return m_hRgn;
1060  }
1061 
1062 #ifndef _WIN32_WCE
1063  HRGN CreateEllipticRgn(int x1, int y1, int x2, int y2)
1064  {
1065  ATLASSERT(m_hRgn == NULL);
1066  m_hRgn = ::CreateEllipticRgn(x1, y1, x2, y2);
1067  return m_hRgn;
1068  }
1069 
1070  HRGN CreateEllipticRgnIndirect(LPCRECT lpRect)
1071  {
1072  ATLASSERT(m_hRgn == NULL);
1073  m_hRgn = ::CreateEllipticRgnIndirect(lpRect);
1074  return m_hRgn;
1075  }
1076 
1077  HRGN CreatePolygonRgn(LPPOINT lpPoints, int nCount, int nMode)
1078  {
1079  ATLASSERT(m_hRgn == NULL);
1080  m_hRgn = ::CreatePolygonRgn(lpPoints, nCount, nMode);
1081  return m_hRgn;
1082  }
1083 
1084  HRGN CreatePolyPolygonRgn(LPPOINT lpPoints, LPINT lpPolyCounts, int nCount, int nPolyFillMode)
1085  {
1086  ATLASSERT(m_hRgn == NULL);
1087  m_hRgn = ::CreatePolyPolygonRgn(lpPoints, lpPolyCounts, nCount, nPolyFillMode);
1088  return m_hRgn;
1089  }
1090 
1091  HRGN CreateRoundRectRgn(int x1, int y1, int x2, int y2, int x3, int y3)
1092  {
1093  ATLASSERT(m_hRgn == NULL);
1094  m_hRgn = ::CreateRoundRectRgn(x1, y1, x2, y2, x3, y3);
1095  return m_hRgn;
1096  }
1097 
1098  HRGN CreateFromPath(HDC hDC)
1099  {
1100  ATLASSERT(m_hRgn == NULL);
1101  ATLASSERT(hDC != NULL);
1102  m_hRgn = ::PathToRegion(hDC);
1103  return m_hRgn;
1104  }
1105 
1106  HRGN CreateFromData(const XFORM* lpXForm, int nCount, const RGNDATA* pRgnData)
1107  {
1108  ATLASSERT(m_hRgn == NULL);
1109  m_hRgn = ::ExtCreateRegion(lpXForm, nCount, pRgnData);
1110  return m_hRgn;
1111  }
1112 #endif // !_WIN32_WCE
1113 
1114  BOOL DeleteObject()
1115  {
1116  ATLASSERT(m_hRgn != NULL);
1117  BOOL bRet = ::DeleteObject(m_hRgn);
1118  if(bRet)
1119  m_hRgn = NULL;
1120  return bRet;
1121  }
1122 
1123 // Operations
1124  void SetRectRgn(int x1, int y1, int x2, int y2)
1125  {
1126  ATLASSERT(m_hRgn != NULL);
1127  ::SetRectRgn(m_hRgn, x1, y1, x2, y2);
1128  }
1129 
1130  void SetRectRgn(LPCRECT lpRect)
1131  {
1132  ATLASSERT(m_hRgn != NULL);
1133  ::SetRectRgn(m_hRgn, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
1134  }
1135 
1136  int CombineRgn(HRGN hRgnSrc1, HRGN hRgnSrc2, int nCombineMode)
1137  {
1138  ATLASSERT(m_hRgn != NULL);
1139  return ::CombineRgn(m_hRgn, hRgnSrc1, hRgnSrc2, nCombineMode);
1140  }
1141 
1142  int CombineRgn(HRGN hRgnSrc, int nCombineMode)
1143  {
1144  ATLASSERT(m_hRgn != NULL);
1145  return ::CombineRgn(m_hRgn, m_hRgn, hRgnSrc, nCombineMode);
1146  }
1147 
1148  int CopyRgn(HRGN hRgnSrc)
1149  {
1150  ATLASSERT(m_hRgn != NULL);
1151  return ::CombineRgn(m_hRgn, hRgnSrc, NULL, RGN_COPY);
1152  }
1153 
1154  BOOL EqualRgn(HRGN hRgn) const
1155  {
1156  ATLASSERT(m_hRgn != NULL);
1157  return ::EqualRgn(m_hRgn, hRgn);
1158  }
1159 
1160  int OffsetRgn(int x, int y)
1161  {
1162  ATLASSERT(m_hRgn != NULL);
1163  return ::OffsetRgn(m_hRgn, x, y);
1164  }
1165 
1166  int OffsetRgn(POINT point)
1167  {
1168  ATLASSERT(m_hRgn != NULL);
1169  return ::OffsetRgn(m_hRgn, point.x, point.y);
1170  }
1171 
1172  int GetRgnBox(LPRECT lpRect) const
1173  {
1174  ATLASSERT(m_hRgn != NULL);
1175  return ::GetRgnBox(m_hRgn, lpRect);
1176  }
1177 
1178  BOOL PtInRegion(int x, int y) const
1179  {
1180  ATLASSERT(m_hRgn != NULL);
1181  return ::PtInRegion(m_hRgn, x, y);
1182  }
1183 
1184  BOOL PtInRegion(POINT point) const
1185  {
1186  ATLASSERT(m_hRgn != NULL);
1187  return ::PtInRegion(m_hRgn, point.x, point.y);
1188  }
1189 
1190  BOOL RectInRegion(LPCRECT lpRect) const
1191  {
1192  ATLASSERT(m_hRgn != NULL);
1193  return ::RectInRegion(m_hRgn, lpRect);
1194  }
1195 
1196  int GetRegionData(LPRGNDATA lpRgnData, int nDataSize) const
1197  {
1198  ATLASSERT(m_hRgn != NULL);
1199  return (int)::GetRegionData(m_hRgn, nDataSize, lpRgnData);
1200  }
1201 };
1202 
1203 typedef CRgnT<false> CRgnHandle;
1204 typedef CRgnT<true> CRgn;
1205 
1206 
1208 // CDC - The device context class
1209 
1210 template <bool t_bManaged>
1211 class CDCT
1212 {
1213 public:
1214 // Data members
1215  HDC m_hDC;
1216 
1217 // Constructor/destructor/operators
1218  CDCT(HDC hDC = NULL) : m_hDC(hDC)
1219  {
1220  }
1221 
1222  ~CDCT()
1223  {
1224  if(t_bManaged && m_hDC != NULL)
1225  ::DeleteDC(Detach());
1226  }
1227 
1228  CDCT<t_bManaged>& operator =(HDC hDC)
1229  {
1230  Attach(hDC);
1231  return *this;
1232  }
1233 
1234  void Attach(HDC hDC)
1235  {
1236  if(t_bManaged && m_hDC != NULL && m_hDC != hDC)
1237  ::DeleteDC(m_hDC);
1238  m_hDC = hDC;
1239  }
1240 
1241  HDC Detach()
1242  {
1243  HDC hDC = m_hDC;
1244  m_hDC = NULL;
1245  return hDC;
1246  }
1247 
1248  operator HDC() const { return m_hDC; }
1249 
1250  bool IsNull() const { return (m_hDC == NULL); }
1251 
1252 // Operations
1253 #ifndef _WIN32_WCE
1254  HWND WindowFromDC() const
1255  {
1256  ATLASSERT(m_hDC != NULL);
1257  return ::WindowFromDC(m_hDC);
1258  }
1259 #endif // !_WIN32_WCE
1260 
1261  CPenHandle GetCurrentPen() const
1262  {
1263  ATLASSERT(m_hDC != NULL);
1264  return CPenHandle((HPEN)::GetCurrentObject(m_hDC, OBJ_PEN));
1265  }
1266 
1267  CBrushHandle GetCurrentBrush() const
1268  {
1269  ATLASSERT(m_hDC != NULL);
1270  return CBrushHandle((HBRUSH)::GetCurrentObject(m_hDC, OBJ_BRUSH));
1271  }
1272 
1273  CPaletteHandle GetCurrentPalette() const
1274  {
1275  ATLASSERT(m_hDC != NULL);
1276  return CPaletteHandle((HPALETTE)::GetCurrentObject(m_hDC, OBJ_PAL));
1277  }
1278 
1279  CFontHandle GetCurrentFont() const
1280  {
1281  ATLASSERT(m_hDC != NULL);
1282  return CFontHandle((HFONT)::GetCurrentObject(m_hDC, OBJ_FONT));
1283  }
1284 
1285  CBitmapHandle GetCurrentBitmap() const
1286  {
1287  ATLASSERT(m_hDC != NULL);
1288  return CBitmapHandle((HBITMAP)::GetCurrentObject(m_hDC, OBJ_BITMAP));
1289  }
1290 
1291  HDC CreateDC(LPCTSTR lpszDriverName, LPCTSTR lpszDeviceName, LPCTSTR lpszOutput, const DEVMODE* lpInitData)
1292  {
1293  ATLASSERT(m_hDC == NULL);
1294  m_hDC = ::CreateDC(lpszDriverName, lpszDeviceName, lpszOutput, lpInitData);
1295  return m_hDC;
1296  }
1297 
1298  HDC CreateCompatibleDC(HDC hDC = NULL)
1299  {
1300  ATLASSERT(m_hDC == NULL);
1301  m_hDC = ::CreateCompatibleDC(hDC);
1302  return m_hDC;
1303  }
1304 
1305  BOOL DeleteDC()
1306  {
1307  if(m_hDC == NULL)
1308  return FALSE;
1309  BOOL bRet = ::DeleteDC(m_hDC);
1310  if(bRet)
1311  m_hDC = NULL;
1312  return bRet;
1313  }
1314 
1315 // Device-Context Functions
1316  int SaveDC()
1317  {
1318  ATLASSERT(m_hDC != NULL);
1319  return ::SaveDC(m_hDC);
1320  }
1321 
1322  BOOL RestoreDC(int nSavedDC)
1323  {
1324  ATLASSERT(m_hDC != NULL);
1325  return ::RestoreDC(m_hDC, nSavedDC);
1326  }
1327 
1328  int GetDeviceCaps(int nIndex) const
1329  {
1330  ATLASSERT(m_hDC != NULL);
1331  return ::GetDeviceCaps(m_hDC, nIndex);
1332  }
1333 
1334 #ifndef _WIN32_WCE
1335  UINT SetBoundsRect(LPCRECT lpRectBounds, UINT flags)
1336  {
1337  ATLASSERT(m_hDC != NULL);
1338  return ::SetBoundsRect(m_hDC, lpRectBounds, flags);
1339  }
1340 
1341  UINT GetBoundsRect(LPRECT lpRectBounds, UINT flags) const
1342  {
1343  ATLASSERT(m_hDC != NULL);
1344  return ::GetBoundsRect(m_hDC, lpRectBounds, flags);
1345  }
1346 
1347  BOOL ResetDC(const DEVMODE* lpDevMode)
1348  {
1349  ATLASSERT(m_hDC != NULL);
1350  return ::ResetDC(m_hDC, lpDevMode) != NULL;
1351  }
1352 
1353 // Drawing-Tool Functions
1354  BOOL GetBrushOrg(LPPOINT lpPoint) const
1355  {
1356  ATLASSERT(m_hDC != NULL);
1357  return ::GetBrushOrgEx(m_hDC, lpPoint);
1358  }
1359 #endif // !_WIN32_WCE
1360 
1361  BOOL SetBrushOrg(int x, int y, LPPOINT lpPoint = NULL)
1362  {
1363  ATLASSERT(m_hDC != NULL);
1364  return ::SetBrushOrgEx(m_hDC, x, y, lpPoint);
1365  }
1366 
1367  BOOL SetBrushOrg(POINT point, LPPOINT lpPointRet = NULL)
1368  {
1369  ATLASSERT(m_hDC != NULL);
1370  return ::SetBrushOrgEx(m_hDC, point.x, point.y, lpPointRet);
1371  }
1372 
1373 #ifndef _WIN32_WCE
1374  int EnumObjects(int nObjectType, int (CALLBACK* lpfn)(LPVOID, LPARAM), LPARAM lpData)
1375  {
1376  ATLASSERT(m_hDC != NULL);
1377 #ifdef STRICT
1378  return ::EnumObjects(m_hDC, nObjectType, (GOBJENUMPROC)lpfn, lpData);
1379 #else
1380  return ::EnumObjects(m_hDC, nObjectType, (GOBJENUMPROC)lpfn, (LPVOID)lpData);
1381 #endif
1382  }
1383 #endif // !_WIN32_WCE
1384 
1385 // Type-safe selection helpers
1386  HPEN SelectPen(HPEN hPen)
1387  {
1388  ATLASSERT(m_hDC != NULL);
1389 #ifndef _WIN32_WCE
1390  ATLASSERT(hPen == NULL || ::GetObjectType(hPen) == OBJ_PEN || ::GetObjectType(hPen) == OBJ_EXTPEN);
1391 #else // CE specific
1392  ATLASSERT(hPen == NULL || ::GetObjectType(hPen) == OBJ_PEN);
1393 #endif // _WIN32_WCE
1394  return (HPEN)::SelectObject(m_hDC, hPen);
1395  }
1396 
1397  HBRUSH SelectBrush(HBRUSH hBrush)
1398  {
1399  ATLASSERT(m_hDC != NULL);
1400  ATLASSERT(hBrush == NULL || ::GetObjectType(hBrush) == OBJ_BRUSH);
1401  return (HBRUSH)::SelectObject(m_hDC, hBrush);
1402  }
1403 
1404  HFONT SelectFont(HFONT hFont)
1405  {
1406  ATLASSERT(m_hDC != NULL);
1407  ATLASSERT(hFont == NULL || ::GetObjectType(hFont) == OBJ_FONT);
1408  return (HFONT)::SelectObject(m_hDC, hFont);
1409  }
1410 
1411  HBITMAP SelectBitmap(HBITMAP hBitmap)
1412  {
1413  ATLASSERT(m_hDC != NULL);
1414  ATLASSERT(hBitmap == NULL || ::GetObjectType(hBitmap) == OBJ_BITMAP);
1415  return (HBITMAP)::SelectObject(m_hDC, hBitmap);
1416  }
1417 
1418  int SelectRgn(HRGN hRgn) // special return for regions
1419  {
1420  ATLASSERT(m_hDC != NULL);
1421  ATLASSERT(hRgn == NULL || ::GetObjectType(hRgn) == OBJ_REGION);
1422  return PtrToInt(::SelectObject(m_hDC, hRgn));
1423  }
1424 
1425 // Type-safe selection helpers for stock objects
1426  HPEN SelectStockPen(int nPen)
1427  {
1428  ATLASSERT(m_hDC != NULL);
1429 #if (_WIN32_WINNT >= 0x0500)
1430  ATLASSERT(nPen == WHITE_PEN || nPen == BLACK_PEN || nPen == NULL_PEN || nPen == DC_PEN);
1431 #else
1432  ATLASSERT(nPen == WHITE_PEN || nPen == BLACK_PEN || nPen == NULL_PEN);
1433 #endif // !(_WIN32_WINNT >= 0x0500)
1434  return SelectPen((HPEN)::GetStockObject(nPen));
1435  }
1436 
1437  HBRUSH SelectStockBrush(int nBrush)
1438  {
1439 #if (_WIN32_WINNT >= 0x0500)
1440  ATLASSERT((nBrush >= WHITE_BRUSH && nBrush <= HOLLOW_BRUSH) || nBrush == DC_BRUSH);
1441 #else
1442  ATLASSERT(nBrush >= WHITE_BRUSH && nBrush <= HOLLOW_BRUSH);
1443 #endif // !(_WIN32_WINNT >= 0x0500)
1444  return SelectBrush((HBRUSH)::GetStockObject(nBrush));
1445  }
1446 
1447  HFONT SelectStockFont(int nFont)
1448  {
1449 #ifndef _WIN32_WCE
1450  ATLASSERT((nFont >= OEM_FIXED_FONT && nFont <= SYSTEM_FIXED_FONT) || nFont == DEFAULT_GUI_FONT);
1451 #else // CE specific
1452  ATLASSERT(nFont == SYSTEM_FONT);
1453 #endif // _WIN32_WCE
1454  return SelectFont((HFONT)::GetStockObject(nFont));
1455  }
1456 
1457  HPALETTE SelectStockPalette(int nPalette, BOOL bForceBackground)
1458  {
1459  ATLASSERT(nPalette == DEFAULT_PALETTE); // the only one supported
1460  return SelectPalette((HPALETTE)::GetStockObject(nPalette), bForceBackground);
1461  }
1462 
1463 // Color and Color Palette Functions
1464  COLORREF GetNearestColor(COLORREF crColor) const
1465  {
1466  ATLASSERT(m_hDC != NULL);
1467  return ::GetNearestColor(m_hDC, crColor);
1468  }
1469 
1470  HPALETTE SelectPalette(HPALETTE hPalette, BOOL bForceBackground)
1471  {
1472  ATLASSERT(m_hDC != NULL);
1473 
1474  return ::SelectPalette(m_hDC, hPalette, bForceBackground);
1475  }
1476 
1477  UINT RealizePalette()
1478  {
1479  ATLASSERT(m_hDC != NULL);
1480  return ::RealizePalette(m_hDC);
1481  }
1482 
1483 #ifndef _WIN32_WCE
1484  void UpdateColors()
1485  {
1486  ATLASSERT(m_hDC != NULL);
1487  ::UpdateColors(m_hDC);
1488  }
1489 #endif // !_WIN32_WCE
1490 
1491 // Drawing-Attribute Functions
1492  COLORREF GetBkColor() const
1493  {
1494  ATLASSERT(m_hDC != NULL);
1495  return ::GetBkColor(m_hDC);
1496  }
1497 
1498  int GetBkMode() const
1499  {
1500  ATLASSERT(m_hDC != NULL);
1501  return ::GetBkMode(m_hDC);
1502  }
1503 
1504 #ifndef _WIN32_WCE
1505  int GetPolyFillMode() const
1506  {
1507  ATLASSERT(m_hDC != NULL);
1508  return ::GetPolyFillMode(m_hDC);
1509  }
1510 
1511  int GetROP2() const
1512  {
1513  ATLASSERT(m_hDC != NULL);
1514  return ::GetROP2(m_hDC);
1515  }
1516 
1517  int GetStretchBltMode() const
1518  {
1519  ATLASSERT(m_hDC != NULL);
1520  return ::GetStretchBltMode(m_hDC);
1521  }
1522 #endif // !_WIN32_WCE
1523 
1524  COLORREF GetTextColor() const
1525  {
1526  ATLASSERT(m_hDC != NULL);
1527  return ::GetTextColor(m_hDC);
1528  }
1529 
1530  COLORREF SetBkColor(COLORREF crColor)
1531  {
1532  ATLASSERT(m_hDC != NULL);
1533  return ::SetBkColor(m_hDC, crColor);
1534  }
1535 
1536  int SetBkMode(int nBkMode)
1537  {
1538  ATLASSERT(m_hDC != NULL);
1539  return ::SetBkMode(m_hDC, nBkMode);
1540  }
1541 
1542 #ifndef _WIN32_WCE
1543  int SetPolyFillMode(int nPolyFillMode)
1544  {
1545  ATLASSERT(m_hDC != NULL);
1546  return ::SetPolyFillMode(m_hDC, nPolyFillMode);
1547  }
1548 #endif // !_WIN32_WCE
1549 
1550  int SetROP2(int nDrawMode)
1551  {
1552  ATLASSERT(m_hDC != NULL);
1553  return ::SetROP2(m_hDC, nDrawMode);
1554  }
1555 
1556 #ifndef _WIN32_WCE
1557  int SetStretchBltMode(int nStretchMode)
1558  {
1559  ATLASSERT(m_hDC != NULL);
1560  return ::SetStretchBltMode(m_hDC, nStretchMode);
1561  }
1562 #endif // !_WIN32_WCE
1563 
1564  COLORREF SetTextColor(COLORREF crColor)
1565  {
1566  ATLASSERT(m_hDC != NULL);
1567  return ::SetTextColor(m_hDC, crColor);
1568  }
1569 
1570 #ifndef _WIN32_WCE
1571  BOOL GetColorAdjustment(LPCOLORADJUSTMENT lpColorAdjust) const
1572  {
1573  ATLASSERT(m_hDC != NULL);
1574  return ::GetColorAdjustment(m_hDC, lpColorAdjust);
1575  }
1576 
1577  BOOL SetColorAdjustment(const COLORADJUSTMENT* lpColorAdjust)
1578  {
1579  ATLASSERT(m_hDC != NULL);
1580  return ::SetColorAdjustment(m_hDC, lpColorAdjust);
1581  }
1582 
1583 // Mapping Functions
1584  int GetMapMode() const
1585  {
1586  ATLASSERT(m_hDC != NULL);
1587  return ::GetMapMode(m_hDC);
1588  }
1589 
1590  BOOL GetViewportOrg(LPPOINT lpPoint) const
1591  {
1592  ATLASSERT(m_hDC != NULL);
1593  return ::GetViewportOrgEx(m_hDC, lpPoint);
1594  }
1595 
1596  int SetMapMode(int nMapMode)
1597  {
1598  ATLASSERT(m_hDC != NULL);
1599  return ::SetMapMode(m_hDC, nMapMode);
1600  }
1601 #endif // !_WIN32_WCE
1602 
1603  // Viewport Origin
1604  BOOL SetViewportOrg(int x, int y, LPPOINT lpPoint = NULL)
1605  {
1606  ATLASSERT(m_hDC != NULL);
1607  return ::SetViewportOrgEx(m_hDC, x, y, lpPoint);
1608  }
1609 
1610  BOOL SetViewportOrg(POINT point, LPPOINT lpPointRet = NULL)
1611  {
1612  ATLASSERT(m_hDC != NULL);
1613  return SetViewportOrg(point.x, point.y, lpPointRet);
1614  }
1615 
1616 #ifndef _WIN32_WCE
1617  BOOL OffsetViewportOrg(int nWidth, int nHeight, LPPOINT lpPoint = NULL)
1618  {
1619  ATLASSERT(m_hDC != NULL);
1620  return ::OffsetViewportOrgEx(m_hDC, nWidth, nHeight, lpPoint);
1621  }
1622 
1623  // Viewport Extent
1624  BOOL GetViewportExt(LPSIZE lpSize) const
1625  {
1626  ATLASSERT(m_hDC != NULL);
1627  return ::GetViewportExtEx(m_hDC, lpSize);
1628  }
1629 
1630  BOOL SetViewportExt(int x, int y, LPSIZE lpSize = NULL)
1631  {
1632  ATLASSERT(m_hDC != NULL);
1633  return ::SetViewportExtEx(m_hDC, x, y, lpSize);
1634  }
1635 
1636  BOOL SetViewportExt(SIZE size, LPSIZE lpSizeRet = NULL)
1637  {
1638  ATLASSERT(m_hDC != NULL);
1639  return SetViewportExt(size.cx, size.cy, lpSizeRet);
1640  }
1641 
1642  BOOL ScaleViewportExt(int xNum, int xDenom, int yNum, int yDenom, LPSIZE lpSize = NULL)
1643  {
1644  ATLASSERT(m_hDC != NULL);
1645  return ::ScaleViewportExtEx(m_hDC, xNum, xDenom, yNum, yDenom, lpSize);
1646  }
1647 #endif // !_WIN32_WCE
1648 
1649  // Window Origin
1650 #ifndef _WIN32_WCE
1651  BOOL GetWindowOrg(LPPOINT lpPoint) const
1652  {
1653  ATLASSERT(m_hDC != NULL);
1654  return ::GetWindowOrgEx(m_hDC, lpPoint);
1655  }
1656 
1657  BOOL SetWindowOrg(int x, int y, LPPOINT lpPoint = NULL)
1658  {
1659  ATLASSERT(m_hDC != NULL);
1660  return ::SetWindowOrgEx(m_hDC, x, y, lpPoint);
1661  }
1662 
1663  BOOL SetWindowOrg(POINT point, LPPOINT lpPointRet = NULL)
1664  {
1665  ATLASSERT(m_hDC != NULL);
1666  return SetWindowOrg(point.x, point.y, lpPointRet);
1667  }
1668 
1669  BOOL OffsetWindowOrg(int nWidth, int nHeight, LPPOINT lpPoint = NULL)
1670  {
1671  ATLASSERT(m_hDC != NULL);
1672  return ::OffsetWindowOrgEx(m_hDC, nWidth, nHeight, lpPoint);
1673  }
1674 
1675  // Window extent
1676  BOOL GetWindowExt(LPSIZE lpSize) const
1677  {
1678  ATLASSERT(m_hDC != NULL);
1679  return ::GetWindowExtEx(m_hDC, lpSize);
1680  }
1681 
1682  BOOL SetWindowExt(int x, int y, LPSIZE lpSize = NULL)
1683  {
1684  ATLASSERT(m_hDC != NULL);
1685  return ::SetWindowExtEx(m_hDC, x, y, lpSize);
1686  }
1687 
1688  BOOL SetWindowExt(SIZE size, LPSIZE lpSizeRet = NULL)
1689  {
1690  ATLASSERT(m_hDC != NULL);
1691  return SetWindowExt(size.cx, size.cy, lpSizeRet);
1692  }
1693 
1694  BOOL ScaleWindowExt(int xNum, int xDenom, int yNum, int yDenom, LPSIZE lpSize = NULL)
1695  {
1696  ATLASSERT(m_hDC != NULL);
1697  return ::ScaleWindowExtEx(m_hDC, xNum, xDenom, yNum, yDenom, lpSize);
1698  }
1699 
1700 // Coordinate Functions
1701  BOOL DPtoLP(LPPOINT lpPoints, int nCount = 1) const
1702  {
1703  ATLASSERT(m_hDC != NULL);
1704  return ::DPtoLP(m_hDC, lpPoints, nCount);
1705  }
1706 
1707  BOOL DPtoLP(LPRECT lpRect) const
1708  {
1709  ATLASSERT(m_hDC != NULL);
1710  return ::DPtoLP(m_hDC, (LPPOINT)lpRect, 2);
1711  }
1712 
1713  BOOL DPtoLP(LPSIZE lpSize) const
1714  {
1715  SIZE sizeWinExt = { 0, 0 };
1716  if(!GetWindowExt(&sizeWinExt))
1717  return FALSE;
1718  SIZE sizeVpExt = { 0, 0 };
1719  if(!GetViewportExt(&sizeVpExt))
1720  return FALSE;
1721  lpSize->cx = ::MulDiv(lpSize->cx, abs(sizeWinExt.cx), abs(sizeVpExt.cx));
1722  lpSize->cy = ::MulDiv(lpSize->cy, abs(sizeWinExt.cy), abs(sizeVpExt.cy));
1723  return TRUE;
1724  }
1725 
1726  BOOL LPtoDP(LPPOINT lpPoints, int nCount = 1) const
1727  {
1728  ATLASSERT(m_hDC != NULL);
1729  return ::LPtoDP(m_hDC, lpPoints, nCount);
1730  }
1731 
1732  BOOL LPtoDP(LPRECT lpRect) const
1733  {
1734  ATLASSERT(m_hDC != NULL);
1735  return ::LPtoDP(m_hDC, (LPPOINT)lpRect, 2);
1736  }
1737 
1738  BOOL LPtoDP(LPSIZE lpSize) const
1739  {
1740  SIZE sizeWinExt = { 0, 0 };
1741  if(!GetWindowExt(&sizeWinExt))
1742  return FALSE;
1743  SIZE sizeVpExt = { 0, 0 };
1744  if(!GetViewportExt(&sizeVpExt))
1745  return FALSE;
1746  lpSize->cx = ::MulDiv(lpSize->cx, abs(sizeVpExt.cx), abs(sizeWinExt.cx));
1747  lpSize->cy = ::MulDiv(lpSize->cy, abs(sizeVpExt.cy), abs(sizeWinExt.cy));
1748  return TRUE;
1749  }
1750 
1751 // Special Coordinate Functions (useful for dealing with metafiles and OLE)
1752  #define HIMETRIC_INCH 2540 // HIMETRIC units per inch
1753 
1754  void DPtoHIMETRIC(LPSIZE lpSize) const
1755  {
1756  ATLASSERT(m_hDC != NULL);
1757  int nMapMode;
1758  if((nMapMode = GetMapMode()) < MM_ISOTROPIC && nMapMode != MM_TEXT)
1759  {
1760  // when using a constrained map mode, map against physical inch
1761  ((CDCHandle*)this)->SetMapMode(MM_HIMETRIC);
1762  DPtoLP(lpSize);
1763  ((CDCHandle*)this)->SetMapMode(nMapMode);
1764  }
1765  else
1766  {
1767  // map against logical inch for non-constrained mapping modes
1768  int cxPerInch = GetDeviceCaps(LOGPIXELSX);
1769  int cyPerInch = GetDeviceCaps(LOGPIXELSY);
1770  ATLASSERT(cxPerInch != 0 && cyPerInch != 0);
1771  lpSize->cx = ::MulDiv(lpSize->cx, HIMETRIC_INCH, cxPerInch);
1772  lpSize->cy = ::MulDiv(lpSize->cy, HIMETRIC_INCH, cyPerInch);
1773  }
1774  }
1775 
1776  void HIMETRICtoDP(LPSIZE lpSize) const
1777  {
1778  ATLASSERT(m_hDC != NULL);
1779  int nMapMode;
1780  if((nMapMode = GetMapMode()) < MM_ISOTROPIC && nMapMode != MM_TEXT)
1781  {
1782  // when using a constrained map mode, map against physical inch
1783  ((CDCHandle*)this)->SetMapMode(MM_HIMETRIC);
1784  LPtoDP(lpSize);
1785  ((CDCHandle*)this)->SetMapMode(nMapMode);
1786  }
1787  else
1788  {
1789  // map against logical inch for non-constrained mapping modes
1790  int cxPerInch = GetDeviceCaps(LOGPIXELSX);
1791  int cyPerInch = GetDeviceCaps(LOGPIXELSY);
1792  ATLASSERT(cxPerInch != 0 && cyPerInch != 0);
1793  lpSize->cx = ::MulDiv(lpSize->cx, cxPerInch, HIMETRIC_INCH);
1794  lpSize->cy = ::MulDiv(lpSize->cy, cyPerInch, HIMETRIC_INCH);
1795  }
1796  }
1797 
1798  void LPtoHIMETRIC(LPSIZE lpSize) const
1799  {
1800  LPtoDP(lpSize);
1801  DPtoHIMETRIC(lpSize);
1802  }
1803 
1804  void HIMETRICtoLP(LPSIZE lpSize) const
1805  {
1806  HIMETRICtoDP(lpSize);
1807  DPtoLP(lpSize);
1808  }
1809 #endif // !_WIN32_WCE
1810 
1811 // Region Functions
1812  BOOL FillRgn(HRGN hRgn, HBRUSH hBrush)
1813  {
1814  ATLASSERT(m_hDC != NULL);
1815  return ::FillRgn(m_hDC, hRgn, hBrush);
1816  }
1817 
1818 #ifndef _WIN32_WCE
1819  BOOL FrameRgn(HRGN hRgn, HBRUSH hBrush, int nWidth, int nHeight)
1820  {
1821  ATLASSERT(m_hDC != NULL);
1822  return ::FrameRgn(m_hDC, hRgn, hBrush, nWidth, nHeight);
1823  }
1824 
1825  BOOL InvertRgn(HRGN hRgn)
1826  {
1827  ATLASSERT(m_hDC != NULL);
1828  return ::InvertRgn(m_hDC, hRgn);
1829  }
1830 
1831  BOOL PaintRgn(HRGN hRgn)
1832  {
1833  ATLASSERT(m_hDC != NULL);
1834  return ::PaintRgn(m_hDC, hRgn);
1835  }
1836 #endif // !_WIN32_WCE
1837 
1838 // Clipping Functions
1839  int GetClipBox(LPRECT lpRect) const
1840  {
1841  ATLASSERT(m_hDC != NULL);
1842  return ::GetClipBox(m_hDC, lpRect);
1843  }
1844 
1845  int GetClipRgn(CRgn& region) const
1846  {
1847  ATLASSERT(m_hDC != NULL);
1848  if(region.IsNull())
1849  region.CreateRectRgn(0, 0, 0, 0);
1850 
1851  int nRet = ::GetClipRgn(m_hDC, region);
1852  if(nRet != 1)
1853  region.DeleteObject();
1854 
1855  return nRet;
1856  }
1857 
1858 #ifndef _WIN32_WCE
1859  BOOL PtVisible(int x, int y) const
1860  {
1861  ATLASSERT(m_hDC != NULL);
1862  return ::PtVisible(m_hDC, x, y);
1863  }
1864 
1865  BOOL PtVisible(POINT point) const
1866  {
1867  ATLASSERT(m_hDC != NULL);
1868  return ::PtVisible(m_hDC, point.x, point.y);
1869  }
1870 #endif // !_WIN32_WCE
1871 
1872  BOOL RectVisible(LPCRECT lpRect) const
1873  {
1874  ATLASSERT(m_hDC != NULL);
1875  return ::RectVisible(m_hDC, lpRect);
1876  }
1877 
1878  int SelectClipRgn(HRGN hRgn)
1879  {
1880  ATLASSERT(m_hDC != NULL);
1881  return ::SelectClipRgn(m_hDC, (HRGN)hRgn);
1882  }
1883 
1884  int ExcludeClipRect(int x1, int y1, int x2, int y2)
1885  {
1886  ATLASSERT(m_hDC != NULL);
1887  return ::ExcludeClipRect(m_hDC, x1, y1, x2, y2);
1888  }
1889 
1890  int ExcludeClipRect(LPCRECT lpRect)
1891  {
1892  ATLASSERT(m_hDC != NULL);
1893  return ::ExcludeClipRect(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
1894  }
1895 
1896 #ifndef _WIN32_WCE
1897  int ExcludeUpdateRgn(HWND hWnd)
1898  {
1899  ATLASSERT(m_hDC != NULL);
1900  return ::ExcludeUpdateRgn(m_hDC, hWnd);
1901  }
1902 #endif // !_WIN32_WCE
1903 
1904  int IntersectClipRect(int x1, int y1, int x2, int y2)
1905  {
1906  ATLASSERT(m_hDC != NULL);
1907  return ::IntersectClipRect(m_hDC, x1, y1, x2, y2);
1908  }
1909 
1910  int IntersectClipRect(LPCRECT lpRect)
1911  {
1912  ATLASSERT(m_hDC != NULL);
1913  return ::IntersectClipRect(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
1914  }
1915 
1916 #ifndef _WIN32_WCE
1917  int OffsetClipRgn(int x, int y)
1918  {
1919  ATLASSERT(m_hDC != NULL);
1920  return ::OffsetClipRgn(m_hDC, x, y);
1921  }
1922 
1923  int OffsetClipRgn(SIZE size)
1924  {
1925  ATLASSERT(m_hDC != NULL);
1926  return ::OffsetClipRgn(m_hDC, size.cx, size.cy);
1927  }
1928 
1929  int SelectClipRgn(HRGN hRgn, int nMode)
1930  {
1931  ATLASSERT(m_hDC != NULL);
1932  return ::ExtSelectClipRgn(m_hDC, hRgn, nMode);
1933  }
1934 #endif // !_WIN32_WCE
1935 
1936 // Line-Output Functions
1937 #if !defined(_WIN32_WCE) || (_WIN32_WCE >= 400)
1938  BOOL GetCurrentPosition(LPPOINT lpPoint) const
1939  {
1940  ATLASSERT(m_hDC != NULL);
1941  return ::GetCurrentPositionEx(m_hDC, lpPoint);
1942  }
1943 
1944  BOOL MoveTo(int x, int y, LPPOINT lpPoint = NULL)
1945  {
1946  ATLASSERT(m_hDC != NULL);
1947  return ::MoveToEx(m_hDC, x, y, lpPoint);
1948  }
1949 
1950  BOOL MoveTo(POINT point, LPPOINT lpPointRet = NULL)
1951  {
1952  ATLASSERT(m_hDC != NULL);
1953  return MoveTo(point.x, point.y, lpPointRet);
1954  }
1955 
1956  BOOL LineTo(int x, int y)
1957  {
1958  ATLASSERT(m_hDC != NULL);
1959  return ::LineTo(m_hDC, x, y);
1960  }
1961 
1962  BOOL LineTo(POINT point)
1963  {
1964  ATLASSERT(m_hDC != NULL);
1965  return LineTo(point.x, point.y);
1966  }
1967 #endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 400)
1968 
1969 #ifndef _WIN32_WCE
1970  BOOL Arc(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4)
1971  {
1972  ATLASSERT(m_hDC != NULL);
1973  return ::Arc(m_hDC, x1, y1, x2, y2, x3, y3, x4, y4);
1974  }
1975 
1976  BOOL Arc(LPCRECT lpRect, POINT ptStart, POINT ptEnd)
1977  {
1978  ATLASSERT(m_hDC != NULL);
1979  return ::Arc(m_hDC, lpRect->left, lpRect->top,
1980  lpRect->right, lpRect->bottom, ptStart.x, ptStart.y,
1981  ptEnd.x, ptEnd.y);
1982  }
1983 #endif // !_WIN32_WCE
1984 
1985  BOOL Polyline(LPPOINT lpPoints, int nCount)
1986  {
1987  ATLASSERT(m_hDC != NULL);
1988  return ::Polyline(m_hDC, lpPoints, nCount);
1989  }
1990 
1991 #ifndef _WIN32_WCE
1992  BOOL AngleArc(int x, int y, int nRadius, float fStartAngle, float fSweepAngle)
1993  {
1994  ATLASSERT(m_hDC != NULL);
1995  return ::AngleArc(m_hDC, x, y, nRadius, fStartAngle, fSweepAngle);
1996  }
1997 
1998  BOOL ArcTo(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4)
1999  {
2000  ATLASSERT(m_hDC != NULL);
2001  return ::ArcTo(m_hDC, x1, y1, x2, y2, x3, y3, x4, y4);
2002  }
2003 
2004  BOOL ArcTo(LPCRECT lpRect, POINT ptStart, POINT ptEnd)
2005  {
2006  ATLASSERT(m_hDC != NULL);
2007  return ArcTo(lpRect->left, lpRect->top, lpRect->right,
2008  lpRect->bottom, ptStart.x, ptStart.y, ptEnd.x, ptEnd.y);
2009  }
2010 
2011  int GetArcDirection() const
2012  {
2013  ATLASSERT(m_hDC != NULL);
2014  return ::GetArcDirection(m_hDC);
2015  }
2016 
2017  int SetArcDirection(int nArcDirection)
2018  {
2019  ATLASSERT(m_hDC != NULL);
2020  return ::SetArcDirection(m_hDC, nArcDirection);
2021  }
2022 
2023  BOOL PolyDraw(const POINT* lpPoints, const BYTE* lpTypes, int nCount)
2024  {
2025  ATLASSERT(m_hDC != NULL);
2026  return ::PolyDraw(m_hDC, lpPoints, lpTypes, nCount);
2027  }
2028 
2029  BOOL PolylineTo(const POINT* lpPoints, int nCount)
2030  {
2031  ATLASSERT(m_hDC != NULL);
2032  return ::PolylineTo(m_hDC, lpPoints, nCount);
2033  }
2034 
2035  BOOL PolyPolyline(const POINT* lpPoints,
2036  const DWORD* lpPolyPoints, int nCount)
2037  {
2038  ATLASSERT(m_hDC != NULL);
2039  return ::PolyPolyline(m_hDC, lpPoints, lpPolyPoints, nCount);
2040  }
2041 
2042  BOOL PolyBezier(const POINT* lpPoints, int nCount)
2043  {
2044  ATLASSERT(m_hDC != NULL);
2045  return ::PolyBezier(m_hDC, lpPoints, nCount);
2046  }
2047 
2048  BOOL PolyBezierTo(const POINT* lpPoints, int nCount)
2049  {
2050  ATLASSERT(m_hDC != NULL);
2051  return ::PolyBezierTo(m_hDC, lpPoints, nCount);
2052  }
2053 #endif // !_WIN32_WCE
2054 
2055 // Simple Drawing Functions
2056  BOOL FillRect(LPCRECT lpRect, HBRUSH hBrush)
2057  {
2058  ATLASSERT(m_hDC != NULL);
2059  return ::FillRect(m_hDC, lpRect, hBrush);
2060  }
2061 
2062  BOOL FillRect(LPCRECT lpRect, int nColorIndex)
2063  {
2064  ATLASSERT(m_hDC != NULL);
2065 #ifndef _WIN32_WCE
2066  return ::FillRect(m_hDC, lpRect, (HBRUSH)LongToPtr(nColorIndex + 1));
2067 #else // CE specific
2068  return ::FillRect(m_hDC, lpRect, ::GetSysColorBrush(nColorIndex));
2069 #endif // _WIN32_WCE
2070  }
2071 
2072 #ifndef _WIN32_WCE
2073  BOOL FrameRect(LPCRECT lpRect, HBRUSH hBrush)
2074  {
2075  ATLASSERT(m_hDC != NULL);
2076  return ::FrameRect(m_hDC, lpRect, hBrush);
2077  }
2078 #endif // !_WIN32_WCE
2079 
2080 #if !defined(_WIN32_WCE) || (_WIN32_WCE >= 420)
2081  BOOL InvertRect(LPCRECT lpRect)
2082  {
2083  ATLASSERT(m_hDC != NULL);
2084  return ::InvertRect(m_hDC, lpRect);
2085  }
2086 #endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 420)
2087 
2088  BOOL DrawIcon(int x, int y, HICON hIcon)
2089  {
2090  ATLASSERT(m_hDC != NULL);
2091 #ifndef _WIN32_WCE
2092  return ::DrawIcon(m_hDC, x, y, hIcon);
2093 #else // CE specific
2094  return ::DrawIconEx(m_hDC, x, y, hIcon, 0, 0, 0, NULL, DI_NORMAL);
2095 #endif // _WIN32_WCE
2096  }
2097 
2098  BOOL DrawIcon(POINT point, HICON hIcon)
2099  {
2100  ATLASSERT(m_hDC != NULL);
2101 #ifndef _WIN32_WCE
2102  return ::DrawIcon(m_hDC, point.x, point.y, hIcon);
2103 #else // CE specific
2104  return ::DrawIconEx(m_hDC, point.x, point.y, hIcon, 0, 0, 0, NULL, DI_NORMAL);
2105 #endif // _WIN32_WCE
2106  }
2107 
2108  BOOL DrawIconEx(int x, int y, HICON hIcon, int cxWidth, int cyWidth, UINT uStepIfAniCur = 0, HBRUSH hbrFlickerFreeDraw = NULL, UINT uFlags = DI_NORMAL)
2109  {
2110  ATLASSERT(m_hDC != NULL);
2111  return ::DrawIconEx(m_hDC, x, y, hIcon, cxWidth, cyWidth, uStepIfAniCur, hbrFlickerFreeDraw, uFlags);
2112  }
2113 
2114  BOOL DrawIconEx(POINT point, HICON hIcon, SIZE size, UINT uStepIfAniCur = 0, HBRUSH hbrFlickerFreeDraw = NULL, UINT uFlags = DI_NORMAL)
2115  {
2116  ATLASSERT(m_hDC != NULL);
2117  return ::DrawIconEx(m_hDC, point.x, point.y, hIcon, size.cx, size.cy, uStepIfAniCur, hbrFlickerFreeDraw, uFlags);
2118  }
2119 
2120 #ifndef _WIN32_WCE
2121  BOOL DrawState(POINT pt, SIZE size, HBITMAP hBitmap, UINT nFlags, HBRUSH hBrush = NULL)
2122  {
2123  ATLASSERT(m_hDC != NULL);
2124  return ::DrawState(m_hDC, hBrush, NULL, (LPARAM)hBitmap, 0, pt.x, pt.y, size.cx, size.cy, nFlags | DST_BITMAP);
2125  }
2126 
2127  BOOL DrawState(POINT pt, SIZE size, HICON hIcon, UINT nFlags, HBRUSH hBrush = NULL)
2128  {
2129  ATLASSERT(m_hDC != NULL);
2130  return ::DrawState(m_hDC, hBrush, NULL, (LPARAM)hIcon, 0, pt.x, pt.y, size.cx, size.cy, nFlags | DST_ICON);
2131  }
2132 
2133  BOOL DrawState(POINT pt, SIZE size, LPCTSTR lpszText, UINT nFlags, BOOL bPrefixText = TRUE, int nTextLen = 0, HBRUSH hBrush = NULL)
2134  {
2135  ATLASSERT(m_hDC != NULL);
2136  return ::DrawState(m_hDC, hBrush, NULL, (LPARAM)lpszText, (WPARAM)nTextLen, pt.x, pt.y, size.cx, size.cy, nFlags | (bPrefixText ? DST_PREFIXTEXT : DST_TEXT));
2137  }
2138 
2139  BOOL DrawState(POINT pt, SIZE size, DRAWSTATEPROC lpDrawProc, LPARAM lData, UINT nFlags, HBRUSH hBrush = NULL)
2140  {
2141  ATLASSERT(m_hDC != NULL);
2142  return ::DrawState(m_hDC, hBrush, lpDrawProc, lData, 0, pt.x, pt.y, size.cx, size.cy, nFlags | DST_COMPLEX);
2143  }
2144 #endif // !_WIN32_WCE
2145 
2146 // Ellipse and Polygon Functions
2147 #ifndef _WIN32_WCE
2148  BOOL Chord(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4)
2149  {
2150  ATLASSERT(m_hDC != NULL);
2151  return ::Chord(m_hDC, x1, y1, x2, y2, x3, y3, x4, y4);
2152  }
2153 
2154  BOOL Chord(LPCRECT lpRect, POINT ptStart, POINT ptEnd)
2155  {
2156  ATLASSERT(m_hDC != NULL);
2157  return ::Chord(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom, ptStart.x, ptStart.y, ptEnd.x, ptEnd.y);
2158  }
2159 #endif // !_WIN32_WCE
2160 
2161  void DrawFocusRect(LPCRECT lpRect)
2162  {
2163  ATLASSERT(m_hDC != NULL);
2164  ::DrawFocusRect(m_hDC, lpRect);
2165  }
2166 
2167  BOOL Ellipse(int x1, int y1, int x2, int y2)
2168  {
2169  ATLASSERT(m_hDC != NULL);
2170  return ::Ellipse(m_hDC, x1, y1, x2, y2);
2171  }
2172 
2173  BOOL Ellipse(LPCRECT lpRect)
2174  {
2175  ATLASSERT(m_hDC != NULL);
2176  return ::Ellipse(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
2177  }
2178 
2179 #ifndef _WIN32_WCE
2180  BOOL Pie(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4)
2181  {
2182  ATLASSERT(m_hDC != NULL);
2183  return ::Pie(m_hDC, x1, y1, x2, y2, x3, y3, x4, y4);
2184  }
2185 
2186  BOOL Pie(LPCRECT lpRect, POINT ptStart, POINT ptEnd)
2187  {
2188  ATLASSERT(m_hDC != NULL);
2189  return ::Pie(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom, ptStart.x, ptStart.y, ptEnd.x, ptEnd.y);
2190  }
2191 #endif // !_WIN32_WCE
2192 
2193  BOOL Polygon(LPPOINT lpPoints, int nCount)
2194  {
2195  ATLASSERT(m_hDC != NULL);
2196  return ::Polygon(m_hDC, lpPoints, nCount);
2197  }
2198 
2199 #ifndef _WIN32_WCE
2200  BOOL PolyPolygon(LPPOINT lpPoints, LPINT lpPolyCounts, int nCount)
2201  {
2202  ATLASSERT(m_hDC != NULL);
2203  return ::PolyPolygon(m_hDC, lpPoints, lpPolyCounts, nCount);
2204  }
2205 #endif // !_WIN32_WCE
2206 
2207  BOOL Rectangle(int x1, int y1, int x2, int y2)
2208  {
2209  ATLASSERT(m_hDC != NULL);
2210  return ::Rectangle(m_hDC, x1, y1, x2, y2);
2211  }
2212 
2213  BOOL Rectangle(LPCRECT lpRect)
2214  {
2215  ATLASSERT(m_hDC != NULL);
2216  return ::Rectangle(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
2217  }
2218 
2219  BOOL RoundRect(int x1, int y1, int x2, int y2, int x3, int y3)
2220  {
2221  ATLASSERT(m_hDC != NULL);
2222  return ::RoundRect(m_hDC, x1, y1, x2, y2, x3, y3);
2223  }
2224 
2225  BOOL RoundRect(LPCRECT lpRect, POINT point)
2226  {
2227  ATLASSERT(m_hDC != NULL);
2228  return ::RoundRect(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom, point.x, point.y);
2229  }
2230 
2231 // Bitmap Functions
2232  BOOL PatBlt(int x, int y, int nWidth, int nHeight, DWORD dwRop)
2233  {
2234  ATLASSERT(m_hDC != NULL);
2235  return ::PatBlt(m_hDC, x, y, nWidth, nHeight, dwRop);
2236  }
2237 
2238  BOOL BitBlt(int x, int y, int nWidth, int nHeight, HDC hSrcDC,
2239  int xSrc, int ySrc, DWORD dwRop)
2240  {
2241  ATLASSERT(m_hDC != NULL);
2242  return ::BitBlt(m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, dwRop);
2243  }
2244 
2245  BOOL StretchBlt(int x, int y, int nWidth, int nHeight, HDC hSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, DWORD dwRop)
2246  {
2247  ATLASSERT(m_hDC != NULL);
2248  return ::StretchBlt(m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, nSrcWidth, nSrcHeight, dwRop);
2249  }
2250 
2251  COLORREF GetPixel(int x, int y) const
2252  {
2253  ATLASSERT(m_hDC != NULL);
2254  return ::GetPixel(m_hDC, x, y);
2255  }
2256 
2257  COLORREF GetPixel(POINT point) const
2258  {
2259  ATLASSERT(m_hDC != NULL);
2260  return ::GetPixel(m_hDC, point.x, point.y);
2261  }
2262 
2263  COLORREF SetPixel(int x, int y, COLORREF crColor)
2264  {
2265  ATLASSERT(m_hDC != NULL);
2266  return ::SetPixel(m_hDC, x, y, crColor);
2267  }
2268 
2269  COLORREF SetPixel(POINT point, COLORREF crColor)
2270  {
2271  ATLASSERT(m_hDC != NULL);
2272  return ::SetPixel(m_hDC, point.x, point.y, crColor);
2273  }
2274 
2275 #ifndef _WIN32_WCE
2276  BOOL FloodFill(int x, int y, COLORREF crColor)
2277  {
2278  ATLASSERT(m_hDC != NULL);
2279  return ::FloodFill(m_hDC, x, y, crColor);
2280  }
2281 
2282  BOOL ExtFloodFill(int x, int y, COLORREF crColor, UINT nFillType)
2283  {
2284  ATLASSERT(m_hDC != NULL);
2285  return ::ExtFloodFill(m_hDC, x, y, crColor, nFillType);
2286  }
2287 #endif // !_WIN32_WCE
2288 
2289  BOOL MaskBlt(int x, int y, int nWidth, int nHeight, HDC hSrcDC, int xSrc, int ySrc, HBITMAP hMaskBitmap, int xMask, int yMask, DWORD dwRop)
2290  {
2291  ATLASSERT(m_hDC != NULL);
2292  return ::MaskBlt(m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, hMaskBitmap, xMask, yMask, dwRop);
2293  }
2294 
2295 #ifndef _WIN32_WCE
2296  BOOL PlgBlt(LPPOINT lpPoint, HDC hSrcDC, int xSrc, int ySrc, int nWidth, int nHeight, HBITMAP hMaskBitmap, int xMask, int yMask)
2297  {
2298  ATLASSERT(m_hDC != NULL);
2299  return ::PlgBlt(m_hDC, lpPoint, hSrcDC, xSrc, ySrc, nWidth, nHeight, hMaskBitmap, xMask, yMask);
2300  }
2301 
2302  BOOL SetPixelV(int x, int y, COLORREF crColor)
2303  {
2304  ATLASSERT(m_hDC != NULL);
2305  return ::SetPixelV(m_hDC, x, y, crColor);
2306  }
2307 
2308  BOOL SetPixelV(POINT point, COLORREF crColor)
2309  {
2310  ATLASSERT(m_hDC != NULL);
2311  return ::SetPixelV(m_hDC, point.x, point.y, crColor);
2312  }
2313 #endif // !_WIN32_WCE
2314 
2315 #if !defined(_ATL_NO_MSIMG) || defined(_WIN32_WCE)
2316 #ifndef _WIN32_WCE
2317  BOOL TransparentBlt(int x, int y, int nWidth, int nHeight, HDC hSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, UINT crTransparent)
2318  {
2319  ATLASSERT(m_hDC != NULL);
2320  return ::TransparentBlt(m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, nSrcWidth, nSrcHeight, crTransparent);
2321  }
2322 #else // CE specific
2323  BOOL TransparentImage(int x, int y, int nWidth, int nHeight, HDC hSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, UINT crTransparent)
2324  {
2325  ATLASSERT(m_hDC != NULL);
2326  return ::TransparentImage(m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, nSrcWidth, nSrcHeight, crTransparent);
2327  }
2328 #endif // _WIN32_WCE
2329 
2330 #if (!defined(_WIN32_WCE) || (_WIN32_WCE >= 420))
2331  BOOL GradientFill(const PTRIVERTEX pVertices, DWORD nVertices, void* pMeshElements, DWORD nMeshElements, DWORD dwMode)
2332  {
2333  ATLASSERT(m_hDC != NULL);
2334  return ::GradientFill(m_hDC, pVertices, nVertices, pMeshElements, nMeshElements, dwMode);
2335  }
2336 
2337  BOOL GradientFillRect(RECT& rect, COLORREF clr1, COLORREF clr2, bool bHorizontal)
2338  {
2339  ATLASSERT(m_hDC != NULL);
2340 
2341  TRIVERTEX arrTvx[2] = { { 0 }, { 0 } };
2342 
2343  arrTvx[0].x = rect.left;
2344  arrTvx[0].y = rect.top;
2345  arrTvx[0].Red = MAKEWORD(0, GetRValue(clr1));
2346  arrTvx[0].Green = MAKEWORD(0, GetGValue(clr1));
2347  arrTvx[0].Blue = MAKEWORD(0, GetBValue(clr1));
2348  arrTvx[0].Alpha = 0;
2349 
2350  arrTvx[1].x = rect.right;
2351  arrTvx[1].y = rect.bottom;
2352  arrTvx[1].Red = MAKEWORD(0, GetRValue(clr2));
2353  arrTvx[1].Green = MAKEWORD(0, GetGValue(clr2));
2354  arrTvx[1].Blue = MAKEWORD(0, GetBValue(clr2));
2355  arrTvx[1].Alpha = 0;
2356 
2357  GRADIENT_RECT gr = { 0, 1 };
2358 
2359  return ::GradientFill(m_hDC, arrTvx, 2, &gr, 1, bHorizontal ? GRADIENT_FILL_RECT_H : GRADIENT_FILL_RECT_V);
2360  }
2361 #endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 420)
2362 
2363 #if !defined(_WIN32_WCE) || (_WIN32_WCE > 0x500)
2364  BOOL AlphaBlend(int x, int y, int nWidth, int nHeight, HDC hSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, BLENDFUNCTION bf)
2365  {
2366  ATLASSERT(m_hDC != NULL);
2367  return ::AlphaBlend(m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, nSrcWidth, nSrcHeight, bf);
2368  }
2369 #endif // !defined(_WIN32_WCE) || (_WIN32_WCE > 0x500)
2370 #endif // !defined(_ATL_NO_MSIMG) || defined(_WIN32_WCE)
2371 
2372 // Extra bitmap functions
2373  // Helper function for painting a disabled toolbar or menu bitmap
2374  // This function can take either an HBITMAP (for SS) or a DC with
2375  // the bitmap already painted (for cmdbar)
2376  BOOL DitherBlt(int x, int y, int nWidth, int nHeight, HDC hSrcDC, HBITMAP hBitmap, int xSrc, int ySrc,
2377  HBRUSH hBrushBackground = ::GetSysColorBrush(COLOR_3DFACE),
2378  HBRUSH hBrush3DEffect = ::GetSysColorBrush(COLOR_3DHILIGHT),
2379  HBRUSH hBrushDisabledImage = ::GetSysColorBrush(COLOR_3DSHADOW))
2380  {
2381  ATLASSERT(m_hDC != NULL || hBitmap != NULL);
2382  ATLASSERT(nWidth > 0 && nHeight > 0);
2383 
2384  // Create a generic DC for all BitBlts
2385  CDCHandle dc = (hSrcDC != NULL) ? hSrcDC : ::CreateCompatibleDC(m_hDC);
2386  ATLASSERT(dc.m_hDC != NULL);
2387  if(dc.m_hDC == NULL)
2388  return FALSE;
2389 
2390  // Create a DC for the monochrome DIB section
2391  CDC dcBW = ::CreateCompatibleDC(m_hDC);
2392  ATLASSERT(dcBW.m_hDC != NULL);
2393  if(dcBW.m_hDC == NULL)
2394  {
2395  if(hSrcDC == NULL)
2396  dc.DeleteDC();
2397  return FALSE;
2398  }
2399 
2400  // Create the monochrome DIB section with a black and white palette
2401  struct RGBBWBITMAPINFO
2402  {
2403  BITMAPINFOHEADER bmiHeader;
2404  RGBQUAD bmiColors[2];
2405  };
2406 
2407  RGBBWBITMAPINFO rgbBWBitmapInfo =
2408  {
2409  { sizeof(BITMAPINFOHEADER), nWidth, nHeight, 1, 1, BI_RGB, 0, 0, 0, 0, 0 },
2410  { { 0x00, 0x00, 0x00, 0x00 }, { 0xFF, 0xFF, 0xFF, 0x00 } }
2411  };
2412 
2413  VOID* pbitsBW;
2414  CBitmap bmpBW = ::CreateDIBSection(dcBW, (LPBITMAPINFO)&rgbBWBitmapInfo, DIB_RGB_COLORS, &pbitsBW, NULL, 0);
2415  ATLASSERT(bmpBW.m_hBitmap != NULL);
2416  if(bmpBW.m_hBitmap == NULL)
2417  {
2418  if(hSrcDC == NULL)
2419  dc.DeleteDC();
2420  return FALSE;
2421  }
2422 
2423  // Attach the monochrome DIB section and the bitmap to the DCs
2424  HBITMAP hbmOldBW = dcBW.SelectBitmap(bmpBW);
2425  HBITMAP hbmOldDC = NULL;
2426  if(hBitmap != NULL)
2427  hbmOldDC = dc.SelectBitmap(hBitmap);
2428 
2429  // Block: Dark gray removal: we want (128, 128, 128) pixels to become black and not white
2430  {
2431  CDC dcTemp1 = ::CreateCompatibleDC(m_hDC);
2432  CDC dcTemp2 = ::CreateCompatibleDC(m_hDC);
2433  CBitmap bmpTemp1;
2434  bmpTemp1.CreateCompatibleBitmap(dc, nWidth, nHeight);
2435  CBitmap bmpTemp2;
2436  bmpTemp2.CreateBitmap(nWidth, nHeight, 1, 1, NULL);
2437  HBITMAP hOldBmp1 = dcTemp1.SelectBitmap(bmpTemp1);
2438  HBITMAP hOldBmp2 = dcTemp2.SelectBitmap(bmpTemp2);
2439  // Let's copy our image, it will be altered
2440  dcTemp1.BitBlt(0, 0, nWidth, nHeight, dc, xSrc, ySrc, SRCCOPY);
2441 
2442  // All dark gray pixels will become white, the others black
2443  dcTemp1.SetBkColor(RGB(128, 128, 128));
2444  dcTemp2.BitBlt(0, 0, nWidth, nHeight, dcTemp1, 0, 0, SRCCOPY);
2445  // Do an XOR to set to black these white pixels
2446  dcTemp1.BitBlt(0, 0, nWidth, nHeight, dcTemp2, 0, 0, SRCINVERT);
2447 
2448  // BitBlt the bitmap into the monochrome DIB section
2449  // The DIB section will do a true monochrome conversion
2450  // The magenta background being closer to white will become white
2451  dcBW.BitBlt(0, 0, nWidth, nHeight, dcTemp1, 0, 0, SRCCOPY);
2452 
2453  // Cleanup
2454  dcTemp1.SelectBitmap(hOldBmp1);
2455  dcTemp2.SelectBitmap(hOldBmp2);
2456  }
2457 
2458  // Paint the destination rectangle using hBrushBackground
2459  if(hBrushBackground != NULL)
2460  {
2461  RECT rc = { x, y, x + nWidth, y + nHeight };
2462  FillRect(&rc, hBrushBackground);
2463  }
2464 
2465  // BitBlt the black bits in the monochrome bitmap into hBrush3DEffect color in the destination DC
2466  // The magic ROP comes from the Charles Petzold's book
2467  HBRUSH hOldBrush = SelectBrush(hBrush3DEffect);
2468  BitBlt(x + 1, y + 1, nWidth, nHeight, dcBW, 0, 0, 0xB8074A);
2469 
2470  // BitBlt the black bits in the monochrome bitmap into hBrushDisabledImage color in the destination DC
2471  SelectBrush(hBrushDisabledImage);
2472  BitBlt(x, y, nWidth, nHeight, dcBW, 0, 0, 0xB8074A);
2473 
2474  SelectBrush(hOldBrush);
2475  dcBW.SelectBitmap(hbmOldBW);
2476  dc.SelectBitmap(hbmOldDC);
2477 
2478  if(hSrcDC == NULL)
2479  dc.DeleteDC();
2480 
2481  return TRUE;
2482  }
2483 
2484 // Text Functions
2485 #ifndef _WIN32_WCE
2486  BOOL TextOut(int x, int y, LPCTSTR lpszString, int nCount = -1)
2487  {
2488  ATLASSERT(m_hDC != NULL);
2489  if(nCount == -1)
2490  nCount = lstrlen(lpszString);
2491  return ::TextOut(m_hDC, x, y, lpszString, nCount);
2492  }
2493 #endif // !_WIN32_WCE
2494 
2495  BOOL ExtTextOut(int x, int y, UINT nOptions, LPCRECT lpRect, LPCTSTR lpszString, UINT nCount = -1, LPINT lpDxWidths = NULL)
2496  {
2497  ATLASSERT(m_hDC != NULL);
2498  if(nCount == -1)
2499  nCount = lstrlen(lpszString);
2500  return ::ExtTextOut(m_hDC, x, y, nOptions, lpRect, lpszString, nCount, lpDxWidths);
2501  }
2502 
2503 #ifndef _WIN32_WCE
2504  SIZE TabbedTextOut(int x, int y, LPCTSTR lpszString, int nCount = -1, int nTabPositions = 0, LPINT lpnTabStopPositions = NULL, int nTabOrigin = 0)
2505  {
2506  ATLASSERT(m_hDC != NULL);
2507  if(nCount == -1)
2508  nCount = lstrlen(lpszString);
2509  LONG lRes = ::TabbedTextOut(m_hDC, x, y, lpszString, nCount, nTabPositions, lpnTabStopPositions, nTabOrigin);
2510  SIZE size = { GET_X_LPARAM(lRes), GET_Y_LPARAM(lRes) };
2511  return size;
2512  }
2513 #endif // !_WIN32_WCE
2514 
2515  int DrawText(LPCTSTR lpstrText, int cchText, LPRECT lpRect, UINT uFormat)
2516  {
2517  ATLASSERT(m_hDC != NULL);
2518 #ifndef _WIN32_WCE
2519  ATLASSERT((uFormat & DT_MODIFYSTRING) == 0);
2520 #endif // !_WIN32_WCE
2521  return ::DrawText(m_hDC, lpstrText, cchText, lpRect, uFormat);
2522  }
2523 
2524  int DrawText(LPTSTR lpstrText, int cchText, LPRECT lpRect, UINT uFormat)
2525  {
2526  ATLASSERT(m_hDC != NULL);
2527  return ::DrawText(m_hDC, lpstrText, cchText, lpRect, uFormat);
2528  }
2529 
2530 #ifndef _WIN32_WCE
2531  int DrawTextEx(LPTSTR lpstrText, int cchText, LPRECT lpRect, UINT uFormat, LPDRAWTEXTPARAMS lpDTParams = NULL)
2532  {
2533  ATLASSERT(m_hDC != NULL);
2534  return ::DrawTextEx(m_hDC, lpstrText, cchText, lpRect, uFormat, lpDTParams);
2535  }
2536 #endif // !_WIN32_WCE
2537 
2538 #if (_WIN32_WINNT >= 0x0501)
2539  int DrawShadowText(LPCWSTR lpstrText, int cchText, LPRECT lpRect, DWORD dwFlags, COLORREF clrText, COLORREF clrShadow, int xOffset, int yOffset)
2540  {
2541  ATLASSERT(m_hDC != NULL);
2542  // This function is present only if comctl32.dll version 6 is loaded;
2543  // we use LoadLibrary/GetProcAddress to allow apps compiled with
2544  // _WIN32_WINNT >= 0x0501 to run on older Windows/CommCtrl
2545  int nRet = 0;
2546  HMODULE hCommCtrlDLL = ::LoadLibrary(_T("comctl32.dll"));
2547  ATLASSERT(hCommCtrlDLL != NULL);
2548  if(hCommCtrlDLL != NULL)
2549  {
2550  typedef int (WINAPI *PFN_DrawShadowText)(HDC hDC, LPCWSTR lpstrText, UINT cchText, LPRECT lpRect, DWORD dwFlags, COLORREF clrText, COLORREF clrShadow, int xOffset, int yOffset);
2551  PFN_DrawShadowText pfnDrawShadowText = (PFN_DrawShadowText)::GetProcAddress(hCommCtrlDLL, "DrawShadowText");
2552  ATLASSERT(pfnDrawShadowText != NULL); // this function requires CommCtrl6
2553  if(pfnDrawShadowText != NULL)
2554  nRet = pfnDrawShadowText(m_hDC, lpstrText, cchText, lpRect, dwFlags, clrText, clrShadow, xOffset, yOffset);
2555  ::FreeLibrary(hCommCtrlDLL);
2556  }
2557  return nRet;
2558  }
2559 #endif // (_WIN32_WINNT >= 0x0501)
2560 
2561  BOOL GetTextExtent(LPCTSTR lpszString, int nCount, LPSIZE lpSize) const
2562  {
2563  ATLASSERT(m_hDC != NULL);
2564  if(nCount == -1)
2565  nCount = lstrlen(lpszString);
2566  return ::GetTextExtentPoint32(m_hDC, lpszString, nCount, lpSize);
2567  }
2568 
2569  BOOL GetTextExtentExPoint(LPCTSTR lpszString, int cchString, LPSIZE lpSize, int nMaxExtent, LPINT lpnFit = NULL, LPINT alpDx = NULL)
2570  {
2571  ATLASSERT(m_hDC != NULL);
2572  return ::GetTextExtentExPoint(m_hDC, lpszString, cchString, nMaxExtent, lpnFit, alpDx, lpSize);
2573  }
2574 
2575 #ifndef _WIN32_WCE
2576  DWORD GetTabbedTextExtent(LPCTSTR lpszString, int nCount = -1, int nTabPositions = 0, LPINT lpnTabStopPositions = NULL) const
2577  {
2578  ATLASSERT(m_hDC != NULL);
2579  if(nCount == -1)
2580  nCount = lstrlen(lpszString);
2581  return ::GetTabbedTextExtent(m_hDC, lpszString, nCount, nTabPositions, lpnTabStopPositions);
2582  }
2583 
2584  BOOL GrayString(HBRUSH hBrush, BOOL (CALLBACK* lpfnOutput)(HDC, LPARAM, int), LPARAM lpData, int nCount, int x, int y, int nWidth, int nHeight)
2585  {
2586  ATLASSERT(m_hDC != NULL);
2587  return ::GrayString(m_hDC, hBrush, (GRAYSTRINGPROC)lpfnOutput, lpData, nCount, x, y, nWidth, nHeight);
2588  }
2589 #endif // !_WIN32_WCE
2590 
2591 #if !defined(_WIN32_WCE) || (_WIN32_WCE >= 400)
2592  UINT GetTextAlign() const
2593  {
2594  ATLASSERT(m_hDC != NULL);
2595  return ::GetTextAlign(m_hDC);
2596  }
2597 
2598  UINT SetTextAlign(UINT nFlags)
2599  {
2600  ATLASSERT(m_hDC != NULL);
2601  return ::SetTextAlign(m_hDC, nFlags);
2602  }
2603 #endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 400)
2604 
2605  int GetTextFace(LPTSTR lpszFacename, int nCount) const
2606  {
2607  ATLASSERT(m_hDC != NULL);
2608  return ::GetTextFace(m_hDC, nCount, lpszFacename);
2609  }
2610 
2611  int GetTextFaceLen() const
2612  {
2613  ATLASSERT(m_hDC != NULL);
2614  return ::GetTextFace(m_hDC, 0, NULL);
2615  }
2616 
2617 #ifndef _ATL_NO_COM
2618 #ifdef _OLEAUTO_H_
2619  BOOL GetTextFace(BSTR& bstrFace) const
2620  {
2621  USES_CONVERSION;
2622  ATLASSERT(m_hDC != NULL);
2623  ATLASSERT(bstrFace == NULL);
2624 
2625  int nLen = GetTextFaceLen();
2626  if(nLen == 0)
2627  return FALSE;
2628 
2630  LPTSTR lpszText = buff.Allocate(nLen);
2631  if(lpszText == NULL)
2632  return FALSE;
2633 
2634  if(!GetTextFace(lpszText, nLen))
2635  return FALSE;
2636 
2637  bstrFace = ::SysAllocString(T2OLE(lpszText));
2638  return (bstrFace != NULL) ? TRUE : FALSE;
2639  }
2640 #endif
2641 #endif // !_ATL_NO_COM
2642 
2643 #if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
2644  int GetTextFace(_CSTRING_NS::CString& strFace) const
2645  {
2646  ATLASSERT(m_hDC != NULL);
2647 
2648  int nLen = GetTextFaceLen();
2649  if(nLen == 0)
2650  return 0;
2651 
2652  LPTSTR lpstr = strFace.GetBufferSetLength(nLen);
2653  if(lpstr == NULL)
2654  return 0;
2655  int nRet = GetTextFace(lpstr, nLen);
2656  strFace.ReleaseBuffer();
2657  return nRet;
2658  }
2659 #endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
2660 
2661  BOOL GetTextMetrics(LPTEXTMETRIC lpMetrics) const
2662  {
2663  ATLASSERT(m_hDC != NULL);
2664  return ::GetTextMetrics(m_hDC, lpMetrics);
2665  }
2666 
2667 #ifndef _WIN32_WCE
2668  int SetTextJustification(int nBreakExtra, int nBreakCount)
2669  {
2670  ATLASSERT(m_hDC != NULL);
2671  return ::SetTextJustification(m_hDC, nBreakExtra, nBreakCount);
2672  }
2673 
2674  int GetTextCharacterExtra() const
2675  {
2676  ATLASSERT(m_hDC != NULL);
2677  return ::GetTextCharacterExtra(m_hDC);
2678  }
2679 
2680  int SetTextCharacterExtra(int nCharExtra)
2681  {
2682  ATLASSERT(m_hDC != NULL);
2683  return ::SetTextCharacterExtra(m_hDC, nCharExtra);
2684  }
2685 #endif // !_WIN32_WCE
2686 
2687 // Advanced Drawing
2688  BOOL DrawEdge(LPRECT lpRect, UINT nEdge, UINT nFlags)
2689  {
2690  ATLASSERT(m_hDC != NULL);
2691  return ::DrawEdge(m_hDC, lpRect, nEdge, nFlags);
2692  }
2693 
2694  BOOL DrawFrameControl(LPRECT lpRect, UINT nType, UINT nState)
2695  {
2696  ATLASSERT(m_hDC != NULL);
2697  return ::DrawFrameControl(m_hDC, lpRect, nType, nState);
2698  }
2699 
2700 // Scrolling Functions
2701  BOOL ScrollDC(int dx, int dy, LPCRECT lpRectScroll, LPCRECT lpRectClip, HRGN hRgnUpdate, LPRECT lpRectUpdate)
2702  {
2703  ATLASSERT(m_hDC != NULL);
2704  return ::ScrollDC(m_hDC, dx, dy, lpRectScroll, lpRectClip, hRgnUpdate, lpRectUpdate);
2705  }
2706 
2707 // Font Functions
2708 #ifndef _WIN32_WCE
2709  BOOL GetCharWidth(UINT nFirstChar, UINT nLastChar, LPINT lpBuffer) const
2710  {
2711  ATLASSERT(m_hDC != NULL);
2712  return ::GetCharWidth(m_hDC, nFirstChar, nLastChar, lpBuffer);
2713  }
2714 
2715  // GetCharWidth32 is not supported under Win9x
2716  BOOL GetCharWidth32(UINT nFirstChar, UINT nLastChar, LPINT lpBuffer) const
2717  {
2718  ATLASSERT(m_hDC != NULL);
2719  return ::GetCharWidth32(m_hDC, nFirstChar, nLastChar, lpBuffer);
2720  }
2721 
2722  DWORD SetMapperFlags(DWORD dwFlag)
2723  {
2724  ATLASSERT(m_hDC != NULL);
2725  return ::SetMapperFlags(m_hDC, dwFlag);
2726  }
2727 
2728  BOOL GetAspectRatioFilter(LPSIZE lpSize) const
2729  {
2730  ATLASSERT(m_hDC != NULL);
2731  return ::GetAspectRatioFilterEx(m_hDC, lpSize);
2732  }
2733 
2734  BOOL GetCharABCWidths(UINT nFirstChar, UINT nLastChar, LPABC lpabc) const
2735  {
2736  ATLASSERT(m_hDC != NULL);
2737  return ::GetCharABCWidths(m_hDC, nFirstChar, nLastChar, lpabc);
2738  }
2739 
2740  DWORD GetFontData(DWORD dwTable, DWORD dwOffset, LPVOID lpData, DWORD cbData) const
2741  {
2742  ATLASSERT(m_hDC != NULL);
2743  return ::GetFontData(m_hDC, dwTable, dwOffset, lpData, cbData);
2744  }
2745 
2746  int GetKerningPairs(int nPairs, LPKERNINGPAIR lpkrnpair) const
2747  {
2748  ATLASSERT(m_hDC != NULL);
2749  return ::GetKerningPairs(m_hDC, nPairs, lpkrnpair);
2750  }
2751 
2752  UINT GetOutlineTextMetrics(UINT cbData, LPOUTLINETEXTMETRIC lpotm) const
2753  {
2754  ATLASSERT(m_hDC != NULL);
2755  return ::GetOutlineTextMetrics(m_hDC, cbData, lpotm);
2756  }
2757 
2758  DWORD GetGlyphOutline(UINT nChar, UINT nFormat, LPGLYPHMETRICS lpgm, DWORD cbBuffer, LPVOID lpBuffer, const MAT2* lpmat2) const
2759  {
2760  ATLASSERT(m_hDC != NULL);
2761  return ::GetGlyphOutline(m_hDC, nChar, nFormat, lpgm, cbBuffer, lpBuffer, lpmat2);
2762  }
2763 
2764  BOOL GetCharABCWidths(UINT nFirstChar, UINT nLastChar, LPABCFLOAT lpABCF) const
2765  {
2766  ATLASSERT(m_hDC != NULL);
2767  return ::GetCharABCWidthsFloat(m_hDC, nFirstChar, nLastChar, lpABCF);
2768  }
2769 
2770  BOOL GetCharWidth(UINT nFirstChar, UINT nLastChar, float* lpFloatBuffer) const
2771  {
2772  ATLASSERT(m_hDC != NULL);
2773  return ::GetCharWidthFloat(m_hDC, nFirstChar, nLastChar, lpFloatBuffer);
2774  }
2775 #endif // !_WIN32_WCE
2776 
2777 // Printer/Device Escape Functions
2778 #ifndef _WIN32_WCE
2779  int Escape(int nEscape, int nCount, LPCSTR lpszInData, LPVOID lpOutData)
2780  {
2781  ATLASSERT(m_hDC != NULL);
2782  return ::Escape(m_hDC, nEscape, nCount, lpszInData, lpOutData);
2783  }
2784 #endif // !_WIN32_WCE
2785 
2786  int Escape(int nEscape, int nInputSize, LPCSTR lpszInputData,
2787  int nOutputSize, LPSTR lpszOutputData)
2788  {
2789  ATLASSERT(m_hDC != NULL);
2790  return ::ExtEscape(m_hDC, nEscape, nInputSize, lpszInputData, nOutputSize, lpszOutputData);
2791  }
2792 
2793 #ifndef _WIN32_WCE
2794  int DrawEscape(int nEscape, int nInputSize, LPCSTR lpszInputData)
2795  {
2796  ATLASSERT(m_hDC != NULL);
2797  return ::DrawEscape(m_hDC, nEscape, nInputSize, lpszInputData);
2798  }
2799 #endif // !_WIN32_WCE
2800 
2801  // Escape helpers
2802 #if !defined(_WIN32_WCE) || ((_WIN32_WCE >= 200) && defined(StartDoc))
2803  int StartDoc(LPCTSTR lpszDocName) // old Win3.0 version
2804  {
2805  DOCINFO di = { 0 };
2806  di.cbSize = sizeof(DOCINFO);
2807  di.lpszDocName = lpszDocName;
2808  return StartDoc(&di);
2809  }
2810 
2811  int StartDoc(LPDOCINFO lpDocInfo)
2812  {
2813  ATLASSERT(m_hDC != NULL);
2814  return ::StartDoc(m_hDC, lpDocInfo);
2815  }
2816 
2817  int StartPage()
2818  {
2819  ATLASSERT(m_hDC != NULL);
2820  return ::StartPage(m_hDC);
2821  }
2822 
2823  int EndPage()
2824  {
2825  ATLASSERT(m_hDC != NULL);
2826  return ::EndPage(m_hDC);
2827  }
2828 
2829  int SetAbortProc(BOOL (CALLBACK* lpfn)(HDC, int))
2830  {
2831  ATLASSERT(m_hDC != NULL);
2832  return ::SetAbortProc(m_hDC, (ABORTPROC)lpfn);
2833  }
2834 
2835  int AbortDoc()
2836  {
2837  ATLASSERT(m_hDC != NULL);
2838  return ::AbortDoc(m_hDC);
2839  }
2840 
2841  int EndDoc()
2842  {
2843  ATLASSERT(m_hDC != NULL);
2844  return ::EndDoc(m_hDC);
2845  }
2846 #endif // !defined(_WIN32_WCE) || ((_WIN32_WCE >= 200) && defined(StartDoc))
2847 
2848 // MetaFile Functions
2849 #ifndef _WIN32_WCE
2850  BOOL PlayMetaFile(HMETAFILE hMF)
2851  {
2852  ATLASSERT(m_hDC != NULL);
2853  if(::GetDeviceCaps(m_hDC, TECHNOLOGY) == DT_METAFILE)
2854  {
2855  // playing metafile in metafile, just use core windows API
2856  return ::PlayMetaFile(m_hDC, hMF);
2857  }
2858 
2859  // for special playback, lParam == pDC
2860  return ::EnumMetaFile(m_hDC, hMF, EnumMetaFileProc, (LPARAM)this);
2861  }
2862 
2863  BOOL PlayMetaFile(HENHMETAFILE hEnhMetaFile, LPCRECT lpBounds)
2864  {
2865  ATLASSERT(m_hDC != NULL);
2866  return ::PlayEnhMetaFile(m_hDC, hEnhMetaFile, lpBounds);
2867  }
2868 
2869  BOOL AddMetaFileComment(UINT nDataSize, const BYTE* pCommentData) // can be used for enhanced metafiles only
2870  {
2871  ATLASSERT(m_hDC != NULL);
2872  return ::GdiComment(m_hDC, nDataSize, pCommentData);
2873  }
2874 
2875  // Special handling for metafile playback
2876  static int CALLBACK EnumMetaFileProc(HDC hDC, HANDLETABLE* pHandleTable, METARECORD* pMetaRec, int nHandles, LPARAM lParam)
2877  {
2878  CDCHandle* pDC = (CDCHandle*)lParam;
2879 
2880  switch (pMetaRec->rdFunction)
2881  {
2882  case META_SETMAPMODE:
2883  pDC->SetMapMode((int)(short)pMetaRec->rdParm[0]);
2884  break;
2885  case META_SETWINDOWEXT:
2886  pDC->SetWindowExt((int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]);
2887  break;
2888  case META_SETWINDOWORG:
2889  pDC->SetWindowOrg((int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]);
2890  break;
2891  case META_SETVIEWPORTEXT:
2892  pDC->SetViewportExt((int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]);
2893  break;
2894  case META_SETVIEWPORTORG:
2895  pDC->SetViewportOrg((int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]);
2896  break;
2897  case META_SCALEWINDOWEXT:
2898  pDC->ScaleWindowExt((int)(short)pMetaRec->rdParm[3], (int)(short)pMetaRec->rdParm[2],
2899  (int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]);
2900  break;
2901  case META_SCALEVIEWPORTEXT:
2902  pDC->ScaleViewportExt((int)(short)pMetaRec->rdParm[3], (int)(short)pMetaRec->rdParm[2],
2903  (int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]);
2904  break;
2905  case META_OFFSETVIEWPORTORG:
2906  pDC->OffsetViewportOrg((int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]);
2907  break;
2908  case META_SAVEDC:
2909  pDC->SaveDC();
2910  break;
2911  case META_RESTOREDC:
2912  pDC->RestoreDC((int)(short)pMetaRec->rdParm[0]);
2913  break;
2914  case META_SETBKCOLOR:
2915  pDC->SetBkColor(*(UNALIGNED COLORREF*)&pMetaRec->rdParm[0]);
2916  break;
2917  case META_SETTEXTCOLOR:
2918  pDC->SetTextColor(*(UNALIGNED COLORREF*)&pMetaRec->rdParm[0]);
2919  break;
2920 
2921  // need to watch out for SelectObject(HFONT), for custom font mapping
2922  case META_SELECTOBJECT:
2923  {
2924  HGDIOBJ hObject = pHandleTable->objectHandle[pMetaRec->rdParm[0]];
2925  UINT nObjType = ::GetObjectType(hObject);
2926  if(nObjType == 0)
2927  {
2928  // object type is unknown, determine if it is a font
2929  HFONT hStockFont = (HFONT)::GetStockObject(SYSTEM_FONT);
2930  HFONT hFontOld = (HFONT)::SelectObject(pDC->m_hDC, hStockFont);
2931  HGDIOBJ hObjOld = ::SelectObject(pDC->m_hDC, hObject);
2932  if(hObjOld == hStockFont)
2933  {
2934  // got the stock object back, so must be selecting a font
2935  pDC->SelectFont((HFONT)hObject);
2936  break; // don't play the default record
2937  }
2938  else
2939  {
2940  // didn't get the stock object back, so restore everything
2941  ::SelectObject(pDC->m_hDC, hFontOld);
2942  ::SelectObject(pDC->m_hDC, hObjOld);
2943  }
2944  // and fall through to PlayMetaFileRecord...
2945  }
2946  else if(nObjType == OBJ_FONT)
2947  {
2948  // play back as CDCHandle::SelectFont(HFONT)
2949  pDC->SelectFont((HFONT)hObject);
2950  break; // don't play the default record
2951  }
2952  }
2953  // fall through...
2954 
2955  default:
2956  ::PlayMetaFileRecord(hDC, pHandleTable, pMetaRec, nHandles);
2957  break;
2958  }
2959 
2960  return 1;
2961  }
2962 #endif // !_WIN32_WCE
2963 
2964 // Path Functions
2965 #ifndef _WIN32_WCE
2966  BOOL AbortPath()
2967  {
2968  ATLASSERT(m_hDC != NULL);
2969  return ::AbortPath(m_hDC);
2970  }
2971 
2972  BOOL BeginPath()
2973  {
2974  ATLASSERT(m_hDC != NULL);
2975  return ::BeginPath(m_hDC);
2976  }
2977 
2978  BOOL CloseFigure()
2979  {
2980  ATLASSERT(m_hDC != NULL);
2981  return ::CloseFigure(m_hDC);
2982  }
2983 
2984  BOOL EndPath()
2985  {
2986  ATLASSERT(m_hDC != NULL);
2987  return ::EndPath(m_hDC);
2988  }
2989 
2990  BOOL FillPath()
2991  {
2992  ATLASSERT(m_hDC != NULL);
2993  return ::FillPath(m_hDC);
2994  }
2995 
2996  BOOL FlattenPath()
2997  {
2998  ATLASSERT(m_hDC != NULL);
2999  return ::FlattenPath(m_hDC);
3000  }
3001 
3002  BOOL StrokeAndFillPath()
3003  {
3004  ATLASSERT(m_hDC != NULL);
3005  return ::StrokeAndFillPath(m_hDC);
3006  }
3007 
3008  BOOL StrokePath()
3009  {
3010  ATLASSERT(m_hDC != NULL);
3011  return ::StrokePath(m_hDC);
3012  }
3013 
3014  BOOL WidenPath()
3015  {
3016  ATLASSERT(m_hDC != NULL);
3017  return ::WidenPath(m_hDC);
3018  }
3019 
3020  BOOL GetMiterLimit(PFLOAT pfMiterLimit) const
3021  {
3022  ATLASSERT(m_hDC != NULL);
3023  return ::GetMiterLimit(m_hDC, pfMiterLimit);
3024  }
3025 
3026  BOOL SetMiterLimit(float fMiterLimit)
3027  {
3028  ATLASSERT(m_hDC != NULL);
3029  return ::SetMiterLimit(m_hDC, fMiterLimit, NULL);
3030  }
3031 
3032  int GetPath(LPPOINT lpPoints, LPBYTE lpTypes, int nCount) const
3033  {
3034  ATLASSERT(m_hDC != NULL);
3035  return ::GetPath(m_hDC, lpPoints, lpTypes, nCount);
3036  }
3037 
3038  BOOL SelectClipPath(int nMode)
3039  {
3040  ATLASSERT(m_hDC != NULL);
3041  return ::SelectClipPath(m_hDC, nMode);
3042  }
3043 #endif // !_WIN32_WCE
3044 
3045 // Misc Helper Functions
3046  static CBrushHandle PASCAL GetHalftoneBrush()
3047  {
3048  HBRUSH halftoneBrush = NULL;
3049  WORD grayPattern[8] = { 0 };
3050  for(int i = 0; i < 8; i++)
3051  grayPattern[i] = (WORD)(0x5555 << (i & 1));
3052  HBITMAP grayBitmap = CreateBitmap(8, 8, 1, 1, &grayPattern);
3053  if(grayBitmap != NULL)
3054  {
3055  halftoneBrush = ::CreatePatternBrush(grayBitmap);
3056  DeleteObject(grayBitmap);
3057  }
3058  return CBrushHandle(halftoneBrush);
3059  }
3060 
3061  void DrawDragRect(LPCRECT lpRect, SIZE size, LPCRECT lpRectLast, SIZE sizeLast, HBRUSH hBrush = NULL, HBRUSH hBrushLast = NULL)
3062  {
3063  // first, determine the update region and select it
3064  CRgn rgnOutside;
3065  rgnOutside.CreateRectRgnIndirect(lpRect);
3066  RECT rect = *lpRect;
3067  ::InflateRect(&rect, -size.cx, -size.cy);
3068  ::IntersectRect(&rect, &rect, lpRect);
3069  CRgn rgnInside;
3070  rgnInside.CreateRectRgnIndirect(&rect);
3071  CRgn rgnNew;
3072  rgnNew.CreateRectRgn(0, 0, 0, 0);
3073  rgnNew.CombineRgn(rgnOutside, rgnInside, RGN_XOR);
3074 
3075  HBRUSH hBrushOld = NULL;
3076  CBrush brushHalftone;
3077  if(hBrush == NULL)
3078  brushHalftone = hBrush = CDCHandle::GetHalftoneBrush();
3079  if(hBrushLast == NULL)
3080  hBrushLast = hBrush;
3081 
3082  CRgn rgnLast;
3083  CRgn rgnUpdate;
3084  if(lpRectLast != NULL)
3085  {
3086  // find difference between new region and old region
3087  rgnLast.CreateRectRgn(0, 0, 0, 0);
3088  rgnOutside.SetRectRgn(lpRectLast->left, lpRectLast->top, lpRectLast->right, lpRectLast->bottom);
3089  rect = *lpRectLast;
3090  ::InflateRect(&rect, -sizeLast.cx, -sizeLast.cy);
3091  ::IntersectRect(&rect, &rect, lpRectLast);
3092  rgnInside.SetRectRgn(rect.left, rect.top, rect.right, rect.bottom);
3093  rgnLast.CombineRgn(rgnOutside, rgnInside, RGN_XOR);
3094 
3095  // only diff them if brushes are the same
3096  if(hBrush == hBrushLast)
3097  {
3098  rgnUpdate.CreateRectRgn(0, 0, 0, 0);
3099  rgnUpdate.CombineRgn(rgnLast, rgnNew, RGN_XOR);
3100  }
3101  }
3102  if(hBrush != hBrushLast && lpRectLast != NULL)
3103  {
3104  // brushes are different -- erase old region first
3105  SelectClipRgn(rgnLast);
3106  GetClipBox(&rect);
3107  hBrushOld = SelectBrush(hBrushLast);
3108  PatBlt(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, PATINVERT);
3109  SelectBrush(hBrushOld);
3110  hBrushOld = NULL;
3111  }
3112 
3113  // draw into the update/new region
3114  SelectClipRgn(rgnUpdate.IsNull() ? rgnNew : rgnUpdate);
3115  GetClipBox(&rect);
3116  hBrushOld = SelectBrush(hBrush);
3117  PatBlt(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, PATINVERT);
3118 
3119  // cleanup DC
3120  if(hBrushOld != NULL)
3121  SelectBrush(hBrushOld);
3122  SelectClipRgn(NULL);
3123  }
3124 
3125  void FillSolidRect(LPCRECT lpRect, COLORREF clr)
3126  {
3127  ATLASSERT(m_hDC != NULL);
3128 
3129  COLORREF clrOld = ::SetBkColor(m_hDC, clr);
3130  ATLASSERT(clrOld != CLR_INVALID);
3131  if(clrOld != CLR_INVALID)
3132  {
3133  ::ExtTextOut(m_hDC, 0, 0, ETO_OPAQUE, lpRect, NULL, 0, NULL);
3134  ::SetBkColor(m_hDC, clrOld);
3135  }
3136  }
3137 
3138  void FillSolidRect(int x, int y, int cx, int cy, COLORREF clr)
3139  {
3140  ATLASSERT(m_hDC != NULL);
3141 
3142  RECT rect = { x, y, x + cx, y + cy };
3143  FillSolidRect(&rect, clr);
3144  }
3145 
3146  void Draw3dRect(LPCRECT lpRect, COLORREF clrTopLeft, COLORREF clrBottomRight)
3147  {
3148  Draw3dRect(lpRect->left, lpRect->top, lpRect->right - lpRect->left,
3149  lpRect->bottom - lpRect->top, clrTopLeft, clrBottomRight);
3150  }
3151 
3152  void Draw3dRect(int x, int y, int cx, int cy, COLORREF clrTopLeft, COLORREF clrBottomRight)
3153  {
3154  FillSolidRect(x, y, cx - 1, 1, clrTopLeft);
3155  FillSolidRect(x, y, 1, cy - 1, clrTopLeft);
3156  FillSolidRect(x + cx, y, -1, cy, clrBottomRight);
3157  FillSolidRect(x, y + cy, cx, -1, clrBottomRight);
3158  }
3159 
3160 // DIB support
3161 #if !defined(_WIN32_WCE) || (_WIN32_WCE >= 410)
3162  int SetDIBitsToDevice(int x, int y, DWORD dwWidth, DWORD dwHeight, int xSrc, int ySrc, UINT uStartScan, UINT cScanLines, CONST VOID* lpvBits, CONST BITMAPINFO* lpbmi, UINT uColorUse)
3163  {
3164  ATLASSERT(m_hDC != NULL);
3165  return ::SetDIBitsToDevice(m_hDC, x, y, dwWidth, dwHeight, xSrc, ySrc, uStartScan, cScanLines, lpvBits, lpbmi, uColorUse);
3166  }
3167 #endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 410)
3168 
3169 #if !defined(_WIN32_WCE) || (_WIN32_WCE >= 400)
3170  int StretchDIBits(int x, int y, int nWidth, int nHeight, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, CONST VOID* lpvBits, CONST BITMAPINFO* lpbmi, UINT uColorUse, DWORD dwRop)
3171  {
3172  ATLASSERT(m_hDC != NULL);
3173  return ::StretchDIBits(m_hDC, x, y, nWidth, nHeight, xSrc, ySrc, nSrcWidth, nSrcHeight, lpvBits, lpbmi, uColorUse, dwRop);
3174  }
3175 
3176  UINT GetDIBColorTable(UINT uStartIndex, UINT cEntries, RGBQUAD* pColors) const
3177  {
3178  ATLASSERT(m_hDC != NULL);
3179  return ::GetDIBColorTable(m_hDC, uStartIndex, cEntries, pColors);
3180  }
3181 
3182  UINT SetDIBColorTable(UINT uStartIndex, UINT cEntries, CONST RGBQUAD* pColors)
3183  {
3184  ATLASSERT(m_hDC != NULL);
3185  return ::SetDIBColorTable(m_hDC, uStartIndex, cEntries, pColors);
3186  }
3187 #endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 400)
3188 
3189 // OpenGL support
3190 #if !defined(_ATL_NO_OPENGL) && !defined(_WIN32_WCE)
3191  int ChoosePixelFormat(CONST PIXELFORMATDESCRIPTOR* ppfd)
3192  {
3193  ATLASSERT(m_hDC != NULL);
3194  return ::ChoosePixelFormat(m_hDC, ppfd);
3195  }
3196 
3197  int DescribePixelFormat(int iPixelFormat, UINT nBytes, LPPIXELFORMATDESCRIPTOR ppfd)
3198  {
3199  ATLASSERT(m_hDC != NULL);
3200  return ::DescribePixelFormat(m_hDC, iPixelFormat, nBytes, ppfd);
3201  }
3202 
3203  int GetPixelFormat() const
3204  {
3205  ATLASSERT(m_hDC != NULL);
3206  return ::GetPixelFormat(m_hDC);
3207  }
3208 
3209  BOOL SetPixelFormat(int iPixelFormat, CONST PIXELFORMATDESCRIPTOR* ppfd)
3210  {
3211  ATLASSERT(m_hDC != NULL);
3212  return ::SetPixelFormat(m_hDC, iPixelFormat, ppfd);
3213  }
3214 
3215  BOOL SwapBuffers()
3216  {
3217  ATLASSERT(m_hDC != NULL);
3218  return ::SwapBuffers(m_hDC);
3219  }
3220 
3221  HGLRC wglCreateContext()
3222  {
3223  ATLASSERT(m_hDC != NULL);
3224  return ::wglCreateContext(m_hDC);
3225  }
3226 
3227  HGLRC wglCreateLayerContext(int iLayerPlane)
3228  {
3229  ATLASSERT(m_hDC != NULL);
3230  return ::wglCreateLayerContext(m_hDC, iLayerPlane);
3231  }
3232 
3233  BOOL wglMakeCurrent(HGLRC hglrc)
3234  {
3235  ATLASSERT(m_hDC != NULL);
3236  return ::wglMakeCurrent(m_hDC, hglrc);
3237  }
3238 
3239  BOOL wglUseFontBitmaps(DWORD dwFirst, DWORD dwCount, DWORD listBase)
3240  {
3241  ATLASSERT(m_hDC != NULL);
3242  return ::wglUseFontBitmaps(m_hDC, dwFirst, dwCount, listBase);
3243  }
3244 
3245  BOOL wglUseFontOutlines(DWORD dwFirst, DWORD dwCount, DWORD listBase, FLOAT deviation, FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT lpgmf)
3246  {
3247  ATLASSERT(m_hDC != NULL);
3248  return ::wglUseFontOutlines(m_hDC, dwFirst, dwCount, listBase, deviation, extrusion, format, lpgmf);
3249  }
3250 
3251  BOOL wglDescribeLayerPlane(int iPixelFormat, int iLayerPlane, UINT nBytes, LPLAYERPLANEDESCRIPTOR plpd)
3252  {
3253  ATLASSERT(m_hDC != NULL);
3254  return ::wglDescribeLayerPlane(m_hDC, iPixelFormat, iLayerPlane, nBytes, plpd);
3255  }
3256 
3257  int wglSetLayerPaletteEntries(int iLayerPlane, int iStart, int cEntries, CONST COLORREF* pclr)
3258  {
3259  ATLASSERT(m_hDC != NULL);
3260  return ::wglSetLayerPaletteEntries(m_hDC, iLayerPlane, iStart, cEntries, pclr);
3261  }
3262 
3263  int wglGetLayerPaletteEntries(int iLayerPlane, int iStart, int cEntries, COLORREF* pclr)
3264  {
3265  ATLASSERT(m_hDC != NULL);
3266  return ::wglGetLayerPaletteEntries(m_hDC, iLayerPlane, iStart, cEntries, pclr);
3267  }
3268 
3269  BOOL wglRealizeLayerPalette(int iLayerPlane, BOOL bRealize)
3270  {
3271  ATLASSERT(m_hDC != NULL);
3272  return ::wglRealizeLayerPalette(m_hDC, iLayerPlane, bRealize);
3273  }
3274 
3275  BOOL wglSwapLayerBuffers(UINT uPlanes)
3276  {
3277  ATLASSERT(m_hDC != NULL);
3278  return ::wglSwapLayerBuffers(m_hDC, uPlanes);
3279  }
3280 #endif // !defined(_ATL_NO_OPENGL) && !defined(_WIN32_WCE)
3281 
3282 // New for Windows 2000 only
3283 #if (_WIN32_WINNT >= 0x0500)
3284  COLORREF GetDCPenColor() const
3285  {
3286  ATLASSERT(m_hDC != NULL);
3287  return ::GetDCPenColor(m_hDC);
3288  }
3289 
3290  COLORREF SetDCPenColor(COLORREF clr)
3291  {
3292  ATLASSERT(m_hDC != NULL);
3293  return ::SetDCPenColor(m_hDC, clr);
3294  }
3295 
3296  COLORREF GetDCBrushColor() const
3297  {
3298  ATLASSERT(m_hDC != NULL);
3299  return ::GetDCBrushColor(m_hDC);
3300  }
3301 
3302  COLORREF SetDCBrushColor(COLORREF clr)
3303  {
3304  ATLASSERT(m_hDC != NULL);
3305  return ::SetDCBrushColor(m_hDC, clr);
3306  }
3307 
3308 #ifndef _WIN32_WCE
3309  DWORD GetFontUnicodeRanges(LPGLYPHSET lpgs) const
3310  {
3311  ATLASSERT(m_hDC != NULL);
3312  return ::GetFontUnicodeRanges(m_hDC, lpgs);
3313  }
3314 #endif // !_WIN32_WCE
3315 
3316  DWORD GetGlyphIndices(LPCTSTR lpstr, int cch, LPWORD pgi, DWORD dwFlags) const
3317  {
3318  ATLASSERT(m_hDC != NULL);
3319  return ::GetGlyphIndices(m_hDC, lpstr, cch, pgi, dwFlags);
3320  }
3321 
3322  BOOL GetTextExtentPointI(LPWORD pgiIn, int cgi, LPSIZE lpSize) const
3323  {
3324  ATLASSERT(m_hDC != NULL);
3325  return ::GetTextExtentPointI(m_hDC, pgiIn, cgi, lpSize);
3326  }
3327 
3328  BOOL GetTextExtentExPointI(LPWORD pgiIn, int cgi, int nMaxExtent, LPINT lpnFit, LPINT alpDx, LPSIZE lpSize) const
3329  {
3330  ATLASSERT(m_hDC != NULL);
3331  return ::GetTextExtentExPointI(m_hDC, pgiIn, cgi, nMaxExtent, lpnFit, alpDx, lpSize);
3332  }
3333 
3334  BOOL GetCharWidthI(UINT giFirst, UINT cgi, LPWORD pgi, LPINT lpBuffer) const
3335  {
3336  ATLASSERT(m_hDC != NULL);
3337  return ::GetCharWidthI(m_hDC, giFirst, cgi, pgi, lpBuffer);
3338  }
3339 
3340  BOOL GetCharABCWidthsI(UINT giFirst, UINT cgi, LPWORD pgi, LPABC lpabc) const
3341  {
3342  ATLASSERT(m_hDC != NULL);
3343  return ::GetCharABCWidthsI(m_hDC, giFirst, cgi, pgi, lpabc);
3344  }
3345 #endif // (_WIN32_WINNT >= 0x0500)
3346 
3347 // New for Windows 2000 and Windows 98
3348 #if (WINVER >= 0x0500) && !defined(_WIN32_WCE)
3349  BOOL ColorCorrectPalette(HPALETTE hPalette, DWORD dwFirstEntry, DWORD dwNumOfEntries)
3350  {
3351  ATLASSERT(m_hDC != NULL);
3352  return ::ColorCorrectPalette(m_hDC, hPalette, dwFirstEntry, dwNumOfEntries);
3353  }
3354 #endif // (WINVER >= 0x0500) && !defined(_WIN32_WCE)
3355 };
3356 
3357 typedef CDCT<false> CDCHandle;
3358 typedef CDCT<true> CDC;
3359 
3360 
3362 // CDC Helpers
3363 
3364 class CPaintDC : public CDC
3365 {
3366 public:
3367 // Data members
3368  HWND m_hWnd;
3369  PAINTSTRUCT m_ps;
3370 
3371 // Constructor/destructor
3372  CPaintDC(HWND hWnd)
3373  {
3374  ATLASSERT(::IsWindow(hWnd));
3375  m_hWnd = hWnd;
3376  m_hDC = ::BeginPaint(hWnd, &m_ps);
3377  }
3378 
3379  ~CPaintDC()
3380  {
3381  ATLASSERT(m_hDC != NULL);
3382  ATLASSERT(::IsWindow(m_hWnd));
3383  ::EndPaint(m_hWnd, &m_ps);
3384  Detach();
3385  }
3386 };
3387 
3388 class CClientDC : public CDC
3389 {
3390 public:
3391 // Data members
3392  HWND m_hWnd;
3393 
3394 // Constructor/destructor
3395  CClientDC(HWND hWnd)
3396  {
3397  ATLASSERT(hWnd == NULL || ::IsWindow(hWnd));
3398  m_hWnd = hWnd;
3399  m_hDC = ::GetDC(hWnd);
3400  }
3401 
3402  ~CClientDC()
3403  {
3404  ATLASSERT(m_hDC != NULL);
3405  ::ReleaseDC(m_hWnd, Detach());
3406  }
3407 };
3408 
3409 class CWindowDC : public CDC
3410 {
3411 public:
3412 // Data members
3413  HWND m_hWnd;
3414 
3415 // Constructor/destructor
3416  CWindowDC(HWND hWnd)
3417  {
3418  ATLASSERT(hWnd == NULL || ::IsWindow(hWnd));
3419  m_hWnd = hWnd;
3420  m_hDC = ::GetWindowDC(hWnd);
3421  }
3422 
3423  ~CWindowDC()
3424  {
3425  ATLASSERT(m_hDC != NULL);
3426  ::ReleaseDC(m_hWnd, Detach());
3427  }
3428 };
3429 
3430 class CMemoryDC : public CDC
3431 {
3432 public:
3433 // Data members
3434  HDC m_hDCOriginal;
3435  RECT m_rcPaint;
3436  CBitmap m_bmp;
3437  HBITMAP m_hBmpOld;
3438 
3439 // Constructor/destructor
3440  CMemoryDC(HDC hDC, RECT& rcPaint) : m_hDCOriginal(hDC), m_hBmpOld(NULL)
3441  {
3442  m_rcPaint = rcPaint;
3443  CreateCompatibleDC(m_hDCOriginal);
3444  ATLASSERT(m_hDC != NULL);
3445  m_bmp.CreateCompatibleBitmap(m_hDCOriginal, m_rcPaint.right - m_rcPaint.left, m_rcPaint.bottom - m_rcPaint.top);
3446  ATLASSERT(m_bmp.m_hBitmap != NULL);
3447  m_hBmpOld = SelectBitmap(m_bmp);
3448  SetViewportOrg(-m_rcPaint.left, -m_rcPaint.top);
3449  }
3450 
3451  ~CMemoryDC()
3452  {
3453  ::BitBlt(m_hDCOriginal, m_rcPaint.left, m_rcPaint.top, m_rcPaint.right - m_rcPaint.left, m_rcPaint.bottom - m_rcPaint.top, m_hDC, m_rcPaint.left, m_rcPaint.top, SRCCOPY);
3454  SelectBitmap(m_hBmpOld);
3455  }
3456 };
3457 
3458 
3460 // Enhanced metafile support
3461 
3462 #ifndef _WIN32_WCE
3463 
3465 {
3466 public:
3467 // Data members
3468  HENHMETAFILE m_hEMF;
3469  BYTE* m_pBits;
3470  TCHAR* m_pDesc;
3471  ENHMETAHEADER m_header;
3472  PIXELFORMATDESCRIPTOR m_pfd;
3473 
3474 // Constructor/destructor
3475  CEnhMetaFileInfo(HENHMETAFILE hEMF) : m_pBits(NULL), m_pDesc(NULL), m_hEMF(hEMF)
3476  { }
3477 
3478  ~CEnhMetaFileInfo()
3479  {
3480  delete [] m_pBits;
3481  delete [] m_pDesc;
3482  }
3483 
3484 // Operations
3485  BYTE* GetEnhMetaFileBits()
3486  {
3487  ATLASSERT(m_hEMF != NULL);
3488  UINT nBytes = ::GetEnhMetaFileBits(m_hEMF, 0, NULL);
3489  delete [] m_pBits;
3490  m_pBits = NULL;
3491  ATLTRY(m_pBits = new BYTE[nBytes]);
3492  if (m_pBits != NULL)
3493  ::GetEnhMetaFileBits(m_hEMF, nBytes, m_pBits);
3494  return m_pBits;
3495  }
3496 
3497  LPTSTR GetEnhMetaFileDescription()
3498  {
3499  ATLASSERT(m_hEMF != NULL);
3500  UINT nLen = ::GetEnhMetaFileDescription(m_hEMF, 0, NULL);
3501  delete [] m_pDesc;
3502  m_pDesc = NULL;
3503  ATLTRY(m_pDesc = new TCHAR[nLen]);
3504  if (m_pDesc != NULL)
3505  nLen = ::GetEnhMetaFileDescription(m_hEMF, nLen, m_pDesc);
3506  return m_pDesc;
3507  }
3508 
3509  ENHMETAHEADER* GetEnhMetaFileHeader()
3510  {
3511  ATLASSERT(m_hEMF != NULL);
3512  memset(&m_header, 0, sizeof(m_header));
3513  m_header.iType = EMR_HEADER;
3514  m_header.nSize = sizeof(ENHMETAHEADER);
3515  UINT n = ::GetEnhMetaFileHeader(m_hEMF, sizeof(ENHMETAHEADER), &m_header);
3516  return (n != 0) ? &m_header : NULL;
3517  }
3518 
3519  PIXELFORMATDESCRIPTOR* GetEnhMetaFilePixelFormat()
3520  {
3521  ATLASSERT(m_hEMF != NULL);
3522  memset(&m_pfd, 0, sizeof(m_pfd));
3523  UINT n = ::GetEnhMetaFilePixelFormat(m_hEMF, sizeof(m_pfd), &m_pfd);
3524  return (n != 0) ? &m_pfd : NULL;
3525  }
3526 };
3527 
3528 
3529 template <bool t_bManaged>
3531 {
3532 public:
3533 // Data members
3534  HENHMETAFILE m_hEMF;
3535 
3536 // Constructor/destructor
3537  CEnhMetaFileT(HENHMETAFILE hEMF = NULL) : m_hEMF(hEMF)
3538  {
3539  }
3540 
3541  ~CEnhMetaFileT()
3542  {
3543  if(t_bManaged && m_hEMF != NULL)
3544  DeleteObject();
3545  }
3546 
3547 // Operations
3548  CEnhMetaFileT<t_bManaged>& operator =(HENHMETAFILE hEMF)
3549  {
3550  Attach(hEMF);
3551  return *this;
3552  }
3553 
3554  void Attach(HENHMETAFILE hEMF)
3555  {
3556  if(t_bManaged && m_hEMF != NULL && m_hEMF != hEMF)
3557  DeleteObject();
3558  m_hEMF = hEMF;
3559  }
3560 
3561  HENHMETAFILE Detach()
3562  {
3563  HENHMETAFILE hEMF = m_hEMF;
3564  m_hEMF = NULL;
3565  return hEMF;
3566  }
3567 
3568  operator HENHMETAFILE() const { return m_hEMF; }
3569 
3570  bool IsNull() const { return (m_hEMF == NULL); }
3571 
3572  BOOL DeleteObject()
3573  {
3574  ATLASSERT(m_hEMF != NULL);
3575  BOOL bRet = ::DeleteEnhMetaFile(m_hEMF);
3576  m_hEMF = NULL;
3577  return bRet;
3578  }
3579 
3580  UINT GetEnhMetaFileBits(UINT cbBuffer, LPBYTE lpbBuffer) const
3581  {
3582  ATLASSERT(m_hEMF != NULL);
3583  return ::GetEnhMetaFileBits(m_hEMF, cbBuffer, lpbBuffer);
3584  }
3585 
3586  UINT GetEnhMetaFileDescription(UINT cchBuffer, LPTSTR lpszDescription) const
3587  {
3588  ATLASSERT(m_hEMF != NULL);
3589  return ::GetEnhMetaFileDescription(m_hEMF, cchBuffer, lpszDescription);
3590  }
3591 
3592  UINT GetEnhMetaFileHeader(LPENHMETAHEADER lpemh) const
3593  {
3594  ATLASSERT(m_hEMF != NULL);
3595  lpemh->iType = EMR_HEADER;
3596  lpemh->nSize = sizeof(ENHMETAHEADER);
3597  return ::GetEnhMetaFileHeader(m_hEMF, sizeof(ENHMETAHEADER), lpemh);
3598  }
3599 
3600  UINT GetEnhMetaFilePaletteEntries(UINT cEntries, LPPALETTEENTRY lppe) const
3601  {
3602  ATLASSERT(m_hEMF != NULL);
3603  return ::GetEnhMetaFilePaletteEntries(m_hEMF, cEntries, lppe);
3604  }
3605 
3606  UINT GetEnhMetaFilePixelFormat(DWORD cbBuffer, PIXELFORMATDESCRIPTOR* ppfd) const
3607  {
3608  ATLASSERT(m_hEMF != NULL);
3609  return ::GetEnhMetaFilePixelFormat(m_hEMF, cbBuffer, ppfd);
3610  }
3611 };
3612 
3615 
3616 
3617 class CEnhMetaFileDC : public CDC
3618 {
3619 public:
3620 // Constructor/destructor
3621  CEnhMetaFileDC()
3622  {
3623  }
3624 
3625  CEnhMetaFileDC(HDC hdc, LPCRECT lpRect)
3626  {
3627  Create(hdc, NULL, lpRect, NULL);
3628  ATLASSERT(m_hDC != NULL);
3629  }
3630 
3631  CEnhMetaFileDC(HDC hdcRef, LPCTSTR lpFilename, LPCRECT lpRect, LPCTSTR lpDescription)
3632  {
3633  Create(hdcRef, lpFilename, lpRect, lpDescription);
3634  ATLASSERT(m_hDC != NULL);
3635  }
3636 
3637  ~CEnhMetaFileDC()
3638  {
3639  HENHMETAFILE hEMF = Close();
3640  if (hEMF != NULL)
3641  ::DeleteEnhMetaFile(hEMF);
3642  }
3643 
3644 // Operations
3645  void Create(HDC hdcRef, LPCTSTR lpFilename, LPCRECT lpRect, LPCTSTR lpDescription)
3646  {
3647  ATLASSERT(m_hDC == NULL);
3648  m_hDC = ::CreateEnhMetaFile(hdcRef, lpFilename, lpRect, lpDescription);
3649  }
3650 
3651  HENHMETAFILE Close()
3652  {
3653  HENHMETAFILE hEMF = NULL;
3654  if (m_hDC != NULL)
3655  {
3656  hEMF = ::CloseEnhMetaFile(m_hDC);
3657  m_hDC = NULL;
3658  }
3659  return hEMF;
3660  }
3661 };
3662 
3663 #endif // !_WIN32_WCE
3664 
3665 
3667 // WinCE compatible clipboard CF_DIB format support functions
3668 
3669 #ifndef _WTL_NO_DIB16
3670 
3671 #define DIBINFO16_BITFIELDS { 31744, 992, 31 }
3672 
3673 // DIBINFO16 - To avoid color table problems in WinCE we only create this type of Dib
3674 struct DIBINFO16 // a BITMAPINFO with 2 additional color bitfields
3675 {
3676  BITMAPINFOHEADER bmiHeader;
3677  RGBQUAD bmiColors[3];
3678 
3679  DIBINFO16(SIZE size)
3680  {
3681  BITMAPINFOHEADER bmih = { sizeof(BITMAPINFOHEADER), size.cx, size.cy,
3682  1, 16, BI_BITFIELDS, 2 * size.cx * size.cy , 0, 0, 3 };
3683  DWORD dw[3] = DIBINFO16_BITFIELDS ;
3684 
3685  bmiHeader = bmih;
3686  SecureHelper::memcpy_x(bmiColors, sizeof(bmiColors), dw, 3 * sizeof(DWORD));
3687  }
3688 };
3689 
3690 
3691 // AtlxxxDibxxx minimal packed DIB implementation and helpers to copy and paste CF_DIB
3692 
3693 inline bool AtlIsDib16(LPBITMAPINFOHEADER pbmih)
3694 {
3695  return (pbmih->biBitCount == 16) && (pbmih->biCompression == BI_BITFIELDS);
3696 }
3697 
3698 inline int AtlGetDibColorTableSize(LPBITMAPINFOHEADER pbmih)
3699 {
3700  switch (pbmih->biBitCount)
3701  {
3702  case 2:
3703  case 4:
3704  case 8:
3705  return pbmih->biClrUsed ? pbmih->biClrUsed : 1 << pbmih->biBitCount;
3706  case 24:
3707  break;
3708  case 16:
3709  case 32:
3710  return pbmih->biCompression == BI_BITFIELDS ? 3 : 0;
3711  default:
3712  ATLASSERT(FALSE); // should never come here
3713  }
3714 
3715  return 0;
3716 }
3717 
3718 inline int AtlGetDibNumColors(LPBITMAPINFOHEADER pbmih)
3719 {
3720  switch (pbmih->biBitCount)
3721  {
3722  case 2:
3723  case 4:
3724  case 8:
3725  if (pbmih->biClrUsed)
3726  return pbmih->biClrUsed;
3727  else
3728  break;
3729  case 16:
3730  if (pbmih->biCompression == BI_BITFIELDS )
3731  return 1 << 15;
3732  else
3733  break;
3734  case 24:
3735  break;
3736  case 32:
3737  if (pbmih->biCompression == BI_BITFIELDS )
3738  return 1 << 24;
3739  else
3740  break;
3741  default:
3742  ATLASSERT(FALSE);
3743  }
3744 
3745  return 1 << pbmih->biBitCount;
3746 }
3747 
3748 inline HBITMAP AtlGetDibBitmap(LPBITMAPINFO pbmi)
3749 {
3750  CDC dc(NULL);
3751  void* pBits = NULL;
3752 
3753  LPBYTE pDibBits = (LPBYTE)pbmi + sizeof(BITMAPINFOHEADER) + AtlGetDibColorTableSize(&pbmi->bmiHeader) * sizeof(RGBQUAD);
3754  HBITMAP hbm = CreateDIBSection(dc, pbmi, DIB_RGB_COLORS, &pBits, NULL, NULL);
3755  if (hbm != NULL)
3756  {
3757  int cbBits = pbmi->bmiHeader.biWidth * pbmi->bmiHeader.biHeight * pbmi->bmiHeader.biBitCount / 8;
3758  SecureHelper::memcpy_x(pBits, cbBits, pDibBits, pbmi->bmiHeader.biSizeImage);
3759  }
3760 
3761  return hbm;
3762 }
3763 
3764 inline HBITMAP AtlCopyBitmap(HBITMAP hbm, SIZE sizeDst, bool bAsBitmap = false)
3765 {
3766  CDC hdcSrc = CreateCompatibleDC(NULL);
3767  CDC hdcDst = CreateCompatibleDC(NULL);
3768 
3769  CBitmapHandle hbmOld = NULL, hbmOld2 = NULL, bmSrc = hbm;
3770 
3771  CBitmap bmNew = NULL;
3772 
3773  SIZE sizeSrc = { 0 };
3774  bmSrc.GetSize(sizeSrc);
3775 
3776  hbmOld = hdcSrc.SelectBitmap(bmSrc);
3777 
3778  if (bAsBitmap)
3779  {
3780  bmNew.CreateCompatibleBitmap(hdcSrc, sizeDst.cx, sizeDst.cy);
3781  }
3782  else
3783  {
3784  DIBINFO16 dib16(sizeDst);
3785  LPVOID pBits = NULL;
3786  bmNew = CreateDIBSection(hdcDst, (const BITMAPINFO*)&dib16, DIB_RGB_COLORS, &pBits, NULL, NULL);
3787  }
3788 
3789  ATLASSERT(!bmNew.IsNull());
3790 
3791  hbmOld2 = hdcDst.SelectBitmap(bmNew);
3792  BOOL bOK = FALSE;
3793 
3794  if ((sizeDst.cx == sizeSrc.cx) && (sizeDst.cy == sizeSrc.cy))
3795  bOK = hdcDst.BitBlt(0, 0, sizeDst.cx, sizeDst.cy, hdcSrc, 0, 0, SRCCOPY);
3796  else
3797  bOK = hdcDst.StretchBlt(0, 0, sizeDst.cx, sizeDst.cy, hdcSrc, 0, 0, sizeSrc.cx, sizeSrc.cy, SRCCOPY);
3798 
3799  hdcSrc.SelectBitmap(hbmOld);
3800  hdcDst.SelectBitmap(hbmOld2);
3801 
3802  if (bOK == FALSE)
3803  bmNew.DeleteObject();
3804 
3805  return bmNew.Detach();
3806 }
3807 
3808 inline HLOCAL AtlCreatePackedDib16(HBITMAP hbm, SIZE size)
3809 {
3810  DIBSECTION ds = { 0 };
3811  LPBYTE pDib = NULL;
3812  bool bCopied = false;
3813 
3814  bool bOK = GetObject(hbm, sizeof(ds), &ds) == sizeof(ds);
3815  if ((bOK == FALSE) || (ds.dsBm.bmBits == NULL) || (AtlIsDib16(&ds.dsBmih) == FALSE) ||
3816  (ds.dsBmih.biWidth != size.cx ) || (ds.dsBmih.biHeight != size.cy ))
3817  {
3818  if ((hbm = AtlCopyBitmap(hbm, size)) != NULL)
3819  {
3820  bCopied = true;
3821  bOK = GetObject(hbm, sizeof(ds), &ds) == sizeof(ds);
3822  }
3823  else
3824  {
3825  bOK = FALSE;
3826  }
3827  }
3828 
3829  if((bOK != FALSE) && (AtlIsDib16(&ds.dsBmih) != FALSE) && (ds.dsBm.bmBits != NULL))
3830  {
3831  pDib = (LPBYTE)LocalAlloc(LMEM_ZEROINIT, sizeof(DIBINFO16) + ds.dsBmih.biSizeImage);
3832  if (pDib != NULL)
3833  {
3834  SecureHelper::memcpy_x(pDib, sizeof(DIBINFO16) + ds.dsBmih.biSizeImage, &ds.dsBmih, sizeof(DIBINFO16));
3835  SecureHelper::memcpy_x(pDib + sizeof(DIBINFO16), ds.dsBmih.biSizeImage, ds.dsBm.bmBits, ds.dsBmih.biSizeImage);
3836  }
3837  }
3838 
3839  if (bCopied == true)
3840  DeleteObject(hbm);
3841 
3842  return (HLOCAL)pDib;
3843 }
3844 
3845 inline bool AtlSetClipboardDib16(HBITMAP hbm, SIZE size, HWND hWnd)
3846 {
3847  ATLASSERT(::IsWindow(hWnd));
3848  BOOL bOK = OpenClipboard(hWnd);
3849  if (bOK != FALSE)
3850  {
3851  bOK = EmptyClipboard();
3852  if (bOK != FALSE)
3853  {
3854  HLOCAL hDib = AtlCreatePackedDib16(hbm, size);
3855  if (hDib != NULL)
3856  {
3857  bOK = SetClipboardData(CF_DIB, hDib) != NULL;
3858  if (bOK == FALSE)
3859  LocalFree(hDib);
3860  }
3861  else
3862  {
3863  bOK = FALSE;
3864  }
3865  }
3866  CloseClipboard();
3867  }
3868 
3869  return (bOK != FALSE);
3870 }
3871 
3872 inline HBITMAP AtlGetClipboardDib(HWND hWnd)
3873 {
3874  ATLASSERT(::IsWindow(hWnd) != FALSE);
3875  HBITMAP hbm = NULL;
3876  if (OpenClipboard(hWnd) != FALSE)
3877  {
3878  LPBITMAPINFO pbmi = (LPBITMAPINFO)GetClipboardData(CF_DIB);
3879  if (pbmi != NULL)
3880  hbm = AtlGetDibBitmap(pbmi);
3881  CloseClipboard();
3882  }
3883 
3884  return hbm;
3885 }
3886 
3887 #endif // _WTL_NO_DIB16
3888 
3889 }; // namespace WTL
3890 
3891 #endif // __ATLGDI_H__
Definition: atlwinx.h:455
Definition: atlgdi.h:542
Definition: atlgdi.h:1007
Definition: atlgdi.h:3617
Definition: atlgdi.h:121
Definition: atlgdi.h:889
Definition: atlgdi.h:3388
Definition: atlgdi.h:361
Definition: atlapp.h:484
Definition: atlgdi.h:3674
Definition: atlapp.h:1317
Definition: atlgdi.h:1211
Definition: atlgdi.h:692
Definition: atlgdi.h:230
Definition: atlgdi.h:3364
Definition: atlgdi.h:3409
Definition: atlgdi.h:3530
Definition: atlgdi.h:3464
Definition: atlgdi.h:3430