atlgdi.h 83 KB

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