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