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