comparison foosdk/wtl/Include/atlgdi.h @ 1:20d02a178406 default tip

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