|
|
1.1 root 1: // This is a part of the Microsoft Foundation Classes C++ library.
2: // Copyright (C) 1992 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 Microsoft
7: // QuickHelp documentation provided with the library.
8: // See these sources for detailed information regarding the
9: // Microsoft Foundation Classes product.
10:
11:
12: #include "afxwin.h"
13: #pragma hdrstop
14:
15: #include "winhand_.h"
16:
17: #ifdef AFX_CORE_SEG
18: #pragma code_seg(AFX_CORE_SEG)
19: #endif
20:
21: #ifdef _DEBUG
22: #undef THIS_FILE
23: static char BASED_CODE THIS_FILE[] = __FILE__;
24: #define new DEBUG_NEW
25: #endif
26:
27: /////////////////////////////////////////////////////////////////////////////
28: // Standard exception processing
29:
30: IMPLEMENT_DYNAMIC(CResourceException, CException)
31: static CResourceException NEAR simpleResourceException;
32: void AfxThrowResourceException()
33: { afxExceptionContext.Throw(&simpleResourceException, TRUE); }
34:
35:
36: /////////////////////////////////////////////////////////////////////////////
37: // Diagnostic Output
38: #ifdef _DEBUG
39: CDumpContext& operator<<(CDumpContext& dc, SIZE size)
40: {
41: return dc << "(" << size.cx << " x " << size.cy << ")";
42: }
43:
44: CDumpContext& operator<<(CDumpContext& dc, POINT point)
45: {
46: return dc << "(" << point.x << ", " << point.y << ")";
47: }
48:
49: CDumpContext& operator<<(CDumpContext& dc, const RECT& rect)
50: {
51: return dc << "(L " << rect.left << ", T " << rect.top << ", R " <<
52: rect.right << ", B " << rect.bottom << ")";
53: }
54: #endif //_DEBUG
55:
56:
57:
58: /////////////////////////////////////////////////////////////////////////////
59: // CDC
60:
61: IMPLEMENT_DYNAMIC(CDC, CObject)
62:
63: // Map from HDC to CDC*
64: class NEAR CDCHandleMap : public CHandleMap
65: {
66: public:
67: CObject* NewTempObject(HANDLE h)
68: {
69: // don't add in permanent
70: CDC* p = new CDC();
71: p->m_hDC = (HDC)h; // set after constructed
72: return p;
73: }
74: void DeleteTempObject(CObject* ob)
75: {
76: // destructor doesn't do anything
77: ASSERT(ob->IsKindOf(RUNTIME_CLASS(CDC)));
78: ((CDC*)ob)->m_hDC = NULL;
79: delete ob;
80: }
81: };
82: static CDCHandleMap NEAR deviceMap;
83:
84: #ifdef _DEBUG
85: void CDC::AssertValid() const
86: {
87: CObject::AssertValid();
88: }
89:
90: void CDC::Dump(CDumpContext& dc) const
91: {
92: CObject::Dump(dc);
93: dc << "m_hDC = " << m_hDC;
94: }
95: #endif
96:
97: CDC*
98: CDC::FromHandle(HDC hDC)
99: {
100: return (CDC*)deviceMap.FromHandle(hDC);
101: }
102:
103: void
104: CDC::DeleteTempMap()
105: {
106: deviceMap.DeleteTemp();
107: }
108:
109: BOOL
110: CDC::Attach(HDC hDC)
111: {
112: ASSERT(m_hDC == NULL); // only attach once, detach on destroy
113: if (hDC == NULL)
114: return FALSE;
115: deviceMap.SetPermanent(m_hDC = hDC, this);
116: return TRUE;
117: }
118:
119: HDC CDC::Detach()
120: {
121: HDC hDC;
122: if ((hDC = m_hDC) != NULL)
123: deviceMap.RemovePermanent(m_hDC);
124: m_hDC = NULL;
125: return hDC;
126: }
127:
128: BOOL CDC::DeleteDC()
129: {
130: if (m_hDC == NULL)
131: return FALSE;
132: return ::DeleteDC(Detach());
133: }
134:
135: CDC::~CDC()
136: {
137: if (m_hDC != NULL)
138: ::DeleteDC(Detach());
139: }
140:
141: /////////////////////////////////////////////////////////////////////////////
142: // Out-of-line routines
143:
144: CGdiObject*
145: CDC::SelectGdiObject(HDC hDC, HANDLE h)
146: {
147: return CGdiObject::FromHandle(::SelectObject(hDC, h));
148: }
149:
150: CPalette*
151: CDC::SelectPalette(CPalette* pPalette, BOOL bForceBackground)
152: {
153: return (CPalette*) CGdiObject::FromHandle(
154: ::SelectPalette(m_hDC, (HPALETTE)pPalette->m_hObject, bForceBackground));
155: }
156:
157: /////////////////////////////////////////////////////////////////////////////
158: // Helper DCs
159:
160: IMPLEMENT_DYNAMIC(CClientDC, CDC)
161: IMPLEMENT_DYNAMIC(CWindowDC, CDC)
162: IMPLEMENT_DYNAMIC(CPaintDC, CDC)
163: IMPLEMENT_DYNAMIC(CMetaFileDC, CDC)
164:
165: #ifdef _DEBUG
166: void CClientDC::AssertValid() const
167: {
168: CDC::AssertValid();
169: ASSERT(IsWindow(m_hWnd));
170: }
171:
172: void CClientDC::Dump(CDumpContext& dc) const
173: {
174: CDC::Dump(dc);
175: dc << " m_hWnd = " << (UINT)m_hWnd;
176: }
177: #endif
178:
179: CClientDC::CClientDC(CWnd* pWnd)
180: {
181: if (!Attach(::GetDC(m_hWnd = pWnd->GetSafeHwnd())))
182: AfxThrowResourceException();
183: }
184:
185: CClientDC::~CClientDC()
186: {
187: ASSERT(m_hDC != NULL);
188: ::ReleaseDC(m_hWnd, Detach());
189: }
190:
191:
192: #ifdef _DEBUG
193: void CWindowDC::AssertValid() const
194: {
195: CDC::AssertValid();
196: ASSERT(::IsWindow(m_hWnd));
197: }
198:
199: void CWindowDC::Dump(CDumpContext& dc) const
200: {
201: CDC::Dump(dc);
202: dc << " m_hWnd = " << (UINT)m_hWnd;
203: }
204: #endif
205:
206: CWindowDC::CWindowDC(CWnd* pWnd)
207: {
208: if (!Attach(::GetWindowDC(m_hWnd = pWnd->GetSafeHwnd())))
209: AfxThrowResourceException();
210: }
211:
212: CWindowDC::~CWindowDC()
213: {
214: ASSERT(m_hDC != NULL);
215: ::ReleaseDC(m_hWnd, Detach());
216: }
217:
218: #ifdef _DEBUG
219: void CPaintDC::AssertValid() const
220: {
221: CDC::AssertValid();
222: ASSERT(::IsWindow(m_hWnd));
223: }
224:
225: void CPaintDC::Dump(CDumpContext& dc) const
226: {
227: CDC::Dump(dc);
228: dc << "\nm_hWnd = " << (UINT)m_hWnd;
229: dc << "\nm_ps.hdc = " << (UINT)m_ps.hdc;
230: dc << "\nm_ps.fErase = " << m_ps.fErase;
231: dc << "\nm_ps.rcPaint = " << (CRect)m_ps.rcPaint;
232: }
233: #endif
234:
235: CPaintDC::CPaintDC(CWnd* pWnd)
236: {
237: ASSERT_VALID(pWnd);
238: if (!Attach(::BeginPaint(m_hWnd = pWnd->m_hWnd, &m_ps)))
239: AfxThrowResourceException();
240: }
241:
242: CPaintDC::~CPaintDC()
243: {
244: ASSERT(m_hDC != NULL);
245: ::EndPaint(m_hWnd, &m_ps);
246: Detach();
247: }
248:
249: /////////////////////////////////////////////////////////////////////////////
250: // CGdiObject
251:
252: IMPLEMENT_DYNAMIC(CGdiObject, CObject)
253:
254: // Map from H??? to CGdiObject*
255:
256: class NEAR CGdiHandleMap : public CHandleMap
257: {
258: public:
259: CObject* NewTempObject(HANDLE hObject)
260: {
261: // don't add in permanent
262: CGdiObject* p = new CGdiObject;
263: p->m_hObject = hObject; // set after constructed
264: return p;
265: }
266: void DeleteTempObject(CObject* ob)
267: {
268: ASSERT(ob->IsKindOf(RUNTIME_CLASS(CGdiObject)));
269: ((CGdiObject*)ob)->m_hObject = NULL;
270: // clear before destructed
271: delete ob;
272: }
273: };
274: static CGdiHandleMap NEAR gdiMap;
275:
276: #ifdef _DEBUG
277: void CGdiObject::Dump(CDumpContext& dc) const
278: {
279: CObject::Dump(dc);
280: dc << " m_hObject = " << (UINT)m_hObject;
281: }
282: #endif
283:
284: CGdiObject*
285: CGdiObject::FromHandle(HANDLE h)
286: {
287: return (CGdiObject*)gdiMap.FromHandle(h);
288: }
289:
290: void
291: CGdiObject::DeleteTempMap()
292: {
293: gdiMap.DeleteTemp();
294: }
295:
296: BOOL
297: CGdiObject::Attach(HANDLE hObject)
298: {
299: ASSERT(m_hObject == NULL); // only attach once, detach on destroy
300: if (hObject == NULL)
301: return FALSE;
302: gdiMap.SetPermanent(m_hObject = hObject, this);
303: return TRUE;
304: }
305:
306: HANDLE CGdiObject::Detach()
307: {
308: HANDLE hObject;
309: if ((hObject = m_hObject) != NULL)
310: {
311: gdiMap.RemovePermanent(m_hObject);
312: // because of stock objects, it may be in temporary map too
313: gdiMap.RemoveTemporary(m_hObject);
314: }
315: m_hObject = NULL;
316: return hObject;
317: }
318:
319: BOOL CGdiObject::DeleteObject()
320: {
321: if (m_hObject == NULL)
322: return FALSE;
323: return ::DeleteObject(Detach());
324: }
325:
326: CGdiObject::~CGdiObject()
327: {
328: DeleteObject();
329: }
330:
331: /////////////////////////////////////////////////////////////////////////////
332: // Standard GDI objects
333:
334: IMPLEMENT_DYNAMIC(CPen, CGdiObject)
335: IMPLEMENT_DYNAMIC(CBrush, CGdiObject)
336: IMPLEMENT_DYNAMIC(CFont, CGdiObject)
337: IMPLEMENT_DYNAMIC(CBitmap, CGdiObject)
338: IMPLEMENT_DYNAMIC(CPalette, CGdiObject)
339: IMPLEMENT_DYNAMIC(CRgn, CGdiObject)
340:
341: /////////////////////////////////////////////////////////////////////////////
342: // Out-of-line constructors
343:
344: ////////////////////////////////////////////
345: // CPen
346:
347: CPen::CPen(int nPenStyle, int nWidth, DWORD crColor)
348: {
349: if (!Attach(::CreatePen(nPenStyle, nWidth, crColor)))
350: AfxThrowResourceException();
351: }
352:
353: ////////////////////////////////////////////
354: // CBrush
355:
356: CBrush::CBrush(DWORD crColor)
357: {
358: if (!Attach(::CreateSolidBrush(crColor)))
359: AfxThrowResourceException();
360: }
361:
362: CBrush::CBrush(int nIndex, DWORD crColor)
363: {
364: if (!Attach(::CreateHatchBrush(nIndex, crColor)))
365: AfxThrowResourceException();
366: }
367:
368: CBrush::CBrush(CBitmap* pBitmap)
369: {
370: if (!Attach(::CreatePatternBrush((HBITMAP)pBitmap->m_hObject)))
371: AfxThrowResourceException();
372: }
373:
374: /////////////////////////////////////////////////////////////////////////////
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.