Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2876 lines
77 KiB

  1. // WTL Version 3.1
  2. // Copyright (C) 1997-2000 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This file is a part of Windows Template Library.
  6. // The code and information is provided "as-is" without
  7. // warranty of any kind, either expressed or implied.
  8. #ifndef __ATLGDI_H__
  9. #define __ATLGDI_H__
  10. #pragma once
  11. #ifndef __cplusplus
  12. #error ATL requires C++ compilation (use a .cpp suffix)
  13. #endif
  14. #ifndef __ATLBASE_H__
  15. #error atlgdi.h requires atlbase.h to be included first
  16. #endif
  17. // protect template members from windowsx.h macros
  18. #ifdef _INC_WINDOWSX
  19. #undef CopyRgn
  20. #undef CreateBrush
  21. #undef CreatePen
  22. #undef SelectBrush
  23. #undef SelectPen
  24. #undef SelectFont
  25. #undef SelectBitmap
  26. #endif //_INC_WINDOWSX
  27. // required libraries
  28. #ifndef _ATL_NO_MSIMG
  29. #pragma comment(lib, "msimg32.lib")
  30. #endif //!_ATL_NO_MSIMG
  31. #ifndef _ATL_NO_OPENGL
  32. #pragma comment(lib, "opengl32.lib")
  33. #endif //!_ATL_NO_OPENGL
  34. namespace WTL
  35. {
  36. /////////////////////////////////////////////////////////////////////////////
  37. // Forward declarations
  38. template <bool t_bManaged> class CPenT;
  39. template <bool t_bManaged> class CBrushT;
  40. template <bool t_bManaged> class CFontT;
  41. template <bool t_bManaged> class CBitmapT;
  42. template <bool t_bManaged> class CPaletteT;
  43. template <bool t_bManaged> class CRgnT;
  44. template <bool t_bManaged> class CDCT;
  45. class CPaintDC;
  46. class CClientDC;
  47. class CWindowDC;
  48. class CEnhMetaFileInfo;
  49. template <bool t_bManaged> class CEnhMetaFileT;
  50. class CEnhMetaFileDC;
  51. /////////////////////////////////////////////////////////////////////////////
  52. // CPen
  53. typedef CPenT<false> CPenHandle;
  54. typedef CPenT<true> CPen;
  55. template <bool t_bManaged>
  56. class CPenT
  57. {
  58. public:
  59. // Data members
  60. HPEN m_hPen;
  61. // Constructor/destructor/operators
  62. CPenT(HPEN hPen = NULL) : m_hPen(hPen)
  63. { }
  64. ~CPenT()
  65. {
  66. if(t_bManaged && m_hPen != NULL)
  67. DeleteObject();
  68. }
  69. CPenT<t_bManaged>& operator=(HPEN hPen)
  70. {
  71. m_hPen = hPen;
  72. return *this;
  73. }
  74. void Attach(HPEN hPen)
  75. {
  76. if(t_bManaged && m_hPen != NULL)
  77. ::DeleteObject(m_hPen);
  78. m_hPen = hPen;
  79. }
  80. HPEN Detach()
  81. {
  82. HPEN hPen = m_hPen;
  83. m_hPen = NULL;
  84. return hPen;
  85. }
  86. operator HPEN() const { return m_hPen; }
  87. bool IsNull() const { return (m_hPen == NULL); }
  88. // Create methods
  89. HPEN CreatePen(int nPenStyle, int nWidth, COLORREF crColor)
  90. {
  91. ATLASSERT(m_hPen == NULL);
  92. m_hPen = ::CreatePen(nPenStyle, nWidth, crColor);
  93. return m_hPen;
  94. }
  95. HPEN CreatePen(int nPenStyle, int nWidth, const LOGBRUSH* pLogBrush, int nStyleCount = 0, const DWORD* lpStyle = NULL)
  96. {
  97. ATLASSERT(m_hPen == NULL);
  98. m_hPen = ::ExtCreatePen(nPenStyle, nWidth, pLogBrush, nStyleCount, lpStyle);
  99. return m_hPen;
  100. }
  101. HPEN CreatePenIndirect(LPLOGPEN lpLogPen)
  102. {
  103. ATLASSERT(m_hPen == NULL);
  104. m_hPen = ::CreatePenIndirect(lpLogPen);
  105. return m_hPen;
  106. }
  107. BOOL DeleteObject()
  108. {
  109. ATLASSERT(m_hPen != NULL);
  110. BOOL bRet = ::DeleteObject(m_hPen);
  111. if(bRet)
  112. m_hPen = NULL;
  113. return bRet;
  114. }
  115. // Attributes
  116. int GetLogPen(LOGPEN* pLogPen) const
  117. {
  118. ATLASSERT(m_hPen != NULL);
  119. return ::GetObject(m_hPen, sizeof(LOGPEN), pLogPen);
  120. }
  121. bool GetLogPen(LOGPEN& LogPen) const
  122. {
  123. ATLASSERT(m_hPen != NULL);
  124. return (::GetObject(m_hPen, sizeof(LOGPEN), &LogPen) == sizeof(LOGPEN));
  125. }
  126. int GetExtLogPen(EXTLOGPEN* pLogPen) const
  127. {
  128. ATLASSERT(m_hPen != NULL);
  129. return ::GetObject(m_hPen, sizeof(EXTLOGPEN), pLogPen);
  130. }
  131. bool GetExtLogPen(EXTLOGPEN& ExtLogPen) const
  132. {
  133. ATLASSERT(m_hPen != NULL);
  134. return (::GetObject(m_hPen, sizeof(EXTLOGPEN), &ExtLogPen) == sizeof(EXTLOGPEN));
  135. }
  136. };
  137. /////////////////////////////////////////////////////////////////////////////
  138. // CBrush
  139. typedef CBrushT<false> CBrushHandle;
  140. typedef CBrushT<true> CBrush;
  141. template <bool t_bManaged>
  142. class CBrushT
  143. {
  144. public:
  145. // Data members
  146. HBRUSH m_hBrush;
  147. // Constructor/destructor/operators
  148. CBrushT(HBRUSH hBrush = NULL) : m_hBrush(hBrush)
  149. { }
  150. ~CBrushT()
  151. {
  152. if(t_bManaged && m_hBrush != NULL)
  153. DeleteObject();
  154. }
  155. CBrushT<t_bManaged>& operator=(HBRUSH hBrush)
  156. {
  157. m_hBrush = hBrush;
  158. return *this;
  159. }
  160. void Attach(HBRUSH hBrush)
  161. {
  162. if(t_bManaged && m_hBrush != NULL)
  163. ::DeleteObject(m_hBrush);
  164. m_hBrush = hBrush;
  165. }
  166. HBRUSH Detach()
  167. {
  168. HBRUSH hBrush = m_hBrush;
  169. m_hBrush = NULL;
  170. return hBrush;
  171. }
  172. operator HBRUSH() const { return m_hBrush; }
  173. bool IsNull() const { return (m_hBrush == NULL); }
  174. // Create methods
  175. HBRUSH CreateSolidBrush(COLORREF crColor)
  176. {
  177. ATLASSERT(m_hBrush == NULL);
  178. m_hBrush = ::CreateSolidBrush(crColor);
  179. return m_hBrush;
  180. }
  181. HBRUSH CreateHatchBrush(int nIndex, COLORREF crColor)
  182. {
  183. ATLASSERT(m_hBrush == NULL);
  184. m_hBrush = ::CreateHatchBrush(nIndex, crColor);
  185. return m_hBrush;
  186. }
  187. HBRUSH CreateBrushIndirect(const LOGBRUSH* lpLogBrush)
  188. {
  189. ATLASSERT(m_hBrush == NULL);
  190. m_hBrush = ::CreateBrushIndirect(lpLogBrush);
  191. return m_hBrush;
  192. }
  193. HBRUSH CreatePatternBrush(HBITMAP hBitmap)
  194. {
  195. ATLASSERT(m_hBrush == NULL);
  196. m_hBrush = ::CreatePatternBrush(hBitmap);
  197. return m_hBrush;
  198. }
  199. HBRUSH CreateDIBPatternBrush(HGLOBAL hPackedDIB, UINT nUsage)
  200. {
  201. ATLASSERT(hPackedDIB != NULL);
  202. const void* lpPackedDIB = ::GlobalLock(hPackedDIB);
  203. ATLASSERT(lpPackedDIB != NULL);
  204. m_hBrush = ::CreateDIBPatternBrushPt(lpPackedDIB, nUsage);
  205. ::GlobalUnlock(hPackedDIB);
  206. return m_hBrush;
  207. }
  208. HBRUSH CreateDIBPatternBrush(const void* lpPackedDIB, UINT nUsage)
  209. {
  210. ATLASSERT(m_hBrush == NULL);
  211. m_hBrush = ::CreateDIBPatternBrushPt(lpPackedDIB, nUsage);
  212. return m_hBrush;
  213. }
  214. HBRUSH CreateSysColorBrush(int nIndex)
  215. {
  216. ATLASSERT(m_hBrush == NULL);
  217. m_hBrush = ::GetSysColorBrush(nIndex);
  218. return m_hBrush;
  219. }
  220. BOOL DeleteObject()
  221. {
  222. ATLASSERT(m_hBrush != NULL);
  223. BOOL bRet = ::DeleteObject(m_hBrush);
  224. if(bRet)
  225. m_hBrush = NULL;
  226. return bRet;
  227. }
  228. // Attributes
  229. int GetLogBrush(LOGBRUSH* pLogBrush) const
  230. {
  231. ATLASSERT(m_hBrush != NULL);
  232. return ::GetObject(m_hBrush, sizeof(LOGBRUSH), pLogBrush);
  233. }
  234. bool GetLogBrush(LOGBRUSH& LogBrush) const
  235. {
  236. ATLASSERT(m_hBrush != NULL);
  237. return (::GetObject(m_hBrush, sizeof(LOGBRUSH), &LogBrush) == sizeof(LOGBRUSH));
  238. }
  239. };
  240. /////////////////////////////////////////////////////////////////////////////
  241. // CFont
  242. typedef CFontT<false> CFontHandle;
  243. typedef CFontT<true> CFont;
  244. template <bool t_bManaged>
  245. class CFontT
  246. {
  247. public:
  248. // Data members
  249. HFONT m_hFont;
  250. // Constructor/destructor/operators
  251. CFontT(HFONT hFont = NULL) : m_hFont(hFont)
  252. { }
  253. ~CFontT()
  254. {
  255. if(t_bManaged && m_hFont != NULL)
  256. DeleteObject();
  257. }
  258. CFontT<t_bManaged>& operator=(HFONT hFont)
  259. {
  260. m_hFont = hFont;
  261. return *this;
  262. }
  263. void Attach(HFONT hFont)
  264. {
  265. if(t_bManaged && m_hFont != NULL)
  266. ::DeleteObject(m_hFont);
  267. m_hFont = hFont;
  268. }
  269. HFONT Detach()
  270. {
  271. HFONT hFont = m_hFont;
  272. m_hFont = NULL;
  273. return hFont;
  274. }
  275. operator HFONT() const { return m_hFont; }
  276. bool IsNull() const { return (m_hFont == NULL); }
  277. // Create methods
  278. HFONT CreateFontIndirect(const LOGFONT* lpLogFont)
  279. {
  280. ATLASSERT(m_hFont == NULL);
  281. m_hFont = ::CreateFontIndirect(lpLogFont);
  282. return m_hFont;
  283. }
  284. #if (_WIN32_WINNT >= 0x0500)
  285. HFONT CreateFontIndirectEx(CONST ENUMLOGFONTEXDV* penumlfex)
  286. {
  287. ATLASSERT(m_hFont == NULL);
  288. m_hFont = ::CreateFontIndirectEx(penumlfex);
  289. return m_hFont;
  290. }
  291. #endif //(_WIN32_WINNT >= 0x0500)
  292. HFONT CreateFont(int nHeight, int nWidth, int nEscapement,
  293. int nOrientation, int nWeight, BYTE bItalic, BYTE bUnderline,
  294. BYTE cStrikeOut, BYTE nCharSet, BYTE nOutPrecision,
  295. BYTE nClipPrecision, BYTE nQuality, BYTE nPitchAndFamily,
  296. LPCTSTR lpszFacename)
  297. {
  298. ATLASSERT(m_hFont == NULL);
  299. m_hFont = ::CreateFont(nHeight, nWidth, nEscapement,
  300. nOrientation, nWeight, bItalic, bUnderline, cStrikeOut,
  301. nCharSet, nOutPrecision, nClipPrecision, nQuality,
  302. nPitchAndFamily, lpszFacename);
  303. return m_hFont;
  304. }
  305. HFONT CreatePointFont(int nPointSize, LPCTSTR lpszFaceName, HDC hDC = NULL)
  306. {
  307. LOGFONT logFont;
  308. memset(&logFont, 0, sizeof(LOGFONT));
  309. logFont.lfCharSet = DEFAULT_CHARSET;
  310. logFont.lfHeight = nPointSize;
  311. lstrcpyn(logFont.lfFaceName, lpszFaceName, sizeof(logFont.lfFaceName)/sizeof(TCHAR));
  312. return CreatePointFontIndirect(&logFont, hDC);
  313. }
  314. HFONT CreatePointFontIndirect(const LOGFONT* lpLogFont, HDC hDC = NULL)
  315. {
  316. HDC hDC1 = (hDC != NULL) ? hDC : (::GetDC(NULL));
  317. // convert nPointSize to logical units based on hDC
  318. LOGFONT logFont = *lpLogFont;
  319. POINT pt;
  320. pt.y = ::GetDeviceCaps(hDC1, LOGPIXELSY) * logFont.lfHeight;
  321. pt.y /= 720; // 72 points/inch, 10 decipoints/point
  322. ::DPtoLP(hDC1, &pt, 1);
  323. POINT ptOrg = { 0, 0 };
  324. ::DPtoLP(hDC1, &ptOrg, 1);
  325. logFont.lfHeight = -abs(pt.y - ptOrg.y);
  326. if(hDC == NULL)
  327. ::ReleaseDC(NULL, hDC1);
  328. return CreateFontIndirect(&logFont);
  329. }
  330. BOOL DeleteObject()
  331. {
  332. ATLASSERT(m_hFont != NULL);
  333. BOOL bRet = ::DeleteObject(m_hFont);
  334. if(bRet)
  335. m_hFont = NULL;
  336. return bRet;
  337. }
  338. // Attributes
  339. int GetLogFont(LOGFONT* pLogFont) const
  340. {
  341. ATLASSERT(m_hFont != NULL);
  342. return ::GetObject(m_hFont, sizeof(LOGFONT), pLogFont);
  343. }
  344. bool GetLogFont(LOGFONT& LogFont) const
  345. {
  346. ATLASSERT(m_hFont != NULL);
  347. return (::GetObject(m_hFont, sizeof(LOGFONT), &LogFont) == sizeof(LOGFONT));
  348. }
  349. };
  350. /////////////////////////////////////////////////////////////////////////////
  351. // CBitmap
  352. typedef CBitmapT<false> CBitmapHandle;
  353. typedef CBitmapT<true> CBitmap;
  354. template <bool t_bManaged>
  355. class CBitmapT
  356. {
  357. public:
  358. // Data members
  359. HBITMAP m_hBitmap;
  360. // Constructor/destructor/operators
  361. CBitmapT(HBITMAP hBitmap = NULL) : m_hBitmap(hBitmap)
  362. { }
  363. ~CBitmapT()
  364. {
  365. if(t_bManaged && m_hBitmap != NULL)
  366. DeleteObject();
  367. }
  368. CBitmapT<t_bManaged>& operator=(HBITMAP hBitmap)
  369. {
  370. m_hBitmap = hBitmap;
  371. return *this;
  372. }
  373. void Attach(HBITMAP hBitmap)
  374. {
  375. if(t_bManaged && m_hBitmap != NULL)
  376. ::DeleteObject(m_hBitmap);
  377. m_hBitmap = hBitmap;
  378. }
  379. HBITMAP Detach()
  380. {
  381. HBITMAP hBitmap = m_hBitmap;
  382. m_hBitmap = NULL;
  383. return hBitmap;
  384. }
  385. operator HBITMAP() const { return m_hBitmap; }
  386. bool IsNull() const { return (m_hBitmap == NULL); }
  387. // Create and load methods
  388. HBITMAP LoadBitmap(_U_STRINGorID bitmap)
  389. {
  390. ATLASSERT(m_hBitmap == NULL);
  391. m_hBitmap = ::LoadBitmap(_Module.GetResourceInstance(), bitmap.m_lpstr);
  392. return m_hBitmap;
  393. }
  394. HBITMAP LoadOEMBitmap(UINT nIDBitmap) // for OBM_/OCR_/OIC_
  395. {
  396. ATLASSERT(m_hBitmap == NULL);
  397. m_hBitmap = ::LoadBitmap(NULL, MAKEINTRESOURCE(nIDBitmap));
  398. return m_hBitmap;
  399. }
  400. HBITMAP LoadMappedBitmap(UINT nIDBitmap, UINT nFlags = 0, LPCOLORMAP lpColorMap = NULL, int nMapSize = 0)
  401. {
  402. ATLASSERT(m_hBitmap == NULL);
  403. m_hBitmap = ::CreateMappedBitmap(_Module.GetResourceInstance(), nIDBitmap, (WORD)nFlags, lpColorMap, nMapSize);
  404. return m_hBitmap;
  405. }
  406. HBITMAP CreateBitmap(int nWidth, int nHeight, UINT nPlanes, UINT nBitcount, const void* lpBits)
  407. {
  408. ATLASSERT(m_hBitmap == NULL);
  409. m_hBitmap = ::CreateBitmap(nWidth, nHeight, nPlanes, nBitcount, lpBits);
  410. return m_hBitmap;
  411. }
  412. HBITMAP CreateBitmapIndirect(LPBITMAP lpBitmap)
  413. {
  414. ATLASSERT(m_hBitmap == NULL);
  415. m_hBitmap = ::CreateBitmapIndirect(lpBitmap);
  416. return m_hBitmap;
  417. }
  418. HBITMAP CreateCompatibleBitmap(HDC hDC, int nWidth, int nHeight)
  419. {
  420. ATLASSERT(m_hBitmap == NULL);
  421. m_hBitmap = ::CreateCompatibleBitmap(hDC, nWidth, nHeight);
  422. return m_hBitmap;
  423. }
  424. HBITMAP CreateDiscardableBitmap(HDC hDC, int nWidth, int nHeight)
  425. {
  426. ATLASSERT(m_hBitmap == NULL);
  427. m_hBitmap = ::CreateDiscardableBitmap(hDC, nWidth, nHeight);
  428. return m_hBitmap;
  429. }
  430. BOOL DeleteObject()
  431. {
  432. ATLASSERT(m_hBitmap != NULL);
  433. BOOL bRet = ::DeleteObject(m_hBitmap);
  434. if(bRet)
  435. m_hBitmap = NULL;
  436. return bRet;
  437. }
  438. // Attributes
  439. int GetBitmap(BITMAP* pBitMap) const
  440. {
  441. ATLASSERT(m_hBitmap != NULL);
  442. return ::GetObject(m_hBitmap, sizeof(BITMAP), pBitMap);
  443. }
  444. bool GetBitmap(BITMAP& bm) const
  445. {
  446. ATLASSERT(m_hBitmap != NULL);
  447. return (::GetObject(m_hBitmap, sizeof(BITMAP), &bm) == sizeof(BITMAP));
  448. }
  449. bool GetSize(SIZE& size) const
  450. {
  451. ATLASSERT(m_hBitmap != NULL);
  452. BITMAP bm;
  453. if(!GetBitmap(&bm))
  454. return false;
  455. size.cx = bm.bmWidth;
  456. size.cy = bm.bmHeight;
  457. return true;
  458. }
  459. DWORD GetBitmapBits(DWORD dwCount, LPVOID lpBits) const
  460. {
  461. ATLASSERT(m_hBitmap != NULL);
  462. return ::GetBitmapBits(m_hBitmap, dwCount, lpBits);
  463. }
  464. DWORD SetBitmapBits(DWORD dwCount, const void* lpBits)
  465. {
  466. ATLASSERT(m_hBitmap != NULL);
  467. return ::SetBitmapBits(m_hBitmap, dwCount, lpBits);
  468. }
  469. BOOL GetBitmapDimension(LPSIZE lpSize) const
  470. {
  471. ATLASSERT(m_hBitmap != NULL);
  472. return ::GetBitmapDimensionEx(m_hBitmap, lpSize);
  473. }
  474. BOOL SetBitmapDimension(int nWidth, int nHeight, LPSIZE lpSize = NULL)
  475. {
  476. ATLASSERT(m_hBitmap != NULL);
  477. return ::SetBitmapDimensionEx(m_hBitmap, nWidth, nHeight, lpSize);
  478. }
  479. // DIB support
  480. HBITMAP CreateDIBitmap(HDC hDC, CONST BITMAPINFOHEADER* lpbmih, DWORD dwInit, CONST VOID* lpbInit, CONST BITMAPINFO* lpbmi, UINT uColorUse)
  481. {
  482. ATLASSERT(m_hBitmap == NULL);
  483. m_hBitmap = ::CreateDIBitmap(hDC, lpbmih, dwInit, lpbInit, lpbmi, uColorUse);
  484. return m_hBitmap;
  485. }
  486. HBITMAP CreateDIBSection(HDC hDC, CONST BITMAPINFO* lpbmi, UINT uColorUse, VOID** ppvBits, HANDLE hSection, DWORD dwOffset)
  487. {
  488. ATLASSERT(m_hBitmap == NULL);
  489. m_hBitmap = ::CreateDIBSection(hDC, lpbmi, uColorUse, ppvBits, hSection, dwOffset);
  490. return m_hBitmap;
  491. }
  492. int GetDIBits(HDC hDC, UINT uStartScan, UINT cScanLines, LPVOID lpvBits, LPBITMAPINFO lpbmi, UINT uColorUse) const
  493. {
  494. ATLASSERT(m_hBitmap != NULL);
  495. return ::GetDIBits(hDC, m_hBitmap, uStartScan, cScanLines, lpvBits, lpbmi, uColorUse);
  496. }
  497. int SetDIBits(HDC hDC, UINT uStartScan, UINT cScanLines, CONST VOID* lpvBits, CONST BITMAPINFO* lpbmi, UINT uColorUse)
  498. {
  499. ATLASSERT(m_hBitmap != NULL);
  500. return ::SetDIBits(hDC, m_hBitmap, uStartScan, cScanLines, lpvBits, lpbmi, uColorUse);
  501. }
  502. };
  503. /////////////////////////////////////////////////////////////////////////////
  504. // CPalette
  505. typedef CPaletteT<false> CPaletteHandle;
  506. typedef CPaletteT<true> CPalette;
  507. template <bool t_bManaged>
  508. class CPaletteT
  509. {
  510. public:
  511. // Data members
  512. HPALETTE m_hPalette;
  513. // Constructor/destructor/operators
  514. CPaletteT(HPALETTE hPalette = NULL) : m_hPalette(hPalette)
  515. { }
  516. ~CPaletteT()
  517. {
  518. if(t_bManaged && m_hPalette != NULL)
  519. DeleteObject();
  520. }
  521. CPaletteT<t_bManaged>& operator=(HPALETTE hPalette)
  522. {
  523. m_hPalette = hPalette;
  524. return *this;
  525. }
  526. void Attach(HPALETTE hPalette)
  527. {
  528. if(t_bManaged && m_hPalette != NULL)
  529. ::DeleteObject(m_hPalette);
  530. m_hPalette = hPalette;
  531. }
  532. HPALETTE Detach()
  533. {
  534. HPALETTE hPalette = m_hPalette;
  535. m_hPalette = NULL;
  536. return hPalette;
  537. }
  538. operator HPALETTE() const { return m_hPalette; }
  539. bool IsNull() const { return (m_hPalette == NULL); }
  540. // Create methods
  541. HPALETTE CreatePalette(LPLOGPALETTE lpLogPalette)
  542. {
  543. ATLASSERT(m_hPalette == NULL);
  544. m_hPalette = ::CreatePalette(lpLogPalette);
  545. return m_hPalette;
  546. }
  547. HPALETTE CreateHalftonePalette(HDC hDC)
  548. {
  549. ATLASSERT(m_hPalette == NULL);
  550. ATLASSERT(hDC != NULL);
  551. m_hPalette = ::CreateHalftonePalette(hDC);
  552. return m_hPalette;
  553. }
  554. BOOL DeleteObject()
  555. {
  556. ATLASSERT(m_hPalette != NULL);
  557. BOOL bRet = ::DeleteObject(m_hPalette);
  558. if(bRet)
  559. m_hPalette = NULL;
  560. return bRet;
  561. }
  562. // Attributes
  563. int GetEntryCount() const
  564. {
  565. ATLASSERT(m_hPalette != NULL);
  566. WORD nEntries;
  567. ::GetObject(m_hPalette, sizeof(WORD), &nEntries);
  568. return (int)nEntries;
  569. }
  570. UINT GetPaletteEntries(UINT nStartIndex, UINT nNumEntries, LPPALETTEENTRY lpPaletteColors) const
  571. {
  572. ATLASSERT(m_hPalette != NULL);
  573. return ::GetPaletteEntries(m_hPalette, nStartIndex, nNumEntries, lpPaletteColors);
  574. }
  575. UINT SetPaletteEntries(UINT nStartIndex, UINT nNumEntries, LPPALETTEENTRY lpPaletteColors)
  576. {
  577. ATLASSERT(m_hPalette != NULL);
  578. return ::SetPaletteEntries(m_hPalette, nStartIndex, nNumEntries, lpPaletteColors);
  579. }
  580. // Operations
  581. void AnimatePalette(UINT nStartIndex, UINT nNumEntries, LPPALETTEENTRY lpPaletteColors)
  582. {
  583. ATLASSERT(m_hPalette != NULL);
  584. ::AnimatePalette(m_hPalette, nStartIndex, nNumEntries, lpPaletteColors);
  585. }
  586. BOOL ResizePalette(UINT nNumEntries)
  587. {
  588. ATLASSERT(m_hPalette != NULL);
  589. return ::ResizePalette(m_hPalette, nNumEntries);
  590. }
  591. UINT GetNearestPaletteIndex(COLORREF crColor) const
  592. {
  593. ATLASSERT(m_hPalette != NULL);
  594. return ::GetNearestPaletteIndex(m_hPalette, crColor);
  595. }
  596. };
  597. /////////////////////////////////////////////////////////////////////////////
  598. // CRgn
  599. typedef CRgnT<false> CRgnHandle;
  600. typedef CRgnT<true> CRgn;
  601. template <bool t_bManaged>
  602. class CRgnT
  603. {
  604. public:
  605. // Data members
  606. HRGN m_hRgn;
  607. // Constructor/destructor/operators
  608. CRgnT(HRGN hRgn = NULL) : m_hRgn(hRgn)
  609. { }
  610. ~CRgnT()
  611. {
  612. if(t_bManaged && m_hRgn != NULL)
  613. DeleteObject();
  614. }
  615. CRgnT<t_bManaged>& operator=(HRGN hRgn)
  616. {
  617. m_hRgn = hRgn;
  618. return *this;
  619. }
  620. void Attach(HRGN hRgn)
  621. {
  622. if(t_bManaged && m_hRgn != NULL)
  623. ::DeleteObject(m_hRgn);
  624. m_hRgn = hRgn;
  625. }
  626. HRGN Detach()
  627. {
  628. HRGN hRgn = m_hRgn;
  629. m_hRgn = NULL;
  630. return hRgn;
  631. }
  632. operator HRGN() const { return m_hRgn; }
  633. bool IsNull() const { return (m_hRgn == NULL); }
  634. // Create methods
  635. HRGN CreateRectRgn(int x1, int y1, int x2, int y2)
  636. {
  637. ATLASSERT(m_hRgn == NULL);
  638. m_hRgn = ::CreateRectRgn(x1, y1, x2, y2);
  639. return m_hRgn;
  640. }
  641. HRGN CreateRectRgnIndirect(LPCRECT lpRect)
  642. {
  643. ATLASSERT(m_hRgn == NULL);
  644. m_hRgn = ::CreateRectRgnIndirect(lpRect);
  645. return m_hRgn;
  646. }
  647. HRGN CreateEllipticRgn(int x1, int y1, int x2, int y2)
  648. {
  649. ATLASSERT(m_hRgn == NULL);
  650. m_hRgn = ::CreateEllipticRgn(x1, y1, x2, y2);
  651. return m_hRgn;
  652. }
  653. HRGN CreateEllipticRgnIndirect(LPCRECT lpRect)
  654. {
  655. ATLASSERT(m_hRgn == NULL);
  656. m_hRgn = ::CreateEllipticRgnIndirect(lpRect);
  657. return m_hRgn;
  658. }
  659. HRGN CreatePolygonRgn(LPPOINT lpPoints, int nCount, int nMode)
  660. {
  661. ATLASSERT(m_hRgn == NULL);
  662. m_hRgn = ::CreatePolygonRgn(lpPoints, nCount, nMode);
  663. return m_hRgn;
  664. }
  665. HRGN CreatePolyPolygonRgn(LPPOINT lpPoints, LPINT lpPolyCounts, int nCount, int nPolyFillMode)
  666. {
  667. ATLASSERT(m_hRgn == NULL);
  668. m_hRgn = ::CreatePolyPolygonRgn(lpPoints, lpPolyCounts, nCount, nPolyFillMode);
  669. return m_hRgn;
  670. }
  671. HRGN CreateRoundRectRgn(int x1, int y1, int x2, int y2, int x3, int y3)
  672. {
  673. ATLASSERT(m_hRgn == NULL);
  674. m_hRgn = ::CreateRoundRectRgn(x1, y1, x2, y2, x3, y3);
  675. return m_hRgn;
  676. }
  677. HRGN CreateFromPath(HDC hDC)
  678. {
  679. ATLASSERT(m_hRgn == NULL);
  680. ATLASSERT(hDC != NULL);
  681. m_hRgn = ::PathToRegion(hDC);
  682. return m_hRgn;
  683. }
  684. HRGN CreateFromData(const XFORM* lpXForm, int nCount, const RGNDATA* pRgnData)
  685. {
  686. ATLASSERT(m_hRgn == NULL);
  687. m_hRgn = ::ExtCreateRegion(lpXForm, nCount, pRgnData);
  688. return m_hRgn;
  689. }
  690. BOOL DeleteObject()
  691. {
  692. ATLASSERT(m_hRgn != NULL);
  693. BOOL bRet = ::DeleteObject(m_hRgn);
  694. if(bRet)
  695. m_hRgn = NULL;
  696. return bRet;
  697. }
  698. // Operations
  699. void SetRectRgn(int x1, int y1, int x2, int y2)
  700. {
  701. ATLASSERT(m_hRgn != NULL);
  702. ::SetRectRgn(m_hRgn, x1, y1, x2, y2);
  703. }
  704. void SetRectRgn(LPCRECT lpRect)
  705. {
  706. ATLASSERT(m_hRgn != NULL);
  707. ::SetRectRgn(m_hRgn, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
  708. }
  709. int CombineRgn(HRGN hRgnSrc1, HRGN hRgnSrc2, int nCombineMode)
  710. {
  711. ATLASSERT(m_hRgn != NULL);
  712. return ::CombineRgn(m_hRgn, hRgnSrc1, hRgnSrc2, nCombineMode);
  713. }
  714. int CombineRgn(HRGN hRgnSrc, int nCombineMode)
  715. {
  716. ATLASSERT(m_hRgn != NULL);
  717. return ::CombineRgn(m_hRgn, m_hRgn, hRgnSrc, nCombineMode);
  718. }
  719. int CopyRgn(HRGN hRgnSrc)
  720. {
  721. ATLASSERT(m_hRgn != NULL);
  722. return ::CombineRgn(m_hRgn, hRgnSrc, NULL, RGN_COPY);
  723. }
  724. BOOL EqualRgn(HRGN hRgn) const
  725. {
  726. ATLASSERT(m_hRgn != NULL);
  727. return ::EqualRgn(m_hRgn, hRgn);
  728. }
  729. int OffsetRgn(int x, int y)
  730. {
  731. ATLASSERT(m_hRgn != NULL);
  732. return ::OffsetRgn(m_hRgn, x, y);
  733. }
  734. int OffsetRgn(POINT point)
  735. {
  736. ATLASSERT(m_hRgn != NULL);
  737. return ::OffsetRgn(m_hRgn, point.x, point.y);
  738. }
  739. int GetRgnBox(LPRECT lpRect) const
  740. {
  741. ATLASSERT(m_hRgn != NULL);
  742. return ::GetRgnBox(m_hRgn, lpRect);
  743. }
  744. BOOL PtInRegion(int x, int y) const
  745. {
  746. ATLASSERT(m_hRgn != NULL);
  747. return ::PtInRegion(m_hRgn, x, y);
  748. }
  749. BOOL PtInRegion(POINT point) const
  750. {
  751. ATLASSERT(m_hRgn != NULL);
  752. return ::PtInRegion(m_hRgn, point.x, point.y);
  753. }
  754. BOOL RectInRegion(LPCRECT lpRect) const
  755. {
  756. ATLASSERT(m_hRgn != NULL);
  757. return ::RectInRegion(m_hRgn, lpRect);
  758. }
  759. int GetRegionData(LPRGNDATA lpRgnData, int nDataSize) const
  760. {
  761. ATLASSERT(m_hRgn != NULL);
  762. return (int)::GetRegionData(m_hRgn, nDataSize, lpRgnData);
  763. }
  764. };
  765. /////////////////////////////////////////////////////////////////////////////
  766. // CDC - The device context class
  767. typedef CDCT<false> CDCHandle;
  768. typedef CDCT<true> CDC;
  769. template <bool t_bManaged>
  770. class CDCT
  771. {
  772. public:
  773. // Data members
  774. HDC m_hDC;
  775. // Constructor/destructor/operators
  776. CDCT(HDC hDC = NULL) : m_hDC(hDC)
  777. {
  778. }
  779. ~CDCT()
  780. {
  781. if(t_bManaged && m_hDC != NULL)
  782. ::DeleteDC(Detach());
  783. }
  784. CDCT<t_bManaged>& operator=(HDC hDC)
  785. {
  786. m_hDC = hDC;
  787. return *this;
  788. }
  789. void Attach(HDC hDC)
  790. {
  791. if(t_bManaged && m_hDC != NULL)
  792. ::DeleteDC(m_hDC);
  793. m_hDC = hDC;
  794. }
  795. HDC Detach()
  796. {
  797. HDC hDC = m_hDC;
  798. m_hDC = NULL;
  799. return hDC;
  800. }
  801. operator HDC() const { return m_hDC; }
  802. bool IsNull() const { return (m_hDC == NULL); }
  803. // Operations
  804. HWND WindowFromDC() const
  805. {
  806. ATLASSERT(m_hDC != NULL);
  807. return ::WindowFromDC(m_hDC);
  808. }
  809. CPenHandle GetCurrentPen() const
  810. {
  811. ATLASSERT(m_hDC != NULL);
  812. return CPenHandle((HPEN)::GetCurrentObject(m_hDC, OBJ_PEN));
  813. }
  814. CBrushHandle GetCurrentBrush() const
  815. {
  816. ATLASSERT(m_hDC != NULL);
  817. return CBrushHandle((HBRUSH)::GetCurrentObject(m_hDC, OBJ_BRUSH));
  818. }
  819. CPaletteHandle GetCurrentPalette() const
  820. {
  821. ATLASSERT(m_hDC != NULL);
  822. return CPaletteHandle((HPALETTE)::GetCurrentObject(m_hDC, OBJ_PAL));
  823. }
  824. CFontHandle GetCurrentFont() const
  825. {
  826. ATLASSERT(m_hDC != NULL);
  827. return CFontHandle((HFONT)::GetCurrentObject(m_hDC, OBJ_FONT));
  828. }
  829. CBitmapHandle GetCurrentBitmap() const
  830. {
  831. ATLASSERT(m_hDC != NULL);
  832. return CBitmapHandle((HBITMAP)::GetCurrentObject(m_hDC, OBJ_BITMAP));
  833. }
  834. HDC CreateDC(LPCTSTR lpszDriverName, LPCTSTR lpszDeviceName, LPCTSTR lpszOutput, const DEVMODE* lpInitData)
  835. {
  836. ATLASSERT(m_hDC == NULL);
  837. m_hDC = ::CreateDC(lpszDriverName, lpszDeviceName, lpszOutput, lpInitData);
  838. return m_hDC;
  839. }
  840. HDC CreateCompatibleDC(HDC hDC = NULL)
  841. {
  842. ATLASSERT(m_hDC == NULL);
  843. m_hDC = ::CreateCompatibleDC(hDC);
  844. return m_hDC;
  845. }
  846. BOOL DeleteDC()
  847. {
  848. if(m_hDC == NULL)
  849. return FALSE;
  850. return ::DeleteDC(Detach());
  851. }
  852. // Device-Context Functions
  853. int SaveDC()
  854. {
  855. ATLASSERT(m_hDC != NULL);
  856. return ::SaveDC(m_hDC);
  857. }
  858. BOOL RestoreDC(int nSavedDC)
  859. {
  860. ATLASSERT(m_hDC != NULL);
  861. return ::RestoreDC(m_hDC, nSavedDC);
  862. }
  863. int GetDeviceCaps(int nIndex) const
  864. {
  865. ATLASSERT(m_hDC != NULL);
  866. return ::GetDeviceCaps(m_hDC, nIndex);
  867. }
  868. UINT SetBoundsRect(LPCRECT lpRectBounds, UINT flags)
  869. {
  870. ATLASSERT(m_hDC != NULL);
  871. return ::SetBoundsRect(m_hDC, lpRectBounds, flags);
  872. }
  873. UINT GetBoundsRect(LPRECT lpRectBounds, UINT flags) const
  874. {
  875. ATLASSERT(m_hDC != NULL);
  876. return ::GetBoundsRect(m_hDC, lpRectBounds, flags);
  877. }
  878. BOOL ResetDC(const DEVMODE* lpDevMode)
  879. {
  880. ATLASSERT(m_hDC != NULL);
  881. return ::ResetDC(m_hDC, lpDevMode) != NULL;
  882. }
  883. // Drawing-Tool Functions
  884. BOOL GetBrushOrg(LPPOINT lpPoint) const
  885. {
  886. ATLASSERT(m_hDC != NULL);
  887. return ::GetBrushOrgEx(m_hDC, lpPoint);
  888. }
  889. BOOL SetBrushOrg(int x, int y, LPPOINT lpPoint = NULL)
  890. {
  891. ATLASSERT(m_hDC != NULL);
  892. return ::SetBrushOrgEx(m_hDC, x, y, lpPoint);
  893. }
  894. BOOL SetBrushOrg(POINT point, LPPOINT lpPointRet = NULL)
  895. {
  896. ATLASSERT(m_hDC != NULL);
  897. return ::SetBrushOrgEx(m_hDC, point.x, point.y, lpPointRet);
  898. }
  899. int EnumObjects(int nObjectType, int (CALLBACK* lpfn)(LPVOID, LPARAM), LPARAM lpData)
  900. {
  901. ATLASSERT(m_hDC != NULL);
  902. #ifdef STRICT
  903. return ::EnumObjects(m_hDC, nObjectType, (GOBJENUMPROC)lpfn, lpData);
  904. #else
  905. return ::EnumObjects(m_hDC, nObjectType, (GOBJENUMPROC)lpfn, (LPVOID)lpData);
  906. #endif
  907. }
  908. // Type-safe selection helpers
  909. HPEN SelectPen(HPEN hPen)
  910. {
  911. ATLASSERT(m_hDC != NULL);
  912. ATLASSERT(hPen == NULL || ::GetObjectType(hPen) == OBJ_PEN || ::GetObjectType(hPen) == OBJ_EXTPEN);
  913. return (HPEN)::SelectObject(m_hDC, hPen);
  914. }
  915. HBRUSH SelectBrush(HBRUSH hBrush)
  916. {
  917. ATLASSERT(m_hDC != NULL);
  918. ATLASSERT(hBrush == NULL || ::GetObjectType(hBrush) == OBJ_BRUSH);
  919. return (HBRUSH)::SelectObject(m_hDC, hBrush);
  920. }
  921. HFONT SelectFont(HFONT hFont)
  922. {
  923. ATLASSERT(m_hDC != NULL);
  924. ATLASSERT(hFont == NULL || ::GetObjectType(hFont) == OBJ_FONT);
  925. return (HFONT)::SelectObject(m_hDC, hFont);
  926. }
  927. HBITMAP SelectBitmap(HBITMAP hBitmap)
  928. {
  929. ATLASSERT(m_hDC != NULL);
  930. ATLASSERT(hBitmap == NULL || ::GetObjectType(hBitmap) == OBJ_BITMAP);
  931. return (HBITMAP)::SelectObject(m_hDC, hBitmap);
  932. }
  933. int SelectRgn(HRGN hRgn) // special return for regions
  934. {
  935. ATLASSERT(m_hDC != NULL);
  936. ATLASSERT(hRgn == NULL || ::GetObjectType(hRgn) == OBJ_REGION);
  937. return PtrToInt(::SelectObject(m_hDC, hRgn));
  938. }
  939. // Type-safe selection helpers for stock objects
  940. HPEN SelectStockPen(int nPen)
  941. {
  942. ATLASSERT(m_hDC != NULL);
  943. #if (_WIN32_WINNT >= 0x0500)
  944. ATLASSERT(nPen == WHITE_PEN || nPen == BLACK_PEN || nPen == NULL_PEN || nPen == DC_PEN);
  945. #else
  946. ATLASSERT(nPen == WHITE_PEN || nPen == BLACK_PEN || nPen == NULL_PEN);
  947. #endif //!(_WIN32_WINNT >= 0x0500)
  948. return SelectPen((HPEN)::GetStockObject(nPen));
  949. }
  950. HBRUSH SelectStockBrush(int nBrush)
  951. {
  952. #if (_WIN32_WINNT >= 0x0500)
  953. ATLASSERT((nBrush >= WHITE_BRUSH && nBrush <= HOLLOW_BRUSH) || nBrush == DC_BRUSH);
  954. #else
  955. ATLASSERT(nBrush >= WHITE_BRUSH && nBrush <= HOLLOW_BRUSH);
  956. #endif //!(_WIN32_WINNT >= 0x0500)
  957. return SelectBrush((HBRUSH)::GetStockObject(nBrush));
  958. }
  959. HFONT SelectStockFont(int nFont)
  960. {
  961. ATLASSERT((nFont >= OEM_FIXED_FONT && nFont <= SYSTEM_FIXED_FONT) || nFont == DEFAULT_GUI_FONT);
  962. return SelectFont((HFONT)::GetStockObject(nFont));
  963. }
  964. HPALETTE SelectStockPalette(int nPalette, BOOL bForceBackground)
  965. {
  966. ATLASSERT(nPalette == DEFAULT_PALETTE); // the only one supported
  967. return SelectPalette((HPALETTE)::GetStockObject(nPalette), bForceBackground);
  968. }
  969. // Color and Color Palette Functions
  970. COLORREF GetNearestColor(COLORREF crColor) const
  971. {
  972. ATLASSERT(m_hDC != NULL);
  973. return ::GetNearestColor(m_hDC, crColor);
  974. }
  975. HPALETTE SelectPalette(HPALETTE hPalette, BOOL bForceBackground)
  976. {
  977. ATLASSERT(m_hDC != NULL);
  978. return ::SelectPalette(m_hDC, hPalette, bForceBackground);
  979. }
  980. UINT RealizePalette()
  981. {
  982. ATLASSERT(m_hDC != NULL);
  983. return ::RealizePalette(m_hDC);
  984. }
  985. void UpdateColors()
  986. {
  987. ATLASSERT(m_hDC != NULL);
  988. ::UpdateColors(m_hDC);
  989. }
  990. // Drawing-Attribute Functions
  991. COLORREF GetBkColor() const
  992. {
  993. ATLASSERT(m_hDC != NULL);
  994. return ::GetBkColor(m_hDC);
  995. }
  996. int GetBkMode() const
  997. {
  998. ATLASSERT(m_hDC != NULL);
  999. return ::GetBkMode(m_hDC);
  1000. }
  1001. int GetPolyFillMode() const
  1002. {
  1003. ATLASSERT(m_hDC != NULL);
  1004. return ::GetPolyFillMode(m_hDC);
  1005. }
  1006. int GetROP2() const
  1007. {
  1008. ATLASSERT(m_hDC != NULL);
  1009. return ::GetROP2(m_hDC);
  1010. }
  1011. int GetStretchBltMode() const
  1012. {
  1013. ATLASSERT(m_hDC != NULL);
  1014. return ::GetStretchBltMode(m_hDC);
  1015. }
  1016. COLORREF GetTextColor() const
  1017. {
  1018. ATLASSERT(m_hDC != NULL);
  1019. return ::GetTextColor(m_hDC);
  1020. }
  1021. COLORREF SetBkColor(COLORREF crColor)
  1022. {
  1023. ATLASSERT(m_hDC != NULL);
  1024. return ::SetBkColor(m_hDC, crColor);
  1025. }
  1026. int SetBkMode(int nBkMode)
  1027. {
  1028. ATLASSERT(m_hDC != NULL);
  1029. return ::SetBkMode(m_hDC, nBkMode);
  1030. }
  1031. int SetPolyFillMode(int nPolyFillMode)
  1032. {
  1033. ATLASSERT(m_hDC != NULL);
  1034. return ::SetPolyFillMode(m_hDC, nPolyFillMode);
  1035. }
  1036. int SetROP2(int nDrawMode)
  1037. {
  1038. ATLASSERT(m_hDC != NULL);
  1039. return ::SetROP2(m_hDC, nDrawMode);
  1040. }
  1041. int SetStretchBltMode(int nStretchMode)
  1042. {
  1043. ATLASSERT(m_hDC != NULL);
  1044. return ::SetStretchBltMode(m_hDC, nStretchMode);
  1045. }
  1046. COLORREF SetTextColor(COLORREF crColor)
  1047. {
  1048. ATLASSERT(m_hDC != NULL);
  1049. return ::SetTextColor(m_hDC, crColor);
  1050. }
  1051. BOOL GetColorAdjustment(LPCOLORADJUSTMENT lpColorAdjust) const
  1052. {
  1053. ATLASSERT(m_hDC != NULL);
  1054. return ::GetColorAdjustment(m_hDC, lpColorAdjust);
  1055. }
  1056. BOOL SetColorAdjustment(const COLORADJUSTMENT* lpColorAdjust)
  1057. {
  1058. ATLASSERT(m_hDC != NULL);
  1059. return ::SetColorAdjustment(m_hDC, lpColorAdjust);
  1060. }
  1061. // Mapping Functions
  1062. int GetMapMode() const
  1063. {
  1064. ATLASSERT(m_hDC != NULL);
  1065. return ::GetMapMode(m_hDC);
  1066. }
  1067. BOOL GetViewportOrg(LPPOINT lpPoint) const
  1068. {
  1069. ATLASSERT(m_hDC != NULL);
  1070. return ::GetViewportOrgEx(m_hDC, lpPoint);
  1071. }
  1072. int SetMapMode(int nMapMode)
  1073. {
  1074. ATLASSERT(m_hDC != NULL);
  1075. return ::SetMapMode(m_hDC, nMapMode);
  1076. }
  1077. // Viewport Origin
  1078. BOOL SetViewportOrg(int x, int y, LPPOINT lpPoint = NULL)
  1079. {
  1080. ATLASSERT(m_hDC != NULL);
  1081. return ::SetViewportOrgEx(m_hDC, x, y, lpPoint);
  1082. }
  1083. BOOL SetViewportOrg(POINT point, LPPOINT lpPointRet = NULL)
  1084. {
  1085. ATLASSERT(m_hDC != NULL);
  1086. return SetViewportOrg(point.x, point.y, lpPointRet);
  1087. }
  1088. BOOL OffsetViewportOrg(int nWidth, int nHeight, LPPOINT lpPoint = NULL)
  1089. {
  1090. ATLASSERT(m_hDC != NULL);
  1091. return ::OffsetViewportOrgEx(m_hDC, nWidth, nHeight, lpPoint);
  1092. }
  1093. // Viewport Extent
  1094. BOOL GetViewportExt(LPSIZE lpSize) const
  1095. {
  1096. ATLASSERT(m_hDC != NULL);
  1097. return ::GetViewportExtEx(m_hDC, lpSize);
  1098. }
  1099. BOOL SetViewportExt(int x, int y, LPSIZE lpSize = NULL)
  1100. {
  1101. ATLASSERT(m_hDC != NULL);
  1102. return ::SetViewportExtEx(m_hDC, x, y, lpSize);
  1103. }
  1104. BOOL SetViewportExt(SIZE size, LPSIZE lpSizeRet = NULL)
  1105. {
  1106. ATLASSERT(m_hDC != NULL);
  1107. return SetViewportExt(size.cx, size.cy, lpSizeRet);
  1108. }
  1109. BOOL ScaleViewportExt(int xNum, int xDenom, int yNum, int yDenom, LPSIZE lpSize = NULL)
  1110. {
  1111. ATLASSERT(m_hDC != NULL);
  1112. return ::ScaleViewportExtEx(m_hDC, xNum, xDenom, yNum, yDenom, lpSize);
  1113. }
  1114. // Window Origin
  1115. BOOL GetWindowOrg(LPPOINT lpPoint) const
  1116. {
  1117. ATLASSERT(m_hDC != NULL);
  1118. return ::GetWindowOrgEx(m_hDC, lpPoint);
  1119. }
  1120. BOOL SetWindowOrg(int x, int y, LPPOINT lpPoint = NULL)
  1121. {
  1122. ATLASSERT(m_hDC != NULL);
  1123. return ::SetWindowOrgEx(m_hDC, x, y, lpPoint);
  1124. }
  1125. BOOL SetWindowOrg(POINT point, LPPOINT lpPointRet = NULL)
  1126. {
  1127. ATLASSERT(m_hDC != NULL);
  1128. return SetWindowOrg(point.x, point.y, lpPointRet);
  1129. }
  1130. BOOL OffsetWindowOrg(int nWidth, int nHeight, LPPOINT lpPoint = NULL)
  1131. {
  1132. ATLASSERT(m_hDC != NULL);
  1133. return ::OffsetWindowOrgEx(m_hDC, nWidth, nHeight, lpPoint);
  1134. }
  1135. // Window extent
  1136. BOOL GetWindowExt(LPSIZE lpSize) const
  1137. {
  1138. ATLASSERT(m_hDC != NULL);
  1139. return ::GetWindowExtEx(m_hDC, lpSize);
  1140. }
  1141. BOOL SetWindowExt(int x, int y, LPSIZE lpSize = NULL)
  1142. {
  1143. ATLASSERT(m_hDC != NULL);
  1144. return ::SetWindowExtEx(m_hDC, x, y, lpSize);
  1145. }
  1146. BOOL SetWindowExt(SIZE size, LPSIZE lpSizeRet)
  1147. {
  1148. ATLASSERT(m_hDC != NULL);
  1149. return SetWindowExt(size.cx, size.cy, lpSizeRet);
  1150. }
  1151. BOOL ScaleWindowExt(int xNum, int xDenom, int yNum, int yDenom, LPSIZE lpSize = NULL)
  1152. {
  1153. ATLASSERT(m_hDC != NULL);
  1154. return ::ScaleWindowExtEx(m_hDC, xNum, xDenom, yNum, yDenom, lpSize);
  1155. }
  1156. // Coordinate Functions
  1157. BOOL DPtoLP(LPPOINT lpPoints, int nCount = 1) const
  1158. {
  1159. ATLASSERT(m_hDC != NULL);
  1160. return ::DPtoLP(m_hDC, lpPoints, nCount);
  1161. }
  1162. BOOL DPtoLP(LPRECT lpRect) const
  1163. {
  1164. ATLASSERT(m_hDC != NULL);
  1165. return ::DPtoLP(m_hDC, (LPPOINT)lpRect, 2);
  1166. }
  1167. BOOL DPtoLP(LPSIZE lpSize) const
  1168. {
  1169. SIZE sizeWinExt;
  1170. if(!GetWindowExt(&sizeWinExt))
  1171. return FALSE;
  1172. SIZE sizeVpExt;
  1173. if(!GetViewportExt(&sizeVpExt))
  1174. return FALSE;
  1175. lpSize->cx = MulDiv(lpSize->cx, abs(sizeWinExt.cx), abs(sizeVpExt.cx));
  1176. lpSize->cy = MulDiv(lpSize->cy, abs(sizeWinExt.cy), abs(sizeVpExt.cy));
  1177. return TRUE;
  1178. }
  1179. BOOL LPtoDP(LPPOINT lpPoints, int nCount = 1) const
  1180. {
  1181. ATLASSERT(m_hDC != NULL);
  1182. return ::LPtoDP(m_hDC, lpPoints, nCount);
  1183. }
  1184. BOOL LPtoDP(LPRECT lpRect) const
  1185. {
  1186. ATLASSERT(m_hDC != NULL);
  1187. return ::LPtoDP(m_hDC, (LPPOINT)lpRect, 2);
  1188. }
  1189. BOOL LPtoDP(LPSIZE lpSize) const
  1190. {
  1191. SIZE sizeWinExt;
  1192. if(!GetWindowExt(&sizeWinExt))
  1193. return FALSE;
  1194. SIZE sizeVpExt;
  1195. if(!GetViewportExt(&sizeVpExt))
  1196. return FALSE;
  1197. lpSize->cx = ::MulDiv(lpSize->cx, abs(sizeVpExt.cx), abs(sizeWinExt.cx));
  1198. lpSize->cy = ::MulDiv(lpSize->cy, abs(sizeVpExt.cy), abs(sizeWinExt.cy));
  1199. return TRUE;
  1200. }
  1201. // Special Coordinate Functions (useful for dealing with metafiles and OLE)
  1202. #define HIMETRIC_INCH 2540 // HIMETRIC units per inch
  1203. void DPtoHIMETRIC(LPSIZE lpSize) const
  1204. {
  1205. ATLASSERT(m_hDC != NULL);
  1206. int nMapMode;
  1207. if((nMapMode = GetMapMode()) < MM_ISOTROPIC && nMapMode != MM_TEXT)
  1208. {
  1209. // when using a constrained map mode, map against physical inch
  1210. ((CDCHandle*)this)->SetMapMode(MM_HIMETRIC);
  1211. DPtoLP(lpSize);
  1212. ((CDCHandle*)this)->SetMapMode(nMapMode);
  1213. }
  1214. else
  1215. {
  1216. // map against logical inch for non-constrained mapping modes
  1217. int cxPerInch = GetDeviceCaps(LOGPIXELSX);
  1218. int cyPerInch = GetDeviceCaps(LOGPIXELSY);
  1219. ATLASSERT(cxPerInch != 0 && cyPerInch != 0);
  1220. lpSize->cx = MulDiv(lpSize->cx, HIMETRIC_INCH, cxPerInch);
  1221. lpSize->cy = MulDiv(lpSize->cy, HIMETRIC_INCH, cyPerInch);
  1222. }
  1223. }
  1224. void HIMETRICtoDP(LPSIZE lpSize) const
  1225. {
  1226. ATLASSERT(m_hDC != NULL);
  1227. int nMapMode;
  1228. if((nMapMode = GetMapMode()) < MM_ISOTROPIC && nMapMode != MM_TEXT)
  1229. {
  1230. // when using a constrained map mode, map against physical inch
  1231. ((CDCHandle*)this)->SetMapMode(MM_HIMETRIC);
  1232. LPtoDP(lpSize);
  1233. ((CDCHandle*)this)->SetMapMode(nMapMode);
  1234. }
  1235. else
  1236. {
  1237. // map against logical inch for non-constrained mapping modes
  1238. int cxPerInch = GetDeviceCaps(LOGPIXELSX);
  1239. int cyPerInch = GetDeviceCaps(LOGPIXELSY);
  1240. ATLASSERT(cxPerInch != 0 && cyPerInch != 0);
  1241. lpSize->cx = MulDiv(lpSize->cx, cxPerInch, HIMETRIC_INCH);
  1242. lpSize->cy = MulDiv(lpSize->cy, cyPerInch, HIMETRIC_INCH);
  1243. }
  1244. }
  1245. void LPtoHIMETRIC(LPSIZE lpSize) const
  1246. {
  1247. LPtoDP(lpSize);
  1248. DPtoHIMETRIC(lpSize);
  1249. }
  1250. void HIMETRICtoLP(LPSIZE lpSize) const
  1251. {
  1252. HIMETRICtoDP(lpSize);
  1253. DPtoLP(lpSize);
  1254. }
  1255. // Region Functions
  1256. BOOL FillRgn(HRGN hRgn, HBRUSH hBrush)
  1257. {
  1258. ATLASSERT(m_hDC != NULL);
  1259. return ::FillRgn(m_hDC, hRgn, hBrush);
  1260. }
  1261. BOOL FrameRgn(HRGN hRgn, HBRUSH hBrush, int nWidth, int nHeight)
  1262. {
  1263. ATLASSERT(m_hDC != NULL);
  1264. return ::FrameRgn(m_hDC, hRgn, hBrush, nWidth, nHeight);
  1265. }
  1266. BOOL InvertRgn(HRGN hRgn)
  1267. {
  1268. ATLASSERT(m_hDC != NULL);
  1269. return ::InvertRgn(m_hDC, hRgn);
  1270. }
  1271. BOOL PaintRgn(HRGN hRgn)
  1272. {
  1273. ATLASSERT(m_hDC != NULL);
  1274. return ::PaintRgn(m_hDC, hRgn);
  1275. }
  1276. // Clipping Functions
  1277. int GetClipBox(LPRECT lpRect) const
  1278. {
  1279. ATLASSERT(m_hDC != NULL);
  1280. return ::GetClipBox(m_hDC, lpRect);
  1281. }
  1282. BOOL PtVisible(int x, int y) const
  1283. {
  1284. ATLASSERT(m_hDC != NULL);
  1285. return ::PtVisible(m_hDC, x, y);
  1286. }
  1287. BOOL PtVisible(POINT point) const
  1288. {
  1289. ATLASSERT(m_hDC != NULL);
  1290. return ::PtVisible(m_hDC, point.x, point.y);
  1291. }
  1292. BOOL RectVisible(LPCRECT lpRect) const
  1293. {
  1294. ATLASSERT(m_hDC != NULL);
  1295. return ::RectVisible(m_hDC, lpRect);
  1296. }
  1297. int SelectClipRgn(HRGN hRgn)
  1298. {
  1299. ATLASSERT(m_hDC != NULL);
  1300. return ::SelectClipRgn(m_hDC, (HRGN)hRgn);
  1301. }
  1302. int ExcludeClipRect(int x1, int y1, int x2, int y2)
  1303. {
  1304. ATLASSERT(m_hDC != NULL);
  1305. return ::ExcludeClipRect(m_hDC, x1, y1, x2, y2);
  1306. }
  1307. int ExcludeClipRect(LPCRECT lpRect)
  1308. {
  1309. ATLASSERT(m_hDC != NULL);
  1310. return ::ExcludeClipRect(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
  1311. }
  1312. int ExcludeUpdateRgn(HWND hWnd)
  1313. {
  1314. ATLASSERT(m_hDC != NULL);
  1315. return ::ExcludeUpdateRgn(m_hDC, hWnd);
  1316. }
  1317. int IntersectClipRect(int x1, int y1, int x2, int y2)
  1318. {
  1319. ATLASSERT(m_hDC != NULL);
  1320. return ::IntersectClipRect(m_hDC, x1, y1, x2, y2);
  1321. }
  1322. int IntersectClipRect(LPCRECT lpRect)
  1323. {
  1324. ATLASSERT(m_hDC != NULL);
  1325. return ::IntersectClipRect(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
  1326. }
  1327. int OffsetClipRgn(int x, int y)
  1328. {
  1329. ATLASSERT(m_hDC != NULL);
  1330. return ::OffsetClipRgn(m_hDC, x, y);
  1331. }
  1332. int OffsetClipRgn(SIZE size)
  1333. {
  1334. ATLASSERT(m_hDC != NULL);
  1335. return ::OffsetClipRgn(m_hDC, size.cx, size.cy);
  1336. }
  1337. int SelectClipRgn(HRGN hRgn, int nMode)
  1338. {
  1339. ATLASSERT(m_hDC != NULL);
  1340. return ::ExtSelectClipRgn(m_hDC, hRgn, nMode);
  1341. }
  1342. // Line-Output Functions
  1343. BOOL GetCurrentPosition(LPPOINT lpPoint) const
  1344. {
  1345. ATLASSERT(m_hDC != NULL);
  1346. return ::GetCurrentPositionEx(m_hDC, lpPoint);
  1347. }
  1348. BOOL MoveTo(int x, int y, LPPOINT lpPoint = NULL)
  1349. {
  1350. ATLASSERT(m_hDC != NULL);
  1351. return ::MoveToEx(m_hDC, x, y, lpPoint);
  1352. }
  1353. BOOL MoveTo(POINT point, LPPOINT lpPointRet = NULL)
  1354. {
  1355. ATLASSERT(m_hDC != NULL);
  1356. return MoveTo(point.x, point.y, lpPointRet);
  1357. }
  1358. BOOL LineTo(int x, int y)
  1359. {
  1360. ATLASSERT(m_hDC != NULL);
  1361. return ::LineTo(m_hDC, x, y);
  1362. }
  1363. BOOL LineTo(POINT point)
  1364. {
  1365. ATLASSERT(m_hDC != NULL);
  1366. return LineTo(point.x, point.y);
  1367. }
  1368. BOOL Arc(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4)
  1369. {
  1370. ATLASSERT(m_hDC != NULL);
  1371. return ::Arc(m_hDC, x1, y1, x2, y2, x3, y3, x4, y4);
  1372. }
  1373. BOOL Arc(LPCRECT lpRect, POINT ptStart, POINT ptEnd)
  1374. {
  1375. ATLASSERT(m_hDC != NULL);
  1376. return ::Arc(m_hDC, lpRect->left, lpRect->top,
  1377. lpRect->right, lpRect->bottom, ptStart.x, ptStart.y,
  1378. ptEnd.x, ptEnd.y);
  1379. }
  1380. BOOL Polyline(LPPOINT lpPoints, int nCount)
  1381. {
  1382. ATLASSERT(m_hDC != NULL);
  1383. return ::Polyline(m_hDC, lpPoints, nCount);
  1384. }
  1385. BOOL AngleArc(int x, int y, int nRadius, float fStartAngle, float fSweepAngle)
  1386. {
  1387. ATLASSERT(m_hDC != NULL);
  1388. return ::AngleArc(m_hDC, x, y, nRadius, fStartAngle, fSweepAngle);
  1389. }
  1390. BOOL ArcTo(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4)
  1391. {
  1392. ATLASSERT(m_hDC != NULL);
  1393. return ::ArcTo(m_hDC, x1, y1, x2, y2, x3, y3, x4, y4);
  1394. }
  1395. BOOL ArcTo(LPCRECT lpRect, POINT ptStart, POINT ptEnd)
  1396. {
  1397. ATLASSERT(m_hDC != NULL);
  1398. return ArcTo(lpRect->left, lpRect->top, lpRect->right,
  1399. lpRect->bottom, ptStart.x, ptStart.y, ptEnd.x, ptEnd.y);
  1400. }
  1401. int GetArcDirection() const
  1402. {
  1403. ATLASSERT(m_hDC != NULL);
  1404. return ::GetArcDirection(m_hDC);
  1405. }
  1406. int SetArcDirection(int nArcDirection)
  1407. {
  1408. ATLASSERT(m_hDC != NULL);
  1409. return ::SetArcDirection(m_hDC, nArcDirection);
  1410. }
  1411. BOOL PolyDraw(const POINT* lpPoints, const BYTE* lpTypes, int nCount)
  1412. {
  1413. ATLASSERT(m_hDC != NULL);
  1414. return ::PolyDraw(m_hDC, lpPoints, lpTypes, nCount);
  1415. }
  1416. BOOL PolylineTo(const POINT* lpPoints, int nCount)
  1417. {
  1418. ATLASSERT(m_hDC != NULL);
  1419. return ::PolylineTo(m_hDC, lpPoints, nCount);
  1420. }
  1421. BOOL PolyPolyline(const POINT* lpPoints,
  1422. const DWORD* lpPolyPoints, int nCount)
  1423. {
  1424. ATLASSERT(m_hDC != NULL);
  1425. return ::PolyPolyline(m_hDC, lpPoints, lpPolyPoints, nCount);
  1426. }
  1427. BOOL PolyBezier(const POINT* lpPoints, int nCount)
  1428. {
  1429. ATLASSERT(m_hDC != NULL);
  1430. return ::PolyBezier(m_hDC, lpPoints, nCount);
  1431. }
  1432. BOOL PolyBezierTo(const POINT* lpPoints, int nCount)
  1433. {
  1434. ATLASSERT(m_hDC != NULL);
  1435. return ::PolyBezierTo(m_hDC, lpPoints, nCount);
  1436. }
  1437. // Simple Drawing Functions
  1438. BOOL FillRect(LPCRECT lpRect, HBRUSH hBrush)
  1439. {
  1440. ATLASSERT(m_hDC != NULL);
  1441. return ::FillRect(m_hDC, lpRect, hBrush);
  1442. }
  1443. BOOL FrameRect(LPCRECT lpRect, HBRUSH hBrush)
  1444. {
  1445. ATLASSERT(m_hDC != NULL);
  1446. return ::FrameRect(m_hDC, lpRect, hBrush);
  1447. }
  1448. BOOL InvertRect(LPCRECT lpRect)
  1449. {
  1450. ATLASSERT(m_hDC != NULL);
  1451. return ::InvertRect(m_hDC, lpRect);
  1452. }
  1453. BOOL DrawIcon(int x, int y, HICON hIcon)
  1454. {
  1455. ATLASSERT(m_hDC != NULL);
  1456. return ::DrawIcon(m_hDC, x, y, hIcon);
  1457. }
  1458. BOOL DrawIcon(POINT point, HICON hIcon)
  1459. {
  1460. ATLASSERT(m_hDC != NULL);
  1461. return ::DrawIcon(m_hDC, point.x, point.y, hIcon);
  1462. }
  1463. BOOL DrawIconEx(int x, int y, HICON hIcon, int cxWidth, int cyWidth, UINT uStepIfAniCur = 0, HBRUSH hbrFlickerFreeDraw = NULL, UINT uFlags = DI_NORMAL)
  1464. {
  1465. ATLASSERT(m_hDC != NULL);
  1466. return ::DrawIconEx(m_hDC, x, y, hIcon, cxWidth, cyWidth, uStepIfAniCur, hbrFlickerFreeDraw, uFlags);
  1467. }
  1468. BOOL DrawIconEx(POINT point, HICON hIcon, SIZE size, UINT uStepIfAniCur = 0, HBRUSH hbrFlickerFreeDraw = NULL, UINT uFlags = DI_NORMAL)
  1469. {
  1470. ATLASSERT(m_hDC != NULL);
  1471. return ::DrawIconEx(m_hDC, point.x, point.y, hIcon, size.cx, size.cy, uStepIfAniCur, hbrFlickerFreeDraw, uFlags);
  1472. }
  1473. BOOL DrawState(POINT pt, SIZE size, HBITMAP hBitmap, UINT nFlags, HBRUSH hBrush = NULL)
  1474. {
  1475. ATLASSERT(m_hDC != NULL);
  1476. return ::DrawState(m_hDC, hBrush, NULL, (LPARAM)hBitmap, 0, pt.x, pt.y, size.cx, size.cy, nFlags | DST_BITMAP);
  1477. }
  1478. BOOL DrawState(POINT pt, SIZE size, HICON hIcon, UINT nFlags, HBRUSH hBrush = NULL)
  1479. {
  1480. ATLASSERT(m_hDC != NULL);
  1481. return ::DrawState(m_hDC, hBrush, NULL, (LPARAM)hIcon, 0, pt.x, pt.y, size.cx, size.cy, nFlags | DST_ICON);
  1482. }
  1483. BOOL DrawState(POINT pt, SIZE size, LPCTSTR lpszText, UINT nFlags, BOOL bPrefixText = TRUE, int nTextLen = 0, HBRUSH hBrush = NULL)
  1484. {
  1485. ATLASSERT(m_hDC != NULL);
  1486. return ::DrawState(m_hDC, hBrush, NULL, (LPARAM)lpszText, (WPARAM)nTextLen, pt.x, pt.y, size.cx, size.cy, nFlags | (bPrefixText ? DST_PREFIXTEXT : DST_TEXT));
  1487. }
  1488. BOOL DrawState(POINT pt, SIZE size, DRAWSTATEPROC lpDrawProc, LPARAM lData, UINT nFlags, HBRUSH hBrush = NULL)
  1489. {
  1490. ATLASSERT(m_hDC != NULL);
  1491. return ::DrawState(m_hDC, hBrush, lpDrawProc, lData, 0, pt.x, pt.y, size.cx, size.cy, nFlags | DST_COMPLEX);
  1492. }
  1493. // Ellipse and Polygon Functions
  1494. BOOL Chord(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4)
  1495. {
  1496. ATLASSERT(m_hDC != NULL);
  1497. return ::Chord(m_hDC, x1, y1, x2, y2, x3, y3, x4, y4);
  1498. }
  1499. BOOL Chord(LPCRECT lpRect, POINT ptStart, POINT ptEnd)
  1500. {
  1501. ATLASSERT(m_hDC != NULL);
  1502. return ::Chord(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom, ptStart.x, ptStart.y, ptEnd.x, ptEnd.y);
  1503. }
  1504. void DrawFocusRect(LPCRECT lpRect)
  1505. {
  1506. ATLASSERT(m_hDC != NULL);
  1507. ::DrawFocusRect(m_hDC, lpRect);
  1508. }
  1509. BOOL Ellipse(int x1, int y1, int x2, int y2)
  1510. {
  1511. ATLASSERT(m_hDC != NULL);
  1512. return ::Ellipse(m_hDC, x1, y1, x2, y2);
  1513. }
  1514. BOOL Ellipse(LPCRECT lpRect)
  1515. {
  1516. ATLASSERT(m_hDC != NULL);
  1517. return ::Ellipse(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
  1518. }
  1519. BOOL Pie(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4)
  1520. {
  1521. ATLASSERT(m_hDC != NULL);
  1522. return ::Pie(m_hDC, x1, y1, x2, y2, x3, y3, x4, y4);
  1523. }
  1524. BOOL Pie(LPCRECT lpRect, POINT ptStart, POINT ptEnd)
  1525. {
  1526. ATLASSERT(m_hDC != NULL);
  1527. return ::Pie(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom, ptStart.x, ptStart.y, ptEnd.x, ptEnd.y);
  1528. }
  1529. BOOL Polygon(LPPOINT lpPoints, int nCount)
  1530. {
  1531. ATLASSERT(m_hDC != NULL);
  1532. return ::Polygon(m_hDC, lpPoints, nCount);
  1533. }
  1534. BOOL PolyPolygon(LPPOINT lpPoints, LPINT lpPolyCounts, int nCount)
  1535. {
  1536. ATLASSERT(m_hDC != NULL);
  1537. return ::PolyPolygon(m_hDC, lpPoints, lpPolyCounts, nCount);
  1538. }
  1539. BOOL Rectangle(int x1, int y1, int x2, int y2)
  1540. {
  1541. ATLASSERT(m_hDC != NULL);
  1542. return ::Rectangle(m_hDC, x1, y1, x2, y2);
  1543. }
  1544. BOOL Rectangle(LPCRECT lpRect)
  1545. {
  1546. ATLASSERT(m_hDC != NULL);
  1547. return ::Rectangle(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
  1548. }
  1549. BOOL RoundRect(int x1, int y1, int x2, int y2, int x3, int y3)
  1550. {
  1551. ATLASSERT(m_hDC != NULL);
  1552. return ::RoundRect(m_hDC, x1, y1, x2, y2, x3, y3);
  1553. }
  1554. BOOL RoundRect(LPCRECT lpRect, POINT point)
  1555. {
  1556. ATLASSERT(m_hDC != NULL);
  1557. return ::RoundRect(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom, point.x, point.y);
  1558. }
  1559. // Bitmap Functions
  1560. BOOL PatBlt(int x, int y, int nWidth, int nHeight, DWORD dwRop)
  1561. {
  1562. ATLASSERT(m_hDC != NULL);
  1563. return ::PatBlt(m_hDC, x, y, nWidth, nHeight, dwRop);
  1564. }
  1565. BOOL BitBlt(int x, int y, int nWidth, int nHeight, HDC hSrcDC,
  1566. int xSrc, int ySrc, DWORD dwRop)
  1567. {
  1568. ATLASSERT(m_hDC != NULL);
  1569. return ::BitBlt(m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, dwRop);
  1570. }
  1571. BOOL StretchBlt(int x, int y, int nWidth, int nHeight, HDC hSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, DWORD dwRop)
  1572. {
  1573. ATLASSERT(m_hDC != NULL);
  1574. return ::StretchBlt(m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, nSrcWidth, nSrcHeight, dwRop);
  1575. }
  1576. COLORREF GetPixel(int x, int y) const
  1577. {
  1578. ATLASSERT(m_hDC != NULL);
  1579. return ::GetPixel(m_hDC, x, y);
  1580. }
  1581. COLORREF GetPixel(POINT point) const
  1582. {
  1583. ATLASSERT(m_hDC != NULL);
  1584. return ::GetPixel(m_hDC, point.x, point.y);
  1585. }
  1586. COLORREF SetPixel(int x, int y, COLORREF crColor)
  1587. {
  1588. ATLASSERT(m_hDC != NULL);
  1589. return ::SetPixel(m_hDC, x, y, crColor);
  1590. }
  1591. COLORREF SetPixel(POINT point, COLORREF crColor)
  1592. {
  1593. ATLASSERT(m_hDC != NULL);
  1594. return ::SetPixel(m_hDC, point.x, point.y, crColor);
  1595. }
  1596. BOOL FloodFill(int x, int y, COLORREF crColor)
  1597. {
  1598. ATLASSERT(m_hDC != NULL);
  1599. return ::FloodFill(m_hDC, x, y, crColor);
  1600. }
  1601. BOOL ExtFloodFill(int x, int y, COLORREF crColor, UINT nFillType)
  1602. {
  1603. ATLASSERT(m_hDC != NULL);
  1604. return ::ExtFloodFill(m_hDC, x, y, crColor, nFillType);
  1605. }
  1606. BOOL MaskBlt(int x, int y, int nWidth, int nHeight, HDC hSrcDC, int xSrc, int ySrc, HBITMAP hMaskBitmap, int xMask, int yMask, DWORD dwRop)
  1607. {
  1608. ATLASSERT(m_hDC != NULL);
  1609. return ::MaskBlt(m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, hMaskBitmap, xMask, yMask, dwRop);
  1610. }
  1611. BOOL PlgBlt(LPPOINT lpPoint, HDC hSrcDC, int xSrc, int ySrc, int nWidth, int nHeight, HBITMAP hMaskBitmap, int xMask, int yMask)
  1612. {
  1613. ATLASSERT(m_hDC != NULL);
  1614. return ::PlgBlt(m_hDC, lpPoint, hSrcDC, xSrc, ySrc, nWidth, nHeight, hMaskBitmap, xMask, yMask);
  1615. }
  1616. BOOL SetPixelV(int x, int y, COLORREF crColor)
  1617. {
  1618. ATLASSERT(m_hDC != NULL);
  1619. return ::SetPixelV(m_hDC, x, y, crColor);
  1620. }
  1621. BOOL SetPixelV(POINT point, COLORREF crColor)
  1622. {
  1623. ATLASSERT(m_hDC != NULL);
  1624. return ::SetPixelV(m_hDC, point.x, point.y, crColor);
  1625. }
  1626. #ifndef _ATL_NO_MSIMG
  1627. BOOL AlphaBlend(int x, int y, int nWidth, int nHeight, HDC hSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, BLENDFUNCTION bf)
  1628. {
  1629. ATLASSERT(m_hDC != NULL);
  1630. return ::AlphaBlend(m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, nSrcWidth, nSrcHeight, bf);
  1631. }
  1632. BOOL TransparentBlt(int x, int y, int nWidth, int nHeight, HDC hSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, UINT crTransparent)
  1633. {
  1634. ATLASSERT(m_hDC != NULL);
  1635. return ::TransparentBlt(m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, nSrcWidth, nSrcHeight, crTransparent);
  1636. }
  1637. BOOL GradientFill(const PTRIVERTEX pVertices, DWORD nVertices, void* pMeshElements, DWORD nMeshElements, DWORD dwMode)
  1638. {
  1639. ATLASSERT(m_hDC != NULL);
  1640. return ::GradientFill(m_hDC, pVertices, nVertices, pMeshElements, nMeshElements, dwMode);
  1641. }
  1642. #endif //!_ATL_NO_MSIMG
  1643. // Extra bitmap functions
  1644. // Helper function for painting a disabled toolbar or menu bitmap
  1645. // This function can take either an HBITMAP (for SS) or a DC with
  1646. // the bitmap already painted (for cmdbar)
  1647. BOOL DitherBlt(int x, int y, int nWidth, int nHeight, HDC hSrcDC, HBITMAP hBitmap, int xSrc, int ySrc)
  1648. {
  1649. ATLASSERT(m_hDC != NULL || hBitmap != NULL);
  1650. ATLASSERT(nWidth > 0 && nHeight > 0);
  1651. // Create a generic DC for all BitBlts
  1652. CDCHandle dc = (hSrcDC != NULL) ? hSrcDC : ::CreateCompatibleDC(m_hDC);
  1653. ATLASSERT(dc.m_hDC != NULL);
  1654. if(dc.m_hDC == NULL)
  1655. return FALSE;
  1656. // Create a DC for the monochrome DIB section
  1657. CDC dcBW = ::CreateCompatibleDC(m_hDC);
  1658. ATLASSERT(dcBW.m_hDC != NULL);
  1659. if(dcBW.m_hDC == NULL)
  1660. {
  1661. if(hSrcDC == NULL)
  1662. ::DeleteDC(dc);
  1663. return FALSE;
  1664. }
  1665. // Create the monochrome DIB section with a black and white palette
  1666. struct RGBBWBITMAPINFO
  1667. {
  1668. BITMAPINFOHEADER bmiHeader;
  1669. RGBQUAD bmiColors[2];
  1670. };
  1671. RGBBWBITMAPINFO rgbBWBitmapInfo =
  1672. {
  1673. { sizeof(BITMAPINFOHEADER), nWidth, nHeight, 1, 1, BI_RGB, 0, 0, 0, 0, 0 },
  1674. { { 0x00, 0x00, 0x00, 0x00 }, { 0xFF, 0xFF, 0xFF, 0x00 } }
  1675. };
  1676. VOID *pbitsBW;
  1677. CBitmap bmpBW = ::CreateDIBSection(dcBW, (LPBITMAPINFO)&rgbBWBitmapInfo, DIB_RGB_COLORS, &pbitsBW, NULL, 0);
  1678. ATLASSERT(bmpBW.m_hBitmap != NULL);
  1679. if(bmpBW.m_hBitmap == NULL)
  1680. {
  1681. if(hSrcDC == NULL)
  1682. ::DeleteDC(dc);
  1683. return FALSE;
  1684. }
  1685. // Attach the monochrome DIB section and the bitmap to the DCs
  1686. HBITMAP hbmOldBW = dcBW.SelectBitmap(bmpBW);
  1687. HBITMAP hbmOldDC = NULL;
  1688. if(hBitmap != NULL)
  1689. hbmOldDC = dc.SelectBitmap(hBitmap);
  1690. // Block: Dark gray removal: we want (128, 128, 128) pixels to become black and not white
  1691. {
  1692. CDC dcTemp1 = ::CreateCompatibleDC(m_hDC);
  1693. CDC dcTemp2 = ::CreateCompatibleDC(m_hDC);
  1694. CBitmap bmpTemp1;
  1695. bmpTemp1.CreateCompatibleBitmap(dc, nWidth, nHeight);
  1696. CBitmap bmpTemp2;
  1697. bmpTemp2.CreateBitmap(nWidth, nHeight, 1, 1, NULL);
  1698. HBITMAP hOldBmp1 = dcTemp1.SelectBitmap(bmpTemp1);
  1699. HBITMAP hOldBmp2 = dcTemp2.SelectBitmap(bmpTemp2);
  1700. // Let's copy our image, it will be altered
  1701. dcTemp1.BitBlt(0, 0, nWidth, nHeight, dc, xSrc, ySrc, SRCCOPY);
  1702. // All dark gray pixels will become white, the others black
  1703. dcTemp1.SetBkColor(RGB(128, 128, 128));
  1704. dcTemp2.BitBlt(0, 0, nWidth, nHeight, dcTemp1, 0, 0, SRCCOPY);
  1705. // Do an XOR to set to black these white pixels
  1706. dcTemp1.BitBlt(0, 0, nWidth, nHeight, dcTemp2, 0, 0, SRCINVERT);
  1707. // BitBlt the bitmap into the monochrome DIB section
  1708. // The DIB section will do a true monochrome conversion
  1709. // The magenta background being closer to white will become white
  1710. dcBW.BitBlt(0, 0, nWidth, nHeight, dcTemp1, 0, 0, SRCCOPY);
  1711. // Cleanup
  1712. dcTemp1.SelectBitmap(hOldBmp1);
  1713. dcTemp2.SelectBitmap(hOldBmp2);
  1714. }
  1715. // Paint the destination rectangle in gray
  1716. RECT rc = { x, y, x + nWidth, y + nHeight };
  1717. FillRect(&rc, ::GetSysColorBrush(COLOR_3DFACE));
  1718. // BitBlt the black bits in the monochrome bitmap into COLOR_3DHILIGHT bits in the destination DC
  1719. // The magic ROP comes from the Charles Petzold's book
  1720. CBrush brushHilight;
  1721. brushHilight.CreateSolidBrush(::GetSysColor(COLOR_3DHILIGHT));
  1722. HBRUSH hOldBrush = SelectBrush(brushHilight);
  1723. BitBlt(x + 1, y + 1, nWidth, nHeight, dcBW, 0, 0, 0xB8074A);
  1724. // BitBlt the black bits in the monochrome bitmap into COLOR_3DSHADOW bits in the destination DC
  1725. CBrush brushShadow;
  1726. brushShadow.CreateSolidBrush(::GetSysColor(COLOR_3DSHADOW));
  1727. SelectBrush(brushShadow);
  1728. BitBlt(x, y, nWidth, nHeight, dcBW, 0, 0, 0xB8074A);
  1729. SelectBrush(hOldBrush);
  1730. dcBW.SelectBitmap(hbmOldBW);
  1731. dc.SelectBitmap(hbmOldDC);
  1732. if(hSrcDC == NULL)
  1733. ::DeleteDC(dc);
  1734. return TRUE;
  1735. }
  1736. // Text Functions
  1737. BOOL TextOut(int x, int y, LPCTSTR lpszString, int nCount = -1)
  1738. {
  1739. ATLASSERT(m_hDC != NULL);
  1740. if(nCount == -1)
  1741. nCount = lstrlen(lpszString);
  1742. return ::TextOut(m_hDC, x, y, lpszString, nCount);
  1743. }
  1744. BOOL ExtTextOut(int x, int y, UINT nOptions, LPCRECT lpRect, LPCTSTR lpszString, UINT nCount = -1, LPINT lpDxWidths = NULL)
  1745. {
  1746. ATLASSERT(m_hDC != NULL);
  1747. if(nCount == -1)
  1748. nCount = lstrlen(lpszString);
  1749. return ::ExtTextOut(m_hDC, x, y, nOptions, lpRect, lpszString, nCount, lpDxWidths);
  1750. }
  1751. SIZE TabbedTextOut(int x, int y, LPCTSTR lpszString, int nCount = -1, int nTabPositions = 0, LPINT lpnTabStopPositions = NULL, int nTabOrigin = 0)
  1752. {
  1753. ATLASSERT(m_hDC != NULL);
  1754. if(nCount == -1)
  1755. nCount = lstrlen(lpszString);
  1756. LONG lRes = ::TabbedTextOut(m_hDC, x, y, lpszString, nCount, nTabPositions, lpnTabStopPositions, nTabOrigin);
  1757. SIZE size = { GET_X_LPARAM(lRes), GET_Y_LPARAM(lRes) };
  1758. return size;
  1759. }
  1760. int DrawText(LPCTSTR lpszString, int nCount, LPRECT lpRect, UINT nFormat)
  1761. {
  1762. ATLASSERT(m_hDC != NULL);
  1763. return ::DrawText(m_hDC, lpszString, nCount, lpRect, nFormat);
  1764. }
  1765. BOOL GetTextExtent(LPCTSTR lpszString, int nCount, LPSIZE lpSize) const
  1766. {
  1767. ATLASSERT(m_hDC != NULL);
  1768. if(nCount == -1)
  1769. nCount = lstrlen(lpszString);
  1770. return ::GetTextExtentPoint32(m_hDC, lpszString, nCount, lpSize);
  1771. }
  1772. BOOL GetTabbedTextExtent(LPCTSTR lpszString, int nCount, int nTabPositions, LPINT lpnTabStopPositions) const
  1773. {
  1774. ATLASSERT(m_hDC != NULL);
  1775. if(nCount == -1)
  1776. nCount = lstrlen(lpszString);
  1777. return ::GetTabbedTextExtent(m_hDC, lpszString, nCount, nTabPositions, lpnTabStopPositions);
  1778. }
  1779. BOOL GrayString(HBRUSH hBrush, BOOL (CALLBACK* lpfnOutput)(HDC, LPARAM, int), LPARAM lpData, int nCount, int x, int y, int nWidth, int nHeight)
  1780. {
  1781. ATLASSERT(m_hDC != NULL);
  1782. return ::GrayString(m_hDC, hBrush, (GRAYSTRINGPROC)lpfnOutput, lpData, nCount, x, y, nWidth, nHeight);
  1783. }
  1784. UINT GetTextAlign() const
  1785. {
  1786. ATLASSERT(m_hDC != NULL);
  1787. return ::GetTextAlign(m_hDC);
  1788. }
  1789. UINT SetTextAlign(UINT nFlags)
  1790. {
  1791. ATLASSERT(m_hDC != NULL);
  1792. return ::SetTextAlign(m_hDC, nFlags);
  1793. }
  1794. int GetTextFace(LPTSTR lpszFacename, int nCount) const
  1795. {
  1796. ATLASSERT(m_hDC != NULL);
  1797. return ::GetTextFace(m_hDC, nCount, lpszFacename);
  1798. }
  1799. int GetTextFaceLen() const
  1800. {
  1801. ATLASSERT(m_hDC != NULL);
  1802. return ::GetTextFace(m_hDC, 0, NULL);
  1803. }
  1804. #ifndef _ATL_NO_COM
  1805. #ifdef _OLEAUTO_H_
  1806. BOOL GetTextFace(BSTR& bstrFace) const
  1807. {
  1808. USES_CONVERSION;
  1809. ATLASSERT(m_hDC != NULL);
  1810. ATLASSERT(bstrFace == NULL);
  1811. int nLen = GetTextFaceLen();
  1812. if(nLen == 0)
  1813. return FALSE;
  1814. LPTSTR lpszText = (LPTSTR)_alloca(nLen * sizeof(TCHAR));
  1815. if(!GetTextFace(lpszText, nLen))
  1816. return FALSE;
  1817. bstrFace = ::SysAllocString(T2OLE(lpszText));
  1818. return (bstrFace != NULL) ? TRUE : FALSE;
  1819. }
  1820. #endif
  1821. #endif //!_ATL_NO_COM
  1822. #ifdef __ATLSTR_H__
  1823. int GetTextFace(CString& strFace) const
  1824. {
  1825. ATLASSERT(m_hDC != NULL);
  1826. int nLen = GetTextFaceLen();
  1827. if(nLen == 0)
  1828. return 0;
  1829. int nRet = GetTextFace(strFace.GetBufferSetLength(nLen), nLen);
  1830. strFace.ReleaseBuffer();
  1831. return nRet;
  1832. }
  1833. #endif //__ATLSTR_H__
  1834. BOOL GetTextMetrics(LPTEXTMETRIC lpMetrics) const
  1835. {
  1836. ATLASSERT(m_hDC != NULL);
  1837. return ::GetTextMetrics(m_hDC, lpMetrics);
  1838. }
  1839. int SetTextJustification(int nBreakExtra, int nBreakCount)
  1840. {
  1841. ATLASSERT(m_hDC != NULL);
  1842. return ::SetTextJustification(m_hDC, nBreakExtra, nBreakCount);
  1843. }
  1844. int GetTextCharacterExtra() const
  1845. {
  1846. ATLASSERT(m_hDC != NULL);
  1847. return ::GetTextCharacterExtra(m_hDC);
  1848. }
  1849. int SetTextCharacterExtra(int nCharExtra)
  1850. {
  1851. ATLASSERT(m_hDC != NULL);
  1852. return ::SetTextCharacterExtra(m_hDC, nCharExtra);
  1853. }
  1854. // Advanced Drawing
  1855. BOOL DrawEdge(LPRECT lpRect, UINT nEdge, UINT nFlags)
  1856. {
  1857. ATLASSERT(m_hDC != NULL);
  1858. return ::DrawEdge(m_hDC, lpRect, nEdge, nFlags);
  1859. }
  1860. BOOL DrawFrameControl(LPRECT lpRect, UINT nType, UINT nState)
  1861. {
  1862. ATLASSERT(m_hDC != NULL);
  1863. return ::DrawFrameControl(m_hDC, lpRect, nType, nState);
  1864. }
  1865. // Scrolling Functions
  1866. BOOL ScrollDC(int dx, int dy, LPCRECT lpRectScroll, LPCRECT lpRectClip, HRGN hRgnUpdate, LPRECT lpRectUpdate)
  1867. {
  1868. ATLASSERT(m_hDC != NULL);
  1869. return ::ScrollDC(m_hDC, dx, dy, lpRectScroll, lpRectClip, hRgnUpdate, lpRectUpdate);
  1870. }
  1871. // Font Functions
  1872. BOOL GetCharWidth(UINT nFirstChar, UINT nLastChar, LPINT lpBuffer) const
  1873. {
  1874. ATLASSERT(m_hDC != NULL);
  1875. return ::GetCharWidth(m_hDC, nFirstChar, nLastChar, lpBuffer);
  1876. }
  1877. // GetCharWidth32 is not supported under Win9x
  1878. BOOL GetCharWidth32(UINT nFirstChar, UINT nLastChar, LPINT lpBuffer) const
  1879. {
  1880. ATLASSERT(m_hDC != NULL);
  1881. return ::GetCharWidth32(m_hDC, nFirstChar, nLastChar, lpBuffer);
  1882. }
  1883. DWORD SetMapperFlags(DWORD dwFlag)
  1884. {
  1885. ATLASSERT(m_hDC != NULL);
  1886. return ::SetMapperFlags(m_hDC, dwFlag);
  1887. }
  1888. BOOL GetAspectRatioFilter(LPSIZE lpSize) const
  1889. {
  1890. ATLASSERT(m_hDC != NULL);
  1891. return ::GetAspectRatioFilterEx(m_hDC, lpSize);
  1892. }
  1893. BOOL GetCharABCWidths(UINT nFirstChar, UINT nLastChar, LPABC lpabc) const
  1894. {
  1895. ATLASSERT(m_hDC != NULL);
  1896. return ::GetCharABCWidths(m_hDC, nFirstChar, nLastChar, lpabc);
  1897. }
  1898. DWORD GetFontData(DWORD dwTable, DWORD dwOffset, LPVOID lpData, DWORD cbData) const
  1899. {
  1900. ATLASSERT(m_hDC != NULL);
  1901. return ::GetFontData(m_hDC, dwTable, dwOffset, lpData, cbData);
  1902. }
  1903. int GetKerningPairs(int nPairs, LPKERNINGPAIR lpkrnpair) const
  1904. {
  1905. ATLASSERT(m_hDC != NULL);
  1906. return ::GetKerningPairs(m_hDC, nPairs, lpkrnpair);
  1907. }
  1908. UINT GetOutlineTextMetrics(UINT cbData, LPOUTLINETEXTMETRIC lpotm) const
  1909. {
  1910. ATLASSERT(m_hDC != NULL);
  1911. return ::GetOutlineTextMetrics(m_hDC, cbData, lpotm);
  1912. }
  1913. DWORD GetGlyphOutline(UINT nChar, UINT nFormat, LPGLYPHMETRICS lpgm, DWORD cbBuffer, LPVOID lpBuffer, const MAT2* lpmat2) const
  1914. {
  1915. ATLASSERT(m_hDC != NULL);
  1916. return ::GetGlyphOutline(m_hDC, nChar, nFormat, lpgm, cbBuffer, lpBuffer, lpmat2);
  1917. }
  1918. BOOL GetCharABCWidths(UINT nFirstChar, UINT nLastChar, LPABCFLOAT lpABCF) const
  1919. {
  1920. ATLASSERT(m_hDC != NULL);
  1921. return ::GetCharABCWidthsFloat(m_hDC, nFirstChar, nLastChar, lpABCF);
  1922. }
  1923. BOOL GetCharWidth(UINT nFirstChar, UINT nLastChar, float* lpFloatBuffer) const
  1924. {
  1925. ATLASSERT(m_hDC != NULL);
  1926. return ::GetCharWidthFloat(m_hDC, nFirstChar, nLastChar, lpFloatBuffer);
  1927. }
  1928. // Printer/Device Escape Functions
  1929. int Escape(int nEscape, int nCount, LPCSTR lpszInData, LPVOID lpOutData)
  1930. {
  1931. ATLASSERT(m_hDC != NULL);
  1932. return ::Escape(m_hDC, nEscape, nCount, lpszInData, lpOutData);
  1933. }
  1934. int Escape(int nEscape, int nInputSize, LPCSTR lpszInputData,
  1935. int nOutputSize, LPSTR lpszOutputData)
  1936. {
  1937. ATLASSERT(m_hDC != NULL);
  1938. return ::ExtEscape(m_hDC, nEscape, nInputSize, lpszInputData, nOutputSize, lpszOutputData);
  1939. }
  1940. int DrawEscape(int nEscape, int nInputSize, LPCSTR lpszInputData)
  1941. {
  1942. ATLASSERT(m_hDC != NULL);
  1943. return ::DrawEscape(m_hDC, nEscape, nInputSize, lpszInputData);
  1944. }
  1945. // Escape helpers
  1946. int StartDoc(LPCTSTR lpszDocName) // old Win3.0 version
  1947. {
  1948. DOCINFO di;
  1949. memset(&di, 0, sizeof(DOCINFO));
  1950. di.cbSize = sizeof(DOCINFO);
  1951. di.lpszDocName = lpszDocName;
  1952. return StartDoc(&di);
  1953. }
  1954. int StartDoc(LPDOCINFO lpDocInfo)
  1955. {
  1956. ATLASSERT(m_hDC != NULL);
  1957. return ::StartDoc(m_hDC, lpDocInfo);
  1958. }
  1959. int StartPage()
  1960. {
  1961. ATLASSERT(m_hDC != NULL);
  1962. return ::StartPage(m_hDC);
  1963. }
  1964. int EndPage()
  1965. {
  1966. ATLASSERT(m_hDC != NULL);
  1967. return ::EndPage(m_hDC);
  1968. }
  1969. int SetAbortProc(BOOL (CALLBACK* lpfn)(HDC, int))
  1970. {
  1971. ATLASSERT(m_hDC != NULL);
  1972. return ::SetAbortProc(m_hDC, (ABORTPROC)lpfn);
  1973. }
  1974. int AbortDoc()
  1975. {
  1976. ATLASSERT(m_hDC != NULL);
  1977. return ::AbortDoc(m_hDC);
  1978. }
  1979. int EndDoc()
  1980. {
  1981. ATLASSERT(m_hDC != NULL);
  1982. return ::EndDoc(m_hDC);
  1983. }
  1984. // MetaFile Functions
  1985. BOOL PlayMetaFile(HMETAFILE hMF)
  1986. {
  1987. ATLASSERT(m_hDC != NULL);
  1988. if(::GetDeviceCaps(m_hDC, TECHNOLOGY) == DT_METAFILE)
  1989. {
  1990. // playing metafile in metafile, just use core windows API
  1991. return ::PlayMetaFile(m_hDC, hMF);
  1992. }
  1993. // for special playback, lParam == pDC
  1994. return ::EnumMetaFile(m_hDC, hMF, EnumMetaFileProc, (LPARAM)this);
  1995. }
  1996. BOOL PlayMetaFile(HENHMETAFILE hEnhMetaFile, LPCRECT lpBounds)
  1997. {
  1998. ATLASSERT(m_hDC != NULL);
  1999. return ::PlayEnhMetaFile(m_hDC, hEnhMetaFile, lpBounds);
  2000. }
  2001. BOOL AddMetaFileComment(UINT nDataSize, const BYTE* pCommentData) // can be used for enhanced metafiles only
  2002. {
  2003. ATLASSERT(m_hDC != NULL);
  2004. return ::GdiComment(m_hDC, nDataSize, pCommentData);
  2005. }
  2006. // Special handling for metafile playback
  2007. static int CALLBACK EnumMetaFileProc(HDC hDC, HANDLETABLE* pHandleTable, METARECORD* pMetaRec, int nHandles, LPARAM lParam)
  2008. {
  2009. CDCHandle* pDC = (CDCHandle*)lParam;
  2010. switch (pMetaRec->rdFunction)
  2011. {
  2012. case META_SETMAPMODE:
  2013. pDC->SetMapMode((int)(short)pMetaRec->rdParm[0]);
  2014. break;
  2015. case META_SETWINDOWEXT:
  2016. pDC->SetWindowExt((int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]);
  2017. break;
  2018. case META_SETWINDOWORG:
  2019. pDC->SetWindowOrg((int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]);
  2020. break;
  2021. case META_SETVIEWPORTEXT:
  2022. pDC->SetViewportExt((int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]);
  2023. break;
  2024. case META_SETVIEWPORTORG:
  2025. pDC->SetViewportOrg((int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]);
  2026. break;
  2027. case META_SCALEWINDOWEXT:
  2028. pDC->ScaleWindowExt((int)(short)pMetaRec->rdParm[3], (int)(short)pMetaRec->rdParm[2],
  2029. (int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]);
  2030. break;
  2031. case META_SCALEVIEWPORTEXT:
  2032. pDC->ScaleViewportExt((int)(short)pMetaRec->rdParm[3], (int)(short)pMetaRec->rdParm[2],
  2033. (int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]);
  2034. break;
  2035. case META_OFFSETVIEWPORTORG:
  2036. pDC->OffsetViewportOrg((int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]);
  2037. break;
  2038. case META_SAVEDC:
  2039. pDC->SaveDC();
  2040. break;
  2041. case META_RESTOREDC:
  2042. pDC->RestoreDC((int)(short)pMetaRec->rdParm[0]);
  2043. break;
  2044. case META_SETBKCOLOR:
  2045. pDC->SetBkColor(*(UNALIGNED COLORREF*)&pMetaRec->rdParm[0]);
  2046. break;
  2047. case META_SETTEXTCOLOR:
  2048. pDC->SetTextColor(*(UNALIGNED COLORREF*)&pMetaRec->rdParm[0]);
  2049. break;
  2050. // need to watch out for SelectObject(HFONT), for custom font mapping
  2051. case META_SELECTOBJECT:
  2052. {
  2053. HGDIOBJ hObject = pHandleTable->objectHandle[pMetaRec->rdParm[0]];
  2054. UINT nObjType = ::GetObjectType(hObject);
  2055. if(nObjType == 0)
  2056. {
  2057. // object type is unknown, determine if it is a font
  2058. HFONT hStockFont = (HFONT)::GetStockObject(SYSTEM_FONT);
  2059. HFONT hFontOld = (HFONT)::SelectObject(pDC->m_hDC, hStockFont);
  2060. HGDIOBJ hObjOld = ::SelectObject(pDC->m_hDC, hObject);
  2061. if(hObjOld == hStockFont)
  2062. {
  2063. // got the stock object back, so must be selecting a font
  2064. pDC->SelectFont((HFONT)hObject);
  2065. break; // don't play the default record
  2066. }
  2067. else
  2068. {
  2069. // didn't get the stock object back, so restore everything
  2070. ::SelectObject(pDC->m_hDC, hFontOld);
  2071. ::SelectObject(pDC->m_hDC, hObjOld);
  2072. }
  2073. // and fall through to PlayMetaFileRecord...
  2074. }
  2075. else if(nObjType == OBJ_FONT)
  2076. {
  2077. // play back as CDCHandle::SelectFont(HFONT)
  2078. pDC->SelectFont((HFONT)hObject);
  2079. break; // don't play the default record
  2080. }
  2081. }
  2082. // fall through...
  2083. default:
  2084. ::PlayMetaFileRecord(hDC, pHandleTable, pMetaRec, nHandles);
  2085. break;
  2086. }
  2087. return 1;
  2088. }
  2089. // Path Functions
  2090. BOOL AbortPath()
  2091. {
  2092. ATLASSERT(m_hDC != NULL);
  2093. return ::AbortPath(m_hDC);
  2094. }
  2095. BOOL BeginPath()
  2096. {
  2097. ATLASSERT(m_hDC != NULL);
  2098. return ::BeginPath(m_hDC);
  2099. }
  2100. BOOL CloseFigure()
  2101. {
  2102. ATLASSERT(m_hDC != NULL);
  2103. return ::CloseFigure(m_hDC);
  2104. }
  2105. BOOL EndPath()
  2106. {
  2107. ATLASSERT(m_hDC != NULL);
  2108. return ::EndPath(m_hDC);
  2109. }
  2110. BOOL FillPath()
  2111. {
  2112. ATLASSERT(m_hDC != NULL);
  2113. return ::FillPath(m_hDC);
  2114. }
  2115. BOOL FlattenPath()
  2116. {
  2117. ATLASSERT(m_hDC != NULL);
  2118. return ::FlattenPath(m_hDC);
  2119. }
  2120. BOOL StrokeAndFillPath()
  2121. {
  2122. ATLASSERT(m_hDC != NULL);
  2123. return ::StrokeAndFillPath(m_hDC);
  2124. }
  2125. BOOL StrokePath()
  2126. {
  2127. ATLASSERT(m_hDC != NULL);
  2128. return ::StrokePath(m_hDC);
  2129. }
  2130. BOOL WidenPath()
  2131. {
  2132. ATLASSERT(m_hDC != NULL);
  2133. return ::WidenPath(m_hDC);
  2134. }
  2135. BOOL GetMiterLimit(PFLOAT pfMiterLimit) const
  2136. {
  2137. ATLASSERT(m_hDC != NULL);
  2138. return ::GetMiterLimit(m_hDC, pfMiterLimit);
  2139. }
  2140. BOOL SetMiterLimit(float fMiterLimit)
  2141. {
  2142. ATLASSERT(m_hDC != NULL);
  2143. return ::SetMiterLimit(m_hDC, fMiterLimit, NULL);
  2144. }
  2145. int GetPath(LPPOINT lpPoints, LPBYTE lpTypes, int nCount) const
  2146. {
  2147. ATLASSERT(m_hDC != NULL);
  2148. return ::GetPath(m_hDC, lpPoints, lpTypes, nCount);
  2149. }
  2150. BOOL SelectClipPath(int nMode)
  2151. {
  2152. ATLASSERT(m_hDC != NULL);
  2153. return ::SelectClipPath(m_hDC, nMode);
  2154. }
  2155. // Misc Helper Functions
  2156. static CBrushHandle PASCAL GetHalftoneBrush()
  2157. {
  2158. HBRUSH halftoneBrush = NULL;
  2159. WORD grayPattern[8];
  2160. for(int i = 0; i < 8; i++)
  2161. grayPattern[i] = (WORD)(0x5555 << (i & 1));
  2162. HBITMAP grayBitmap = CreateBitmap(8, 8, 1, 1, &grayPattern);
  2163. if(grayBitmap != NULL)
  2164. {
  2165. halftoneBrush = ::CreatePatternBrush(grayBitmap);
  2166. DeleteObject(grayBitmap);
  2167. }
  2168. return CBrushHandle(halftoneBrush);
  2169. }
  2170. void DrawDragRect(LPCRECT lpRect, SIZE size, LPCRECT lpRectLast, SIZE sizeLast, HBRUSH hBrush = NULL, HBRUSH hBrushLast = NULL)
  2171. {
  2172. // first, determine the update region and select it
  2173. HRGN hRgnNew;
  2174. HRGN hRgnOutside, hRgnInside;
  2175. hRgnOutside = ::CreateRectRgnIndirect(lpRect);
  2176. RECT rect = *lpRect;
  2177. ::InflateRect(&rect, -size.cx, -size.cy);
  2178. ::IntersectRect(&rect, &rect, lpRect);
  2179. hRgnInside = ::CreateRectRgnIndirect(&rect);
  2180. hRgnNew = ::CreateRectRgn(0, 0, 0, 0);
  2181. ::CombineRgn(hRgnNew, hRgnOutside, hRgnInside, RGN_XOR);
  2182. HBRUSH hBrushOld = NULL;
  2183. if(hBrush == NULL)
  2184. hBrush = CDCHandle::GetHalftoneBrush();
  2185. if(hBrushLast == NULL)
  2186. hBrushLast = hBrush;
  2187. HRGN hRgnLast = NULL, hRgnUpdate = NULL;
  2188. if(lpRectLast != NULL)
  2189. {
  2190. // find difference between new region and old region
  2191. hRgnLast = ::CreateRectRgn(0, 0, 0, 0);
  2192. ::SetRectRgn(hRgnOutside, lpRectLast->left, lpRectLast->top, lpRectLast->right, lpRectLast->bottom);
  2193. rect = *lpRectLast;
  2194. ::InflateRect(&rect, -sizeLast.cx, -sizeLast.cy);
  2195. ::IntersectRect(&rect, &rect, lpRectLast);
  2196. ::SetRectRgn(hRgnInside, rect.left, rect.top, rect.right, rect.bottom);
  2197. ::CombineRgn(hRgnLast, hRgnOutside, hRgnInside, RGN_XOR);
  2198. // only diff them if brushes are the same
  2199. if(hBrush == hBrushLast)
  2200. {
  2201. hRgnUpdate = ::CreateRectRgn(0, 0, 0, 0);
  2202. ::CombineRgn(hRgnUpdate, hRgnLast, hRgnNew, RGN_XOR);
  2203. }
  2204. }
  2205. if(hBrush != hBrushLast && lpRectLast != NULL)
  2206. {
  2207. // brushes are different -- erase old region first
  2208. SelectClipRgn(hRgnLast);
  2209. GetClipBox(&rect);
  2210. hBrushOld = SelectBrush(hBrushLast);
  2211. PatBlt(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, PATINVERT);
  2212. SelectBrush(hBrushOld);
  2213. hBrushOld = NULL;
  2214. }
  2215. // draw into the update/new region
  2216. SelectClipRgn(hRgnUpdate != NULL ? hRgnUpdate : hRgnNew);
  2217. GetClipBox(&rect);
  2218. hBrushOld = SelectBrush(hBrush);
  2219. PatBlt(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, PATINVERT);
  2220. // cleanup DC
  2221. if(hBrushOld != NULL)
  2222. SelectBrush(hBrushOld);
  2223. SelectClipRgn(NULL);
  2224. }
  2225. void FillSolidRect(LPCRECT lpRect, COLORREF clr)
  2226. {
  2227. ATLASSERT(m_hDC != NULL);
  2228. ::SetBkColor(m_hDC, clr);
  2229. ::ExtTextOut(m_hDC, 0, 0, ETO_OPAQUE, lpRect, NULL, 0, NULL);
  2230. }
  2231. void FillSolidRect(int x, int y, int cx, int cy, COLORREF clr)
  2232. {
  2233. ATLASSERT(m_hDC != NULL);
  2234. ::SetBkColor(m_hDC, clr);
  2235. RECT rect = { x, y, x + cx, y + cy };
  2236. ::ExtTextOut(m_hDC, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
  2237. }
  2238. void Draw3dRect(LPCRECT lpRect, COLORREF clrTopLeft, COLORREF clrBottomRight)
  2239. {
  2240. Draw3dRect(lpRect->left, lpRect->top, lpRect->right - lpRect->left,
  2241. lpRect->bottom - lpRect->top, clrTopLeft, clrBottomRight);
  2242. }
  2243. void Draw3dRect(int x, int y, int cx, int cy, COLORREF clrTopLeft, COLORREF clrBottomRight)
  2244. {
  2245. FillSolidRect(x, y, cx - 1, 1, clrTopLeft);
  2246. FillSolidRect(x, y, 1, cy - 1, clrTopLeft);
  2247. FillSolidRect(x + cx, y, -1, cy, clrBottomRight);
  2248. FillSolidRect(x, y + cy, cx, -1, clrBottomRight);
  2249. }
  2250. // DIB support
  2251. 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)
  2252. {
  2253. ATLASSERT(m_hDC != NULL);
  2254. return ::SetDIBitsToDevice(m_hDC, x, y, dwWidth, dwHeight, xSrc, ySrc, uStartScan, cScanLines, lpvBits, lpbmi, uColorUse);
  2255. }
  2256. 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)
  2257. {
  2258. ATLASSERT(m_hDC != NULL);
  2259. return ::StretchDIBits(m_hDC, x, y, nWidth, nHeight, xSrc, ySrc, nSrcWidth, nSrcHeight, lpvBits, lpbmi, uColorUse, dwRop);
  2260. }
  2261. UINT GetDIBColorTable(UINT uStartIndex, UINT cEntries, RGBQUAD* pColors) const
  2262. {
  2263. ATLASSERT(m_hDC != NULL);
  2264. return ::GetDIBColorTable(m_hDC, uStartIndex, cEntries, pColors);
  2265. }
  2266. UINT SetDIBColorTable(UINT uStartIndex, UINT cEntries, CONST RGBQUAD* pColors)
  2267. {
  2268. ATLASSERT(m_hDC != NULL);
  2269. return ::SetDIBColorTable(m_hDC, uStartIndex, cEntries, pColors);
  2270. }
  2271. // OpenGL support
  2272. #ifndef _ATL_NO_OPENGL
  2273. int ChoosePixelFormat(CONST PIXELFORMATDESCRIPTOR* ppfd)
  2274. {
  2275. ATLASSERT(m_hDC != NULL);
  2276. return ::ChoosePixelFormat(m_hDC, ppfd);
  2277. }
  2278. int DescribePixelFormat(int iPixelFormat, UINT nBytes, LPPIXELFORMATDESCRIPTOR ppfd)
  2279. {
  2280. ATLASSERT(m_hDC != NULL);
  2281. return ::DescribePixelFormat(m_hDC, iPixelFormat, nBytes, ppfd);
  2282. }
  2283. int GetPixelFormat() const
  2284. {
  2285. ATLASSERT(m_hDC != NULL);
  2286. return ::GetPixelFormat(m_hDC);
  2287. }
  2288. BOOL SetPixelFormat(int iPixelFormat, CONST PIXELFORMATDESCRIPTOR* ppfd)
  2289. {
  2290. ATLASSERT(m_hDC != NULL);
  2291. return ::SetPixelFormat(m_hDC, iPixelFormat, ppfd);
  2292. }
  2293. BOOL SwapBuffers()
  2294. {
  2295. ATLASSERT(m_hDC != NULL);
  2296. return ::SwapBuffers(m_hDC);
  2297. }
  2298. HGLRC wglCreateContext()
  2299. {
  2300. ATLASSERT(m_hDC != NULL);
  2301. return ::wglCreateContext(m_hDC);
  2302. }
  2303. HGLRC wglCreateLayerContext(int iLayerPlane)
  2304. {
  2305. ATLASSERT(m_hDC != NULL);
  2306. return ::wglCreateLayerContext(m_hDC, iLayerPlane);
  2307. }
  2308. BOOL wglMakeCurrent(HGLRC hglrc)
  2309. {
  2310. ATLASSERT(m_hDC != NULL);
  2311. return ::wglMakeCurrent(m_hDC, hglrc);
  2312. }
  2313. BOOL wglUseFontBitmaps(DWORD dwFirst, DWORD dwCount, DWORD listBase)
  2314. {
  2315. ATLASSERT(m_hDC != NULL);
  2316. return ::wglUseFontBitmaps(m_hDC, dwFirst, dwCount, listBase);
  2317. }
  2318. BOOL wglUseFontOutlines(DWORD dwFirst, DWORD dwCount, DWORD listBase, FLOAT deviation, FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT lpgmf)
  2319. {
  2320. ATLASSERT(m_hDC != NULL);
  2321. return ::wglUseFontOutlines(m_hDC, dwFirst, dwCount, listBase, deviation, extrusion, format, lpgmf);
  2322. }
  2323. BOOL wglDescribeLayerPlane(int iPixelFormat, int iLayerPlane, UINT nBytes, LPLAYERPLANEDESCRIPTOR plpd)
  2324. {
  2325. ATLASSERT(m_hDC != NULL);
  2326. return ::wglDescribeLayerPlane(m_hDC, iPixelFormat, iLayerPlane, nBytes, plpd);
  2327. }
  2328. int wglSetLayerPaletteEntries(int iLayerPlane, int iStart, int cEntries, CONST COLORREF* pclr)
  2329. {
  2330. ATLASSERT(m_hDC != NULL);
  2331. return ::wglSetLayerPaletteEntries(m_hDC, iLayerPlane, iStart, cEntries, pclr);
  2332. }
  2333. int wglGetLayerPaletteEntries(int iLayerPlane, int iStart, int cEntries, COLORREF* pclr)
  2334. {
  2335. ATLASSERT(m_hDC != NULL);
  2336. return ::wglGetLayerPaletteEntries(m_hDC, iLayerPlane, iStart, cEntries, pclr);
  2337. }
  2338. BOOL wglRealizeLayerPalette(int iLayerPlane, BOOL bRealize)
  2339. {
  2340. ATLASSERT(m_hDC != NULL);
  2341. return ::wglRealizeLayerPalette(m_hDC, iLayerPlane, bRealize);
  2342. }
  2343. BOOL wglSwapLayerBuffers(UINT uPlanes)
  2344. {
  2345. ATLASSERT(m_hDC != NULL);
  2346. return ::wglSwapLayerBuffers(m_hDC, uPlanes);
  2347. }
  2348. #endif //!_ATL_NO_OPENGL
  2349. // New for Windows 2000 only
  2350. #if (_WIN32_WINNT >= 0x0500)
  2351. COLORREF GetDCPenColor() const
  2352. {
  2353. ATLASSERT(m_hDC != NULL);
  2354. return ::GetDCPenColor(m_hDC);
  2355. }
  2356. COLORREF SetDCPenColor(COLORREF clr)
  2357. {
  2358. ATLASSERT(m_hDC != NULL);
  2359. return ::SetDCPenColor(m_hDC, clr);
  2360. }
  2361. COLORREF GetDCBrushColor() const
  2362. {
  2363. ATLASSERT(m_hDC != NULL);
  2364. return ::GetDCBrushColor(m_hDC);
  2365. }
  2366. COLORREF SetDCBrushColor(COLORREF clr)
  2367. {
  2368. ATLASSERT(m_hDC != NULL);
  2369. return ::SetDCBrushColor(m_hDC, clr);
  2370. }
  2371. DWORD GetFontUnicodeRanges(LPGLYPHSET lpgs) const
  2372. {
  2373. ATLASSERT(m_hDC != NULL);
  2374. return ::GetFontUnicodeRanges(m_hDC, lpgs);
  2375. }
  2376. DWORD GetGlyphIndices(LPCTSTR lpstr, int cch, LPWORD pgi, DWORD dwFlags) const
  2377. {
  2378. ATLASSERT(m_hDC != NULL);
  2379. return ::GetGlyphIndices(m_hDC, lpstr, cch, pgi, dwFlags);
  2380. }
  2381. BOOL GetTextExtentPointI(LPWORD pgiIn, int cgi, LPSIZE lpSize) const
  2382. {
  2383. ATLASSERT(m_hDC != NULL);
  2384. return ::GetTextExtentPointI(m_hDC, pgiIn, cgi, lpSize);
  2385. }
  2386. BOOL GetTextExtentExPointI(LPWORD pgiIn, int cgi, int nMaxExtent, LPINT lpnFit, LPINT alpDx, LPSIZE lpSize) const
  2387. {
  2388. ATLASSERT(m_hDC != NULL);
  2389. return ::GetTextExtentExPointI(m_hDC, pgiIn, cgi, nMaxExtent, lpnFit, alpDx, lpSize);
  2390. }
  2391. BOOL GetCharWidthI(UINT giFirst, UINT cgi, LPWORD pgi, LPINT lpBuffer) const
  2392. {
  2393. ATLASSERT(m_hDC != NULL);
  2394. return ::GetCharWidthI(m_hDC, giFirst, cgi, pgi, lpBuffer);
  2395. }
  2396. BOOL GetCharABCWidthsI(UINT giFirst, UINT cgi, LPWORD pgi, LPABC lpabc) const
  2397. {
  2398. ATLASSERT(m_hDC != NULL);
  2399. return ::GetCharABCWidthsI(m_hDC, giFirst, cgi, pgi, lpabc);
  2400. }
  2401. #endif //(_WIN32_WINNT >= 0x0500)
  2402. // New for Windows 2000 and Windows 98
  2403. #if (WINVER >= 0x0500)
  2404. BOOL ColorCorrectPalette(HPALETTE hPalette, DWORD dwFirstEntry, DWORD dwNumOfEntries)
  2405. {
  2406. ATLASSERT(m_hDC != NULL);
  2407. return ::ColorCorrectPalette(m_hDC, hPalette, dwFirstEntry, dwNumOfEntries);
  2408. }
  2409. #endif //(WINVER >= 0x0500)
  2410. };
  2411. /////////////////////////////////////////////////////////////////////////////
  2412. // CDC Helpers
  2413. class CPaintDC : public CDC
  2414. {
  2415. public:
  2416. // Data members
  2417. HWND m_hWnd;
  2418. PAINTSTRUCT m_ps;
  2419. // Constructor/destructor
  2420. CPaintDC(HWND hWnd)
  2421. {
  2422. ATLASSERT(::IsWindow(hWnd));
  2423. m_hWnd = hWnd;
  2424. m_hDC = ::BeginPaint(hWnd, &m_ps);
  2425. }
  2426. ~CPaintDC()
  2427. {
  2428. ATLASSERT(m_hDC != NULL);
  2429. ATLASSERT(::IsWindow(m_hWnd));
  2430. ::EndPaint(m_hWnd, &m_ps);
  2431. Detach();
  2432. }
  2433. };
  2434. class CClientDC : public CDC
  2435. {
  2436. public:
  2437. // Data members
  2438. HWND m_hWnd;
  2439. // Constructor/destructor
  2440. CClientDC(HWND hWnd)
  2441. {
  2442. ATLASSERT(hWnd == NULL || ::IsWindow(hWnd));
  2443. m_hWnd = hWnd;
  2444. m_hDC = ::GetDC(hWnd);
  2445. }
  2446. ~CClientDC()
  2447. {
  2448. ATLASSERT(m_hDC != NULL);
  2449. ::ReleaseDC(m_hWnd, Detach());
  2450. }
  2451. };
  2452. class CWindowDC : public CDC
  2453. {
  2454. public:
  2455. // Data members
  2456. HWND m_hWnd;
  2457. // Constructor/destructor
  2458. CWindowDC(HWND hWnd)
  2459. {
  2460. ATLASSERT(hWnd == NULL || ::IsWindow(hWnd));
  2461. m_hWnd = hWnd;
  2462. m_hDC = ::GetWindowDC(hWnd);
  2463. }
  2464. ~CWindowDC()
  2465. {
  2466. ATLASSERT(m_hDC != NULL);
  2467. ::ReleaseDC(m_hWnd, Detach());
  2468. }
  2469. };
  2470. /////////////////////////////////////////////////////////////////////////////
  2471. // Enhanced metafile support
  2472. class CEnhMetaFileInfo
  2473. {
  2474. public:
  2475. // Data members
  2476. HENHMETAFILE m_hEMF;
  2477. BYTE* m_pBits;
  2478. TCHAR* m_pDesc;
  2479. ENHMETAHEADER m_header;
  2480. PIXELFORMATDESCRIPTOR m_pfd;
  2481. // Constructor/destructor
  2482. CEnhMetaFileInfo(HENHMETAFILE hEMF) : m_pBits(NULL), m_pDesc(NULL), m_hEMF(hEMF)
  2483. { }
  2484. ~CEnhMetaFileInfo()
  2485. {
  2486. delete [] m_pBits;
  2487. delete [] m_pDesc;
  2488. }
  2489. // Operations
  2490. BYTE* GetEnhMetaFileBits()
  2491. {
  2492. ATLASSERT(m_hEMF != NULL);
  2493. UINT nBytes = ::GetEnhMetaFileBits(m_hEMF, 0, NULL);
  2494. delete [] m_pBits;
  2495. m_pBits = NULL;
  2496. ATLTRY(m_pBits = new BYTE[nBytes]);
  2497. if (m_pBits != NULL)
  2498. ::GetEnhMetaFileBits(m_hEMF, nBytes, m_pBits);
  2499. return m_pBits;
  2500. }
  2501. LPTSTR GetEnhMetaFileDescription()
  2502. {
  2503. ATLASSERT(m_hEMF != NULL);
  2504. UINT nLen = ::GetEnhMetaFileDescription(m_hEMF, 0, NULL);
  2505. delete [] m_pDesc;
  2506. m_pDesc = NULL;
  2507. ATLTRY(m_pDesc = new TCHAR[nLen]);
  2508. if (m_pDesc != NULL)
  2509. nLen = ::GetEnhMetaFileDescription(m_hEMF, nLen, m_pDesc);
  2510. return m_pDesc;
  2511. }
  2512. ENHMETAHEADER* GetEnhMetaFileHeader()
  2513. {
  2514. ATLASSERT(m_hEMF != NULL);
  2515. memset(&m_header, 0, sizeof(m_header));
  2516. m_header.iType = EMR_HEADER;
  2517. m_header.nSize = sizeof(ENHMETAHEADER);
  2518. UINT n = ::GetEnhMetaFileHeader(m_hEMF, sizeof(ENHMETAHEADER), &m_header);
  2519. return (n != 0) ? &m_header : NULL;
  2520. }
  2521. PIXELFORMATDESCRIPTOR* GetEnhMetaFilePixelFormat()
  2522. {
  2523. ATLASSERT(m_hEMF != NULL);
  2524. memset(&m_pfd, 0, sizeof(m_pfd));
  2525. UINT n = ::GetEnhMetaFilePixelFormat(m_hEMF, sizeof(m_pfd), &m_pfd);
  2526. return (n != 0) ? &m_pfd : NULL;
  2527. }
  2528. };
  2529. typedef CEnhMetaFileT<false> CEnhMetaFileHandle;
  2530. typedef CEnhMetaFileT<true> CEnhMetaFile;
  2531. template <bool t_bManaged>
  2532. class CEnhMetaFileT
  2533. {
  2534. public:
  2535. // Data members
  2536. HENHMETAFILE m_hEMF;
  2537. // Constructor/destructor
  2538. CEnhMetaFileT(HENHMETAFILE hEMF = NULL) : m_hEMF(hEMF)
  2539. {
  2540. }
  2541. ~CEnhMetaFileT()
  2542. {
  2543. if(t_bManaged && m_hEMF != NULL)
  2544. DeleteObject();
  2545. }
  2546. // Operations
  2547. CEnhMetaFileT<t_bManaged>& operator=(HENHMETAFILE hEMF)
  2548. {
  2549. Attach(hEMF);
  2550. return *this;
  2551. }
  2552. void Attach(HENHMETAFILE hEMF)
  2553. {
  2554. if(t_bManaged && m_hEMF != NULL)
  2555. DeleteObject();
  2556. m_hEMF = hEMF;
  2557. }
  2558. HENHMETAFILE Detach()
  2559. {
  2560. HENHMETAFILE hEMF = m_hEMF;
  2561. m_hEMF = NULL;
  2562. return hEMF;
  2563. }
  2564. operator HENHMETAFILE() const { return m_hEMF; }
  2565. bool IsNull() const { return (m_hEMF == NULL); }
  2566. BOOL DeleteObject()
  2567. {
  2568. ATLASSERT(m_hEMF != NULL);
  2569. BOOL bRet = ::DeleteEnhMetaFile(m_hEMF);
  2570. m_hEMF = NULL;
  2571. return bRet;
  2572. }
  2573. UINT GetEnhMetaFileBits(UINT cbBuffer, LPBYTE lpbBuffer) const
  2574. {
  2575. ATLASSERT(m_hEMF != NULL);
  2576. return ::GetEnhMetaFileBits(m_hEMF, cbBuffer, lpbBuffer);
  2577. }
  2578. UINT GetEnhMetaFileDescription(UINT cchBuffer, LPTSTR lpszDescription) const
  2579. {
  2580. ATLASSERT(m_hEMF != NULL);
  2581. return ::GetEnhMetaFileDescription(m_hEMF, cchBuffer, lpszDescription);
  2582. }
  2583. UINT GetEnhMetaFileHeader(LPENHMETAHEADER lpemh) const
  2584. {
  2585. ATLASSERT(m_hEMF != NULL);
  2586. lpemh->iType = EMR_HEADER;
  2587. lpemh->nSize = sizeof(ENHMETAHEADER);
  2588. return ::GetEnhMetaFileHeader(m_hEMF, sizeof(ENHMETAHEADER), lpemh);
  2589. }
  2590. UINT GetEnhMetaFilePaletteEntries(UINT cEntries, LPPALETTEENTRY lppe) const
  2591. {
  2592. ATLASSERT(m_hEMF != NULL);
  2593. return ::GetEnhMetaFilePaletteEntries(m_hEMF, cEntries, lppe);
  2594. }
  2595. UINT GetEnhMetaFilePixelFormat(DWORD cbBuffer, PIXELFORMATDESCRIPTOR* ppfd) const
  2596. {
  2597. ATLASSERT(m_hEMF != NULL);
  2598. return ::GetEnhMetaFilePixelFormat(m_hEMF, cbBuffer, ppfd);
  2599. }
  2600. };
  2601. class CEnhMetaFileDC : public CDC
  2602. {
  2603. public:
  2604. // Constructor/destructor
  2605. CEnhMetaFileDC()
  2606. {
  2607. }
  2608. CEnhMetaFileDC(HDC hdc, LPCRECT lpRect)
  2609. {
  2610. Create(hdc, NULL, lpRect, NULL);
  2611. ATLASSERT(m_hDC != NULL);
  2612. }
  2613. CEnhMetaFileDC(HDC hdcRef, LPCTSTR lpFilename, LPCRECT lpRect, LPCTSTR lpDescription)
  2614. {
  2615. Create(hdcRef, lpFilename, lpRect, lpDescription);
  2616. ATLASSERT(m_hDC != NULL);
  2617. }
  2618. ~CEnhMetaFileDC()
  2619. {
  2620. HENHMETAFILE hEMF = Close();
  2621. if (hEMF != NULL)
  2622. ::DeleteEnhMetaFile(hEMF);
  2623. }
  2624. // Operations
  2625. void Create(HDC hdcRef, LPCTSTR lpFilename, LPCRECT lpRect, LPCTSTR lpDescription)
  2626. {
  2627. ATLASSERT(m_hDC == NULL);
  2628. m_hDC = ::CreateEnhMetaFile(hdcRef, lpFilename, lpRect, lpDescription);
  2629. }
  2630. HENHMETAFILE Close()
  2631. {
  2632. HENHMETAFILE hEMF = NULL;
  2633. if (m_hDC != NULL)
  2634. {
  2635. hEMF = ::CloseEnhMetaFile(m_hDC);
  2636. m_hDC = NULL;
  2637. }
  2638. return hEMF;
  2639. }
  2640. };
  2641. }; //namespace WTL
  2642. #endif // __ATLGDI_H__