wingdi.cpp 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378
  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10. #include "stdafx.h"
  11. #ifdef AFX_CORE2_SEG
  12. #pragma code_seg(AFX_CORE2_SEG)
  13. #endif
  14. #ifdef _DEBUG
  15. #undef THIS_FILE
  16. static char THIS_FILE[] = __FILE__;
  17. #endif
  18. /////////////////////////////////////////////////////////////////////////////
  19. // Diagnostic Output
  20. #ifdef _DEBUG
  21. CDumpContext& AFXAPI operator<<(CDumpContext& dc, SIZE size)
  22. {
  23. return dc << "(" << size.cx << " x " << size.cy << ")";
  24. }
  25. CDumpContext& AFXAPI operator<<(CDumpContext& dc, POINT point)
  26. {
  27. return dc << "(" << point.x << ", " << point.y << ")";
  28. }
  29. CDumpContext& AFXAPI operator<<(CDumpContext& dc, const RECT& rect)
  30. {
  31. return dc << "(L " << rect.left << ", T " << rect.top << ", R " <<
  32. rect.right << ", B " << rect.bottom << ")";
  33. }
  34. #endif //_DEBUG
  35. /////////////////////////////////////////////////////////////////////////////
  36. // CDC
  37. CDC::CDC()
  38. {
  39. m_hDC = NULL;
  40. m_hAttribDC = NULL;
  41. m_bPrinting = FALSE;
  42. }
  43. #ifdef _DEBUG
  44. void CDC::AssertValid() const
  45. {
  46. CObject::AssertValid();
  47. }
  48. void CDC::Dump(CDumpContext& dc) const
  49. {
  50. CObject::Dump(dc);
  51. dc << "m_hDC = " << (UINT)m_hDC;
  52. dc << "\nm_hAttribDC = " << (UINT)m_hAttribDC;
  53. dc << "\nm_bPrinting = " << m_bPrinting;
  54. dc << "\n";
  55. }
  56. #endif //_DEBUG
  57. #include "fixalloc.h"
  58. class CTempDC : public CDC
  59. {
  60. DECLARE_DYNCREATE(CTempDC)
  61. DECLARE_FIXED_ALLOC(CTempDC);
  62. };
  63. CHandleMap* PASCAL afxMapHDC(BOOL bCreate)
  64. {
  65. AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
  66. if (pState->m_pmapHDC == NULL && bCreate)
  67. {
  68. BOOL bEnable = AfxEnableMemoryTracking(FALSE);
  69. #ifndef _AFX_PORTABLE
  70. _PNH pnhOldHandler = AfxSetNewHandler(&AfxCriticalNewHandler);
  71. #endif
  72. pState->m_pmapHDC = new CHandleMap(RUNTIME_CLASS(CTempDC),
  73. offsetof(CDC, m_hDC), 2);
  74. #ifndef _AFX_PORTABLE
  75. AfxSetNewHandler(pnhOldHandler);
  76. #endif
  77. AfxEnableMemoryTracking(bEnable);
  78. }
  79. return pState->m_pmapHDC;
  80. }
  81. CDC* PASCAL CDC::FromHandle(HDC hDC)
  82. {
  83. CHandleMap* pMap = afxMapHDC(TRUE); //create map if not exist
  84. ASSERT(pMap != NULL);
  85. CDC* pDC = (CDC*)pMap->FromHandle(hDC);
  86. ASSERT(pDC == NULL || pDC->m_hDC == hDC);
  87. return pDC;
  88. }
  89. BOOL CDC::Attach(HDC hDC)
  90. {
  91. ASSERT(m_hDC == NULL); // only attach once, detach on destroy
  92. ASSERT(m_hAttribDC == NULL); // only attach to an empty DC
  93. if (hDC == NULL)
  94. return FALSE;
  95. CHandleMap* pMap = afxMapHDC(TRUE); // create map if not exist
  96. ASSERT(pMap != NULL);
  97. pMap->SetPermanent(m_hDC = hDC, this);
  98. SetAttribDC(m_hDC); // Default to same as output
  99. return TRUE;
  100. }
  101. HDC CDC::Detach()
  102. {
  103. HDC hDC = m_hDC;
  104. if (hDC != NULL)
  105. {
  106. CHandleMap* pMap = afxMapHDC(); // don't create if not exist
  107. if (pMap != NULL)
  108. pMap->RemoveHandle(m_hDC);
  109. }
  110. ReleaseAttribDC();
  111. m_hDC = NULL;
  112. return hDC;
  113. }
  114. BOOL CDC::DeleteDC()
  115. {
  116. if (m_hDC == NULL)
  117. return FALSE;
  118. return ::DeleteDC(Detach());
  119. }
  120. CDC::~CDC()
  121. {
  122. if (m_hDC != NULL)
  123. ::DeleteDC(Detach());
  124. }
  125. void CDC::SetAttribDC(HDC hDC) // Set the Attribute DC
  126. {
  127. m_hAttribDC = hDC;
  128. }
  129. void CDC::SetOutputDC(HDC hDC) // Set the Output DC
  130. {
  131. #ifdef _DEBUG
  132. CHandleMap* pMap = afxMapHDC();
  133. if (pMap != NULL && pMap->LookupPermanent(m_hDC) == this)
  134. {
  135. TRACE0("Cannot Set Output hDC on Attached CDC.\n");
  136. ASSERT(FALSE);
  137. }
  138. #endif
  139. m_hDC = hDC;
  140. }
  141. void CDC::ReleaseAttribDC() // Release the Attribute DC
  142. {
  143. m_hAttribDC = NULL;
  144. }
  145. void CDC::ReleaseOutputDC() // Release the Output DC
  146. {
  147. #ifdef _DEBUG
  148. CHandleMap* pMap = afxMapHDC();
  149. if (pMap != NULL && pMap->LookupPermanent(m_hDC) == this)
  150. {
  151. TRACE0("Cannot Release Output hDC on Attached CDC.\n");
  152. ASSERT(FALSE);
  153. }
  154. #endif
  155. m_hDC = NULL;
  156. }
  157. /////////////////////////////////////////////////////////////////////////////
  158. // Out-of-line routines
  159. int CDC::StartDoc(LPCTSTR lpszDocName)
  160. {
  161. DOCINFO di;
  162. memset(&di, 0, sizeof(DOCINFO));
  163. di.cbSize = sizeof(DOCINFO);
  164. di.lpszDocName = lpszDocName;
  165. return StartDoc(&di);
  166. }
  167. int CDC::SaveDC()
  168. {
  169. ASSERT(m_hDC != NULL);
  170. int nRetVal = 0;
  171. if (m_hAttribDC != NULL)
  172. nRetVal = ::SaveDC(m_hAttribDC);
  173. if (m_hDC != m_hAttribDC && ::SaveDC(m_hDC) != 0)
  174. nRetVal = -1; // -1 is the only valid restore value for complex DCs
  175. return nRetVal;
  176. }
  177. BOOL CDC::RestoreDC(int nSavedDC)
  178. {
  179. // if two distinct DCs, nSavedDC can only be -1
  180. ASSERT(m_hDC != NULL);
  181. ASSERT(m_hDC == m_hAttribDC || nSavedDC == -1);
  182. BOOL bRetVal = TRUE;
  183. if (m_hDC != m_hAttribDC)
  184. bRetVal = ::RestoreDC(m_hDC, nSavedDC);
  185. if (m_hAttribDC != NULL)
  186. bRetVal = (bRetVal && ::RestoreDC(m_hAttribDC, nSavedDC));
  187. return bRetVal;
  188. }
  189. CGdiObject* PASCAL CDC::SelectGdiObject(HDC hDC, HGDIOBJ h)
  190. {
  191. return CGdiObject::FromHandle(::SelectObject(hDC, h));
  192. }
  193. CGdiObject* CDC::SelectStockObject(int nIndex)
  194. {
  195. ASSERT(m_hDC != NULL);
  196. HGDIOBJ hObject = ::GetStockObject(nIndex);
  197. HGDIOBJ hOldObj = NULL;
  198. ASSERT(hObject != NULL);
  199. if (m_hDC != m_hAttribDC)
  200. hOldObj = ::SelectObject(m_hDC, hObject);
  201. if (m_hAttribDC != NULL)
  202. hOldObj = ::SelectObject(m_hAttribDC, hObject);
  203. return CGdiObject::FromHandle(hOldObj);
  204. }
  205. CPen* CDC::SelectObject(CPen* pPen)
  206. {
  207. ASSERT(m_hDC != NULL);
  208. HGDIOBJ hOldObj = NULL;
  209. if (m_hDC != m_hAttribDC)
  210. hOldObj = ::SelectObject(m_hDC, pPen->GetSafeHandle());
  211. if (m_hAttribDC != NULL)
  212. hOldObj = ::SelectObject(m_hAttribDC, pPen->GetSafeHandle());
  213. return (CPen*)CGdiObject::FromHandle(hOldObj);
  214. }
  215. CBrush* CDC::SelectObject(CBrush* pBrush)
  216. {
  217. ASSERT(m_hDC != NULL);
  218. HGDIOBJ hOldObj = NULL;
  219. if (m_hDC != m_hAttribDC)
  220. hOldObj = ::SelectObject(m_hDC, pBrush->GetSafeHandle());
  221. if (m_hAttribDC != NULL)
  222. hOldObj = ::SelectObject(m_hAttribDC, pBrush->GetSafeHandle());
  223. return (CBrush*)CGdiObject::FromHandle(hOldObj);
  224. }
  225. CFont* CDC::SelectObject(CFont* pFont)
  226. {
  227. ASSERT(m_hDC != NULL);
  228. HGDIOBJ hOldObj = NULL;
  229. if (m_hDC != m_hAttribDC)
  230. hOldObj = ::SelectObject(m_hDC, pFont->GetSafeHandle());
  231. if (m_hAttribDC != NULL)
  232. hOldObj = ::SelectObject(m_hAttribDC, pFont->GetSafeHandle());
  233. return (CFont*)CGdiObject::FromHandle(hOldObj);
  234. }
  235. int CDC::SelectObject(CRgn* pRgn)
  236. {
  237. ASSERT(m_hDC != NULL);
  238. int nRetVal = GDI_ERROR;
  239. if (m_hDC != m_hAttribDC)
  240. nRetVal = (int)::SelectObject(m_hDC, pRgn->GetSafeHandle());
  241. if (m_hAttribDC != NULL)
  242. nRetVal = (int)::SelectObject(m_hAttribDC, pRgn->GetSafeHandle());
  243. return nRetVal;
  244. }
  245. CPalette* CDC::SelectPalette(CPalette* pPalette, BOOL bForceBackground)
  246. {
  247. ASSERT(m_hDC != NULL);
  248. return (CPalette*) CGdiObject::FromHandle(::SelectPalette(m_hDC,
  249. (HPALETTE)pPalette->GetSafeHandle(), bForceBackground));
  250. }
  251. COLORREF CDC::SetBkColor(COLORREF crColor)
  252. {
  253. ASSERT(m_hDC != NULL);
  254. COLORREF crRetVal = CLR_INVALID;
  255. if (m_hDC != m_hAttribDC)
  256. crRetVal = ::SetBkColor(m_hDC, crColor);
  257. if (m_hAttribDC != NULL)
  258. crRetVal = ::SetBkColor(m_hAttribDC, crColor);
  259. return crRetVal;
  260. }
  261. int CDC::SetBkMode(int nBkMode)
  262. {
  263. ASSERT(m_hDC != NULL);
  264. int nRetVal = 0;
  265. if (m_hDC != m_hAttribDC)
  266. nRetVal = ::SetBkMode(m_hDC, nBkMode);
  267. if (m_hAttribDC != NULL)
  268. nRetVal = ::SetBkMode(m_hAttribDC, nBkMode);
  269. return nRetVal;
  270. }
  271. int CDC::SetPolyFillMode(int nPolyFillMode)
  272. {
  273. ASSERT(m_hDC != NULL);
  274. int nRetVal = 0;
  275. if (m_hDC != m_hAttribDC)
  276. nRetVal = ::SetPolyFillMode(m_hDC, nPolyFillMode);
  277. if (m_hAttribDC != NULL)
  278. nRetVal = ::SetPolyFillMode(m_hAttribDC, nPolyFillMode);
  279. return nRetVal;
  280. }
  281. int CDC::SetROP2(int nDrawMode)
  282. {
  283. ASSERT(m_hDC != NULL);
  284. int nRetVal = 0;
  285. if (m_hDC != m_hAttribDC)
  286. nRetVal = ::SetROP2(m_hDC, nDrawMode);
  287. if (m_hAttribDC != NULL)
  288. nRetVal = ::SetROP2(m_hAttribDC, nDrawMode);
  289. return nRetVal;
  290. }
  291. int CDC::SetStretchBltMode(int nStretchMode)
  292. {
  293. ASSERT(m_hDC != NULL);
  294. int nRetVal = 0;
  295. if (m_hDC != m_hAttribDC)
  296. nRetVal = ::SetStretchBltMode(m_hDC, nStretchMode);
  297. if (m_hAttribDC != NULL)
  298. nRetVal = ::SetStretchBltMode(m_hAttribDC, nStretchMode);
  299. return nRetVal;
  300. }
  301. COLORREF CDC::SetTextColor(COLORREF crColor)
  302. {
  303. ASSERT(m_hDC != NULL);
  304. COLORREF crRetVal = CLR_INVALID;
  305. if (m_hDC != m_hAttribDC)
  306. crRetVal = ::SetTextColor(m_hDC, crColor);
  307. if (m_hAttribDC != NULL)
  308. crRetVal = ::SetTextColor(m_hAttribDC, crColor);
  309. return crRetVal;
  310. }
  311. int CDC::SetMapMode(int nMapMode)
  312. {
  313. ASSERT(m_hDC != NULL);
  314. int nRetVal = 0;
  315. if (m_hDC != m_hAttribDC)
  316. nRetVal = ::SetMapMode(m_hDC, nMapMode);
  317. if (m_hAttribDC != NULL)
  318. nRetVal = ::SetMapMode(m_hAttribDC, nMapMode);
  319. return nRetVal;
  320. }
  321. CPoint CDC::SetViewportOrg(int x, int y)
  322. {
  323. ASSERT(m_hDC != NULL);
  324. CPoint point;
  325. if (m_hDC != m_hAttribDC)
  326. VERIFY(::SetViewportOrgEx(m_hDC, x, y, &point));
  327. if (m_hAttribDC != NULL)
  328. VERIFY(::SetViewportOrgEx(m_hAttribDC, x, y, &point));
  329. return point;
  330. }
  331. CPoint CDC::OffsetViewportOrg(int nWidth, int nHeight)
  332. {
  333. ASSERT(m_hDC != NULL);
  334. CPoint point;
  335. if (m_hDC != m_hAttribDC)
  336. VERIFY(::OffsetViewportOrgEx(m_hDC, nWidth, nHeight, &point));
  337. if (m_hAttribDC != NULL)
  338. VERIFY(::OffsetViewportOrgEx(m_hAttribDC, nWidth, nHeight, &point));
  339. return point;
  340. }
  341. CSize CDC::SetViewportExt(int x, int y)
  342. {
  343. ASSERT(m_hDC != NULL);
  344. CSize size;
  345. if (m_hDC != m_hAttribDC)
  346. VERIFY(::SetViewportExtEx(m_hDC, x, y, &size));
  347. if (m_hAttribDC != NULL)
  348. VERIFY(::SetViewportExtEx(m_hAttribDC, x, y, &size));
  349. return size;
  350. }
  351. CSize CDC::ScaleViewportExt(int xNum, int xDenom, int yNum, int yDenom)
  352. {
  353. ASSERT(m_hDC != NULL);
  354. CSize size;
  355. if (m_hDC != m_hAttribDC)
  356. VERIFY(::ScaleViewportExtEx(m_hDC, xNum, xDenom, yNum, yDenom, &size));
  357. if (m_hAttribDC != NULL)
  358. VERIFY(::ScaleViewportExtEx(m_hAttribDC, xNum, xDenom, yNum, yDenom, &size));
  359. return size;
  360. }
  361. CPoint CDC::SetWindowOrg(int x, int y)
  362. {
  363. ASSERT(m_hDC != NULL);
  364. CPoint point;
  365. if (m_hDC != m_hAttribDC)
  366. VERIFY(::SetWindowOrgEx(m_hDC, x, y, &point));
  367. if (m_hAttribDC != NULL)
  368. VERIFY(::SetWindowOrgEx(m_hAttribDC, x, y, &point));
  369. return point;
  370. }
  371. CPoint CDC::OffsetWindowOrg(int nWidth, int nHeight)
  372. {
  373. ASSERT(m_hDC != NULL);
  374. CPoint point;
  375. if (m_hDC != m_hAttribDC)
  376. VERIFY(::OffsetWindowOrgEx(m_hDC, nWidth, nHeight, &point));
  377. if (m_hAttribDC != NULL)
  378. VERIFY(::OffsetWindowOrgEx(m_hAttribDC, nWidth, nHeight, &point));
  379. return point;
  380. }
  381. CSize CDC::SetWindowExt(int x, int y)
  382. {
  383. ASSERT(m_hDC != NULL);
  384. CSize size;
  385. if (m_hDC != m_hAttribDC)
  386. VERIFY(::SetWindowExtEx(m_hDC, x, y, &size));
  387. if (m_hAttribDC != NULL)
  388. VERIFY(::SetWindowExtEx(m_hAttribDC, x, y, &size));
  389. return size;
  390. }
  391. CSize CDC::ScaleWindowExt(int xNum, int xDenom, int yNum, int yDenom)
  392. {
  393. ASSERT(m_hDC != NULL);
  394. CSize size;
  395. if (m_hDC != m_hAttribDC)
  396. VERIFY(::ScaleWindowExtEx(m_hDC, xNum, xDenom, yNum, yDenom, &size));
  397. if (m_hAttribDC != NULL)
  398. VERIFY(::ScaleWindowExtEx(m_hAttribDC, xNum, xDenom, yNum, yDenom, &size));
  399. return size;
  400. }
  401. int CDC::GetClipBox(LPRECT lpRect) const
  402. {
  403. ASSERT(m_hDC != NULL);
  404. return ::GetClipBox(m_hDC, lpRect);
  405. }
  406. int CDC::SelectClipRgn(CRgn* pRgn)
  407. {
  408. ASSERT(m_hDC != NULL);
  409. int nRetVal = ERROR;
  410. if (m_hDC != m_hAttribDC)
  411. nRetVal = ::SelectClipRgn(m_hDC, (HRGN)pRgn->GetSafeHandle());
  412. if (m_hAttribDC != NULL)
  413. nRetVal = ::SelectClipRgn(m_hAttribDC, (HRGN)pRgn->GetSafeHandle());
  414. return nRetVal;
  415. }
  416. int CDC::ExcludeClipRect(int x1, int y1, int x2, int y2)
  417. {
  418. ASSERT(m_hDC != NULL);
  419. int nRetVal = ERROR;
  420. if (m_hDC != m_hAttribDC)
  421. nRetVal = ::ExcludeClipRect(m_hDC, x1, y1, x2, y2);
  422. if (m_hAttribDC != NULL)
  423. nRetVal = ::ExcludeClipRect(m_hAttribDC, x1, y1, x2, y2);
  424. return nRetVal;
  425. }
  426. int CDC::ExcludeClipRect(LPCRECT lpRect)
  427. {
  428. ASSERT(m_hDC != NULL);
  429. int nRetVal = ERROR;
  430. if (m_hDC != m_hAttribDC)
  431. nRetVal = ::ExcludeClipRect(m_hDC, lpRect->left, lpRect->top,
  432. lpRect->right, lpRect->bottom);
  433. if (m_hAttribDC != NULL)
  434. nRetVal = ::ExcludeClipRect(m_hAttribDC, lpRect->left, lpRect->top,
  435. lpRect->right, lpRect->bottom);
  436. return nRetVal;
  437. }
  438. int CDC::IntersectClipRect(int x1, int y1, int x2, int y2)
  439. {
  440. ASSERT(m_hDC != NULL);
  441. int nRetVal = ERROR;
  442. if (m_hDC != m_hAttribDC)
  443. nRetVal = ::IntersectClipRect(m_hDC, x1, y1, x2, y2);
  444. if (m_hAttribDC != NULL)
  445. nRetVal = ::IntersectClipRect(m_hAttribDC, x1, y1, x2, y2);
  446. return nRetVal;
  447. }
  448. int CDC::IntersectClipRect(LPCRECT lpRect)
  449. {
  450. ASSERT(m_hDC != NULL);
  451. int nRetVal = ERROR;
  452. if (m_hDC != m_hAttribDC)
  453. nRetVal = ::IntersectClipRect(m_hDC, lpRect->left, lpRect->top,
  454. lpRect->right, lpRect->bottom);
  455. if (m_hAttribDC != NULL)
  456. nRetVal = ::IntersectClipRect(m_hAttribDC, lpRect->left, lpRect->top,
  457. lpRect->right, lpRect->bottom);
  458. return nRetVal;
  459. }
  460. int CDC::OffsetClipRgn(int x, int y)
  461. {
  462. ASSERT(m_hDC != NULL);
  463. int nRetVal = ERROR;
  464. if (m_hDC != m_hAttribDC)
  465. nRetVal = ::OffsetClipRgn(m_hDC, x, y);
  466. if (m_hAttribDC != NULL)
  467. nRetVal = ::OffsetClipRgn(m_hAttribDC, x, y);
  468. return nRetVal;
  469. }
  470. int CDC::OffsetClipRgn(SIZE size)
  471. {
  472. ASSERT(m_hDC != NULL);
  473. int nRetVal = ERROR;
  474. if (m_hDC != m_hAttribDC)
  475. nRetVal = ::OffsetClipRgn(m_hDC, size.cx, size.cy);
  476. if (m_hAttribDC != NULL)
  477. nRetVal = ::OffsetClipRgn(m_hAttribDC, size.cx, size.cy);
  478. return nRetVal;
  479. }
  480. CPoint CDC::MoveTo(int x, int y)
  481. {
  482. ASSERT(m_hDC != NULL);
  483. CPoint point;
  484. if (m_hDC != m_hAttribDC)
  485. VERIFY(::MoveToEx(m_hDC, x, y, &point));
  486. if (m_hAttribDC != NULL)
  487. VERIFY(::MoveToEx(m_hAttribDC, x, y, &point));
  488. return point;
  489. }
  490. BOOL CDC::LineTo(int x, int y)
  491. {
  492. ASSERT(m_hDC != NULL);
  493. if (m_hAttribDC != NULL && m_hDC != m_hAttribDC)
  494. ::MoveToEx(m_hAttribDC, x, y, NULL);
  495. return ::LineTo(m_hDC, x, y);
  496. }
  497. UINT CDC::SetTextAlign(UINT nFlags)
  498. {
  499. ASSERT(m_hDC != NULL);
  500. UINT nRetVal = GDI_ERROR;
  501. if (m_hDC != m_hAttribDC)
  502. ::SetTextAlign(m_hDC, nFlags);
  503. if (m_hAttribDC != NULL)
  504. nRetVal = ::SetTextAlign(m_hAttribDC, nFlags);
  505. return nRetVal;
  506. }
  507. int CDC::SetTextJustification(int nBreakExtra, int nBreakCount)
  508. {
  509. ASSERT(m_hDC != NULL);
  510. int nRetVal = 0;
  511. if (m_hDC != m_hAttribDC)
  512. nRetVal = ::SetTextJustification(m_hDC, nBreakExtra, nBreakCount);
  513. if (m_hAttribDC != NULL)
  514. nRetVal = ::SetTextJustification(m_hAttribDC, nBreakExtra, nBreakCount);
  515. return nRetVal;
  516. }
  517. int CDC::SetTextCharacterExtra(int nCharExtra)
  518. {
  519. ASSERT(m_hDC != NULL);
  520. int nRetVal = 0x8000000;
  521. if (m_hDC != m_hAttribDC)
  522. nRetVal = ::SetTextCharacterExtra(m_hDC, nCharExtra);
  523. if (m_hAttribDC != NULL)
  524. nRetVal = ::SetTextCharacterExtra(m_hAttribDC, nCharExtra);
  525. return nRetVal;
  526. }
  527. DWORD CDC::SetMapperFlags(DWORD dwFlag)
  528. {
  529. ASSERT(m_hDC != NULL);
  530. DWORD dwRetVal = GDI_ERROR;
  531. if (m_hDC != m_hAttribDC)
  532. dwRetVal = ::SetMapperFlags(m_hDC, dwFlag);
  533. if (m_hAttribDC != NULL)
  534. dwRetVal = ::SetMapperFlags(m_hAttribDC, dwFlag);
  535. return dwRetVal;
  536. }
  537. typedef DWORD (CALLBACK* AFX_GDIGETLAYOUTPROC)(HDC);
  538. typedef DWORD (CALLBACK* AFX_GDISETLAYOUTPROC)(HDC, DWORD);
  539. DWORD CDC::GetLayout() const
  540. {
  541. ASSERT(m_hDC != NULL);
  542. HINSTANCE hInst = ::GetModuleHandleA("GDI32.DLL");
  543. ASSERT(hInst != NULL);
  544. DWORD dwGetLayout = LAYOUT_LTR;
  545. AFX_GDIGETLAYOUTPROC pfn;
  546. pfn = (AFX_GDIGETLAYOUTPROC) GetProcAddress(hInst, "GetLayout");
  547. // if they API is available, just call it. If it is not
  548. // available, indicate an error.
  549. if (pfn != NULL)
  550. dwGetLayout = (*pfn)(m_hDC);
  551. else
  552. {
  553. dwGetLayout = GDI_ERROR;
  554. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  555. }
  556. return dwGetLayout;
  557. }
  558. DWORD CDC::SetLayout(DWORD dwSetLayout)
  559. {
  560. ASSERT(m_hDC != NULL);
  561. HINSTANCE hInst = ::GetModuleHandleA("GDI32.DLL");
  562. ASSERT(hInst != NULL);
  563. DWORD dwGetLayout = LAYOUT_LTR;
  564. AFX_GDISETLAYOUTPROC pfn;
  565. pfn = (AFX_GDISETLAYOUTPROC) GetProcAddress(hInst, "SetLayout");
  566. // If the API is availalbe, just call it. If it's not available,
  567. // setting anything other than LAYOUT_LTR is an error.
  568. if (pfn != NULL)
  569. dwGetLayout = (*pfn)(m_hDC, dwSetLayout);
  570. else if (dwSetLayout != LAYOUT_LTR)
  571. {
  572. dwGetLayout = GDI_ERROR;
  573. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  574. }
  575. return dwGetLayout;
  576. }
  577. void CWnd::ScreenToClient(LPRECT lpRect) const
  578. {
  579. ASSERT(::IsWindow(m_hWnd));
  580. ::ScreenToClient(m_hWnd, (LPPOINT)lpRect);
  581. ::ScreenToClient(m_hWnd, ((LPPOINT)lpRect)+1);
  582. if (GetExStyle() & WS_EX_LAYOUTRTL)
  583. CRect::SwapLeftRight(lpRect);
  584. }
  585. void CWnd::ClientToScreen(LPRECT lpRect) const
  586. {
  587. ASSERT(::IsWindow(m_hWnd));
  588. ::ClientToScreen(m_hWnd, (LPPOINT)lpRect);
  589. ::ClientToScreen(m_hWnd, ((LPPOINT)lpRect)+1);
  590. if (GetExStyle() & WS_EX_LAYOUTRTL)
  591. CRect::SwapLeftRight(lpRect);
  592. }
  593. /////////////////////////////////////////////////////////////////////////////
  594. // Advanced Win32 GDI functions
  595. BOOL CDC::ArcTo(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4)
  596. {
  597. ASSERT(m_hDC != NULL);
  598. BOOL bResult = ::ArcTo(m_hDC, x1, y1, x2, y2, x3, y3, x4, y4);
  599. if (m_hDC != m_hAttribDC)
  600. {
  601. CPoint pt;
  602. VERIFY(::GetCurrentPositionEx(m_hDC, &pt));
  603. VERIFY(::MoveToEx(m_hAttribDC, pt.x, pt.y, NULL));
  604. }
  605. return bResult;
  606. }
  607. int CDC::SetArcDirection(int nArcDirection)
  608. {
  609. ASSERT(m_hDC != NULL);
  610. int nResult = 0;
  611. if (m_hDC != m_hAttribDC)
  612. nResult = ::SetArcDirection(m_hDC, nArcDirection);
  613. if (m_hAttribDC != NULL)
  614. nResult = ::SetArcDirection(m_hAttribDC, nArcDirection);
  615. return nResult;
  616. }
  617. BOOL CDC::PolyDraw(const POINT* lpPoints, const BYTE* lpTypes, int nCount)
  618. {
  619. ASSERT(m_hDC != NULL);
  620. BOOL bResult = ::PolyDraw(m_hDC, lpPoints, lpTypes, nCount);
  621. if (m_hDC != m_hAttribDC)
  622. {
  623. CPoint pt;
  624. VERIFY(::GetCurrentPositionEx(m_hDC, &pt));
  625. VERIFY(::MoveToEx(m_hAttribDC, pt.x, pt.y, NULL));
  626. }
  627. return bResult;
  628. }
  629. BOOL CDC::PolylineTo(const POINT* lpPoints, int nCount)
  630. {
  631. ASSERT(m_hDC != NULL);
  632. BOOL bResult = ::PolylineTo(m_hDC, lpPoints, nCount);
  633. if (m_hDC != m_hAttribDC)
  634. {
  635. CPoint pt;
  636. VERIFY(::GetCurrentPositionEx(m_hDC, &pt));
  637. VERIFY(::MoveToEx(m_hAttribDC, pt.x, pt.y, NULL));
  638. }
  639. return bResult;
  640. }
  641. BOOL CDC::SetColorAdjustment(const COLORADJUSTMENT* lpColorAdjust)
  642. {
  643. ASSERT(m_hDC != NULL);
  644. BOOL bResult = FALSE;
  645. if (m_hDC != m_hAttribDC)
  646. bResult = ::SetColorAdjustment(m_hDC, lpColorAdjust);
  647. if (m_hAttribDC != NULL)
  648. bResult = ::SetColorAdjustment(m_hAttribDC, lpColorAdjust);
  649. return bResult;
  650. }
  651. BOOL CDC::PolyBezierTo(const POINT* lpPoints, int nCount)
  652. {
  653. ASSERT(m_hDC != NULL);
  654. BOOL bResult = ::PolyBezierTo(m_hDC, lpPoints, nCount);
  655. if (m_hDC != m_hAttribDC)
  656. {
  657. CPoint pt;
  658. VERIFY(::GetCurrentPositionEx(m_hDC, &pt));
  659. VERIFY(::MoveToEx(m_hAttribDC, pt.x, pt.y, NULL));
  660. }
  661. return bResult;
  662. }
  663. BOOL CDC::SelectClipPath(int nMode)
  664. {
  665. ASSERT(m_hDC != NULL);
  666. // output DC always holds the current path
  667. if (!::SelectClipPath(m_hDC, nMode))
  668. return FALSE;
  669. // transfer clipping region into the attribute DC
  670. BOOL bResult = TRUE;
  671. if (m_hDC != m_hAttribDC)
  672. {
  673. HRGN hRgn = ::CreateRectRgn(0, 0, 0, 0);
  674. if (::GetClipRgn(m_hDC, hRgn) < 0 || !::SelectClipRgn(m_hAttribDC, hRgn))
  675. {
  676. TRACE0("Error: unable to transfer clip region in CDC::SelectClipPath!\n");
  677. bResult = FALSE;
  678. }
  679. DeleteObject(hRgn);
  680. }
  681. return bResult;
  682. }
  683. int CDC::SelectClipRgn(CRgn* pRgn, int nMode)
  684. {
  685. ASSERT(m_hDC != NULL);
  686. int nRetVal = ERROR;
  687. if (m_hDC != m_hAttribDC)
  688. nRetVal = ::ExtSelectClipRgn(m_hDC, (HRGN)pRgn->GetSafeHandle(), nMode);
  689. if (m_hAttribDC != NULL)
  690. nRetVal = ::ExtSelectClipRgn(m_hAttribDC, (HRGN)pRgn->GetSafeHandle(), nMode);
  691. return nRetVal;
  692. }
  693. /////////////////////////////////////////////////////////////////////////////
  694. // Special handling for metafile playback
  695. int CALLBACK AfxEnumMetaFileProc(HDC hDC,
  696. HANDLETABLE* pHandleTable, METARECORD* pMetaRec, int nHandles, LPARAM lParam)
  697. {
  698. CDC* pDC = (CDC*)lParam;
  699. ASSERT_VALID(pDC);
  700. switch (pMetaRec->rdFunction)
  701. {
  702. // these records have effects different for each CDC derived class
  703. case META_SETMAPMODE:
  704. pDC->SetMapMode((int)(short)pMetaRec->rdParm[0]);
  705. break;
  706. case META_SETWINDOWEXT:
  707. pDC->SetWindowExt(
  708. (int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]);
  709. break;
  710. case META_SETWINDOWORG:
  711. pDC->SetWindowOrg(
  712. (int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]);
  713. break;
  714. case META_SETVIEWPORTEXT:
  715. pDC->SetViewportExt(
  716. (int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]);
  717. break;
  718. case META_SETVIEWPORTORG:
  719. pDC->SetViewportOrg(
  720. (int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]);
  721. break;
  722. case META_SCALEWINDOWEXT:
  723. pDC->ScaleWindowExt(
  724. (int)(short)pMetaRec->rdParm[3], (int)(short)pMetaRec->rdParm[2],
  725. (int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]);
  726. break;
  727. case META_SCALEVIEWPORTEXT:
  728. pDC->ScaleViewportExt(
  729. (int)(short)pMetaRec->rdParm[3], (int)(short)pMetaRec->rdParm[2],
  730. (int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]);
  731. break;
  732. case META_OFFSETVIEWPORTORG:
  733. pDC->OffsetViewportOrg(
  734. (int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]);
  735. break;
  736. case META_SAVEDC:
  737. pDC->SaveDC();
  738. break;
  739. case META_RESTOREDC:
  740. pDC->RestoreDC((int)(short)pMetaRec->rdParm[0]);
  741. break;
  742. case META_SETBKCOLOR:
  743. pDC->SetBkColor(*(UNALIGNED COLORREF*)&pMetaRec->rdParm[0]);
  744. break;
  745. case META_SETTEXTCOLOR:
  746. pDC->SetTextColor(*(UNALIGNED COLORREF*)&pMetaRec->rdParm[0]);
  747. break;
  748. // need to watch out for SelectObject(HFONT), for custom font mapping
  749. case META_SELECTOBJECT:
  750. {
  751. HGDIOBJ hObject = pHandleTable->objectHandle[pMetaRec->rdParm[0]];
  752. UINT nObjType = GetObjectType(hObject);
  753. if (nObjType == 0)
  754. {
  755. // object type is unknown, determine if it is a font
  756. HFONT hStockFont = (HFONT)::GetStockObject(SYSTEM_FONT);
  757. HFONT hFontOld = (HFONT)::SelectObject(pDC->m_hDC, hStockFont);
  758. HGDIOBJ hObjOld = ::SelectObject(pDC->m_hDC, hObject);
  759. if (hObjOld == hStockFont)
  760. {
  761. // got the stock object back, so must be selecting a font
  762. pDC->SelectObject(CFont::FromHandle((HFONT)hObject));
  763. break; // don't play the default record
  764. }
  765. else
  766. {
  767. // didn't get the stock object back, so restore everything
  768. ::SelectObject(pDC->m_hDC, hFontOld);
  769. ::SelectObject(pDC->m_hDC, hObjOld);
  770. }
  771. // and fall through to PlayMetaFileRecord...
  772. }
  773. else if (nObjType == OBJ_FONT)
  774. {
  775. // play back as CDC::SelectObject(CFont*)
  776. pDC->SelectObject(CFont::FromHandle((HFONT)hObject));
  777. break; // don't play the default record
  778. }
  779. }
  780. // fall through...
  781. default:
  782. ::PlayMetaFileRecord(hDC, pHandleTable, pMetaRec, nHandles);
  783. break;
  784. }
  785. return 1;
  786. }
  787. BOOL CDC::PlayMetaFile(HMETAFILE hMF)
  788. {
  789. if (::GetDeviceCaps(m_hDC, TECHNOLOGY) == DT_METAFILE)
  790. {
  791. // playing metafile in metafile, just use core windows API
  792. return ::PlayMetaFile(m_hDC, hMF);
  793. }
  794. // for special playback, lParam == pDC
  795. return ::EnumMetaFile(m_hDC, hMF, AfxEnumMetaFileProc, (LPARAM)this);
  796. }
  797. /////////////////////////////////////////////////////////////////////////////
  798. // Coordinate transforms
  799. void CDC::LPtoDP(LPSIZE lpSize) const
  800. {
  801. ASSERT(AfxIsValidAddress(lpSize, sizeof(SIZE)));
  802. CSize sizeWinExt = GetWindowExt();
  803. CSize sizeVpExt = GetViewportExt();
  804. lpSize->cx = MulDiv(lpSize->cx, abs(sizeVpExt.cx), abs(sizeWinExt.cx));
  805. lpSize->cy = MulDiv(lpSize->cy, abs(sizeVpExt.cy), abs(sizeWinExt.cy));
  806. }
  807. void CDC::DPtoLP(LPSIZE lpSize) const
  808. {
  809. ASSERT(AfxIsValidAddress(lpSize, sizeof(SIZE)));
  810. CSize sizeWinExt = GetWindowExt();
  811. CSize sizeVpExt = GetViewportExt();
  812. lpSize->cx = MulDiv(lpSize->cx, abs(sizeWinExt.cx), abs(sizeVpExt.cx));
  813. lpSize->cy = MulDiv(lpSize->cy, abs(sizeWinExt.cy), abs(sizeVpExt.cy));
  814. }
  815. /////////////////////////////////////////////////////////////////////////////
  816. // Helper DCs
  817. #ifdef _DEBUG
  818. void CClientDC::AssertValid() const
  819. {
  820. CDC::AssertValid();
  821. ASSERT(m_hWnd == NULL || ::IsWindow(m_hWnd));
  822. }
  823. void CClientDC::Dump(CDumpContext& dc) const
  824. {
  825. CDC::Dump(dc);
  826. dc << "m_hWnd = " << (UINT)m_hWnd;
  827. dc << "\n";
  828. }
  829. #endif
  830. CClientDC::CClientDC(CWnd* pWnd)
  831. {
  832. ASSERT(pWnd == NULL || ::IsWindow(pWnd->m_hWnd));
  833. if (!Attach(::GetDC(m_hWnd = pWnd->GetSafeHwnd())))
  834. AfxThrowResourceException();
  835. }
  836. CClientDC::~CClientDC()
  837. {
  838. ASSERT(m_hDC != NULL);
  839. ::ReleaseDC(m_hWnd, Detach());
  840. }
  841. #ifdef _DEBUG
  842. void CWindowDC::AssertValid() const
  843. {
  844. CDC::AssertValid();
  845. ASSERT(m_hWnd == NULL || ::IsWindow(m_hWnd));
  846. }
  847. void CWindowDC::Dump(CDumpContext& dc) const
  848. {
  849. CDC::Dump(dc);
  850. dc << "m_hWnd = " << (UINT)m_hWnd;
  851. dc << "\n";
  852. }
  853. #endif
  854. CWindowDC::CWindowDC(CWnd* pWnd)
  855. {
  856. ASSERT(pWnd == NULL || ::IsWindow(pWnd->m_hWnd));
  857. if (!Attach(::GetWindowDC(m_hWnd = pWnd->GetSafeHwnd())))
  858. AfxThrowResourceException();
  859. }
  860. CWindowDC::~CWindowDC()
  861. {
  862. ASSERT(m_hDC != NULL);
  863. ::ReleaseDC(m_hWnd, Detach());
  864. }
  865. #ifdef _DEBUG
  866. void CPaintDC::AssertValid() const
  867. {
  868. CDC::AssertValid();
  869. ASSERT(::IsWindow(m_hWnd));
  870. }
  871. void CPaintDC::Dump(CDumpContext& dc) const
  872. {
  873. CDC::Dump(dc);
  874. dc << "m_hWnd = " << (UINT)m_hWnd;
  875. dc << "\nm_ps.hdc = " << (UINT)m_ps.hdc;
  876. dc << "\nm_ps.fErase = " << m_ps.fErase;
  877. dc << "\nm_ps.rcPaint = " << (CRect)m_ps.rcPaint;
  878. dc << "\n";
  879. }
  880. #endif
  881. CPaintDC::CPaintDC(CWnd* pWnd)
  882. {
  883. ASSERT_VALID(pWnd);
  884. ASSERT(::IsWindow(pWnd->m_hWnd));
  885. if (!Attach(::BeginPaint(m_hWnd = pWnd->m_hWnd, &m_ps)))
  886. AfxThrowResourceException();
  887. }
  888. CPaintDC::~CPaintDC()
  889. {
  890. ASSERT(m_hDC != NULL);
  891. ASSERT(::IsWindow(m_hWnd));
  892. ::EndPaint(m_hWnd, &m_ps);
  893. Detach();
  894. }
  895. /////////////////////////////////////////////////////////////////////////////
  896. // CGdiObject
  897. #ifdef _DEBUG
  898. void CGdiObject::Dump(CDumpContext& dc) const
  899. {
  900. CObject::Dump(dc);
  901. dc << "m_hObject = " << (UINT)m_hObject;
  902. dc << "\n";
  903. }
  904. void CGdiObject::AssertValid() const
  905. {
  906. CObject::AssertValid();
  907. ASSERT(m_hObject == NULL ||
  908. (afxData.bWin95 || ::GetObjectType(m_hObject) != 0));
  909. }
  910. #endif
  911. #include "fixalloc.h"
  912. class CTempGdiObject : public CGdiObject
  913. {
  914. DECLARE_DYNCREATE(CTempGdiObject)
  915. DECLARE_FIXED_ALLOC(CTempGdiObject);
  916. };
  917. CHandleMap* PASCAL afxMapHGDIOBJ(BOOL bCreate)
  918. {
  919. AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
  920. if (pState->m_pmapHGDIOBJ == NULL && bCreate)
  921. {
  922. BOOL bEnable = AfxEnableMemoryTracking(FALSE);
  923. #ifndef _AFX_PORTABLE
  924. _PNH pnhOldHandler = AfxSetNewHandler(&AfxCriticalNewHandler);
  925. #endif
  926. pState->m_pmapHGDIOBJ = new CHandleMap(RUNTIME_CLASS(CTempGdiObject),
  927. offsetof(CGdiObject, m_hObject));
  928. #ifndef _AFX_PORTABLE
  929. AfxSetNewHandler(pnhOldHandler);
  930. #endif
  931. AfxEnableMemoryTracking(bEnable);
  932. }
  933. return pState->m_pmapHGDIOBJ;
  934. }
  935. CGdiObject* PASCAL CGdiObject::FromHandle(HGDIOBJ h)
  936. {
  937. CHandleMap* pMap = afxMapHGDIOBJ(TRUE); //create map if not exist
  938. ASSERT(pMap != NULL);
  939. CGdiObject* pObject = (CGdiObject*)pMap->FromHandle(h);
  940. ASSERT(pObject == NULL || pObject->m_hObject == h);
  941. return pObject;
  942. }
  943. BOOL CGdiObject::Attach(HGDIOBJ hObject)
  944. {
  945. ASSERT(m_hObject == NULL); // only attach once, detach on destroy
  946. if (hObject == NULL)
  947. return FALSE;
  948. CHandleMap* pMap = afxMapHGDIOBJ(TRUE); // create map if not exist
  949. ASSERT(pMap != NULL);
  950. pMap->SetPermanent(m_hObject = hObject, this);
  951. return TRUE;
  952. }
  953. HGDIOBJ CGdiObject::Detach()
  954. {
  955. HGDIOBJ hObject = m_hObject;
  956. if (hObject != NULL)
  957. {
  958. CHandleMap* pMap = afxMapHGDIOBJ(); // don't create if not exist
  959. if (pMap != NULL)
  960. pMap->RemoveHandle(m_hObject);
  961. }
  962. m_hObject = NULL;
  963. return hObject;
  964. }
  965. BOOL CGdiObject::DeleteObject()
  966. {
  967. if (m_hObject == NULL)
  968. return FALSE;
  969. return ::DeleteObject(Detach());
  970. }
  971. /////////////////////////////////////////////////////////////////////////////
  972. // Standard GDI objects
  973. /////////////////////////////////////////////////////////////////////////////
  974. // CPen
  975. CPen::CPen(int nPenStyle, int nWidth, COLORREF crColor)
  976. {
  977. if (!Attach(::CreatePen(nPenStyle, nWidth, crColor)))
  978. AfxThrowResourceException();
  979. }
  980. CPen::CPen(int nPenStyle, int nWidth, const LOGBRUSH* pLogBrush,
  981. int nStyleCount, const DWORD* lpStyle)
  982. {
  983. if (!Attach(::ExtCreatePen(nPenStyle, nWidth, pLogBrush, nStyleCount,
  984. lpStyle)))
  985. AfxThrowResourceException();
  986. }
  987. /////////////////////////////////////////////////////////////////////////////
  988. #ifdef _DEBUG
  989. void CPen::Dump(CDumpContext& dc) const
  990. {
  991. CGdiObject::Dump(dc);
  992. if (m_hObject == NULL)
  993. return;
  994. if (!afxData.bWin95 && ::GetObjectType(m_hObject) != OBJ_PEN)
  995. {
  996. // not a valid object
  997. dc << "has ILLEGAL HPEN!";
  998. return;
  999. }
  1000. LOGPEN lp;
  1001. VERIFY(GetObject(sizeof(lp), &lp));
  1002. dc << "lgpn.lopnStyle = " << lp.lopnStyle;
  1003. dc << "\nlgpn.lopnWidth.x (width) = " << lp.lopnWidth.x;
  1004. dc << "\nlgpn.lopnColor = " << (void*)lp.lopnColor;
  1005. dc << "\n";
  1006. }
  1007. #endif
  1008. /////////////////////////////////////////////////////////////////////////////
  1009. // CBrush
  1010. CBrush::CBrush(COLORREF crColor)
  1011. {
  1012. if (!Attach(::CreateSolidBrush(crColor)))
  1013. AfxThrowResourceException();
  1014. }
  1015. CBrush::CBrush(int nIndex, COLORREF crColor)
  1016. {
  1017. if (!Attach(::CreateHatchBrush(nIndex, crColor)))
  1018. AfxThrowResourceException();
  1019. }
  1020. CBrush::CBrush(CBitmap* pBitmap)
  1021. {
  1022. ASSERT_VALID(pBitmap);
  1023. if (!Attach(::CreatePatternBrush((HBITMAP)pBitmap->m_hObject)))
  1024. AfxThrowResourceException();
  1025. }
  1026. BOOL CBrush::CreateDIBPatternBrush(HGLOBAL hPackedDIB, UINT nUsage)
  1027. {
  1028. ASSERT(hPackedDIB != NULL);
  1029. const void* lpPackedDIB = ::GlobalLock(hPackedDIB);
  1030. ASSERT(lpPackedDIB != NULL);
  1031. BOOL bResult = Attach(::CreateDIBPatternBrushPt(lpPackedDIB, nUsage));
  1032. ::GlobalUnlock(hPackedDIB);
  1033. return bResult;
  1034. }
  1035. #ifdef _DEBUG
  1036. void CBrush::Dump(CDumpContext& dc) const
  1037. {
  1038. CGdiObject::Dump(dc);
  1039. if (m_hObject == NULL)
  1040. return;
  1041. if (!afxData.bWin95 && ::GetObjectType(m_hObject) != OBJ_BRUSH)
  1042. {
  1043. // not a valid window
  1044. dc << "has ILLEGAL HBRUSH!";
  1045. return;
  1046. }
  1047. LOGBRUSH lb;
  1048. VERIFY(GetObject(sizeof(lb), &lb));
  1049. dc << "lb.lbStyle = " << lb.lbStyle;
  1050. dc << "\nlb.lbHatch = " << lb.lbHatch;
  1051. dc << "\nlb.lbColor = " << (void*)lb.lbColor;
  1052. dc << "\n";
  1053. }
  1054. #endif
  1055. /////////////////////////////////////////////////////////////////////////////
  1056. #ifdef _DEBUG
  1057. void CFont::Dump(CDumpContext& dc) const
  1058. {
  1059. CGdiObject::Dump(dc);
  1060. if (m_hObject == NULL)
  1061. return;
  1062. if (!afxData.bWin95 && ::GetObjectType(m_hObject) != OBJ_FONT)
  1063. {
  1064. // not a valid GDI object
  1065. dc << "has ILLEGAL HFONT!";
  1066. return;
  1067. }
  1068. LOGFONT lf;
  1069. VERIFY(GetObject(sizeof(lf), &lf));
  1070. dc << "lf.lfHeight = " << lf.lfHeight;
  1071. dc << "\nlf.lfWidth = " << lf.lfWidth;
  1072. dc << "\nlf.lfEscapement = " << lf.lfEscapement;
  1073. dc << "\nlf.lfOrientation = " << lf.lfOrientation;
  1074. dc << "\nlf.lfWeight = " << lf.lfWeight;
  1075. dc << "\nlf.lfItalic = " << (int)lf.lfItalic;
  1076. dc << "\nlf.lfUnderline = " << (int)lf.lfUnderline;
  1077. dc << "\nlf.lfStrikeOut = " << (int)lf.lfStrikeOut;
  1078. dc << "\nlf.lfCharSet = " << (int)lf.lfCharSet;
  1079. dc << "\nlf.lfOutPrecision = " << (int)lf.lfOutPrecision;
  1080. dc << "\nlf.lfClipPrecision = " << (int)lf.lfClipPrecision;
  1081. dc << "\nlf.lfQuality = " << (int)lf.lfQuality;
  1082. dc << "\nlf.lfPitchAndFamily = " << (int)lf.lfPitchAndFamily;
  1083. dc << "\nlf.lfFaceName = " << (LPCTSTR)lf.lfFaceName;
  1084. dc << "\n";
  1085. }
  1086. #endif
  1087. /////////////////////////////////////////////////////////////////////////////
  1088. #ifdef _DEBUG
  1089. void CBitmap::Dump(CDumpContext& dc) const
  1090. {
  1091. CGdiObject::Dump(dc);
  1092. if (m_hObject == NULL)
  1093. return;
  1094. if (!afxData.bWin95 && ::GetObjectType(m_hObject) != OBJ_BITMAP)
  1095. {
  1096. // not a valid object
  1097. dc << "has ILLEGAL HBITMAP!";
  1098. return;
  1099. }
  1100. BITMAP bm;
  1101. VERIFY(GetObject(sizeof(bm), &bm));
  1102. dc << "bm.bmType = " << bm.bmType;
  1103. dc << "\nbm.bmHeight = " << bm.bmHeight;
  1104. dc << "\nbm.bmWidth = " << bm.bmWidth;
  1105. dc << "\nbm.bmWidthBytes = " << bm.bmWidthBytes;
  1106. dc << "\nbm.bmPlanes = " << bm.bmPlanes;
  1107. dc << "\nbm.bmBitsPixel = " << bm.bmBitsPixel;
  1108. dc << "\n";
  1109. }
  1110. #endif
  1111. #ifdef AFX_INIT_SEG
  1112. #pragma code_seg(AFX_INIT_SEG)
  1113. #endif
  1114. IMPLEMENT_DYNAMIC(CResourceException, CException)
  1115. CResourceException _simpleResourceException(FALSE, AFX_IDS_RESOURCE_EXCEPTION);
  1116. IMPLEMENT_DYNAMIC(CUserException, CException)
  1117. CUserException _simpleUserException(FALSE, AFX_IDS_USER_EXCEPTION);
  1118. IMPLEMENT_DYNCREATE(CDC, CObject)
  1119. IMPLEMENT_DYNAMIC(CClientDC, CDC)
  1120. IMPLEMENT_DYNAMIC(CWindowDC, CDC)
  1121. IMPLEMENT_DYNAMIC(CPaintDC, CDC)
  1122. IMPLEMENT_DYNCREATE(CGdiObject, CObject)
  1123. IMPLEMENT_DYNAMIC(CPen, CGdiObject)
  1124. IMPLEMENT_DYNAMIC(CBrush, CGdiObject)
  1125. IMPLEMENT_DYNAMIC(CFont, CGdiObject)
  1126. IMPLEMENT_DYNAMIC(CBitmap, CGdiObject)
  1127. IMPLEMENT_DYNAMIC(CPalette, CGdiObject)
  1128. IMPLEMENT_DYNAMIC(CRgn, CGdiObject)
  1129. IMPLEMENT_DYNCREATE(CTempDC, CDC);
  1130. IMPLEMENT_DYNCREATE(CTempGdiObject, CGdiObject);
  1131. /////////////////////////////////////////////////////////////////////////////
  1132. // Standard exception processing
  1133. #ifdef AFX_CORE2_SEG
  1134. #pragma code_seg(AFX_CORE2_SEG)
  1135. #endif
  1136. // resource failure
  1137. void AFXAPI AfxThrowResourceException()
  1138. {
  1139. THROW((CResourceException*)&_simpleResourceException);
  1140. }
  1141. // user alert
  1142. void AFXAPI AfxThrowUserException()
  1143. {
  1144. THROW((CUserException*)&_simpleUserException);
  1145. }
  1146. #ifdef AFX_INIT_SEG
  1147. #pragma code_seg(AFX_INIT_SEG)
  1148. #endif
  1149. #pragma warning(disable: 4074)
  1150. #pragma init_seg(compiler)
  1151. IMPLEMENT_FIXED_ALLOC(CTempDC, 64);
  1152. IMPLEMENT_FIXED_ALLOC(CTempGdiObject, 64);
  1153. /////////////////////////////////////////////////////////////////////////////