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