|
|
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: // user interface to OLE embedded objects
12: //
13: // Each OLE embedded object is given it's own window to draw in
14: // We use the windows thick frame to provide sizing (NOTE: this is not
15: // UISG conformant!)
16:
17: #include "oclient.h"
18:
19: #include "mainwnd.h"
20: #include "itemwnd.h"
21:
22: /////////////////////////////////////////////////////////////////////////////
23: // Static members for dragging state
24:
25: CRect CItemWnd::dragRect;
26: CPoint CItemWnd::dragPt;
27:
28: /////////////////////////////////////////////////////////////////////////////
29: // Message map for ItemWnd
30:
31: BEGIN_MESSAGE_MAP(CItemWnd, CWnd)
32: // windows messages
33: ON_WM_PAINT()
34: ON_WM_SIZE()
35: ON_WM_LBUTTONDBLCLK()
36: ON_WM_LBUTTONDOWN()
37: ON_WM_LBUTTONUP()
38: ON_WM_MOUSEMOVE()
39: ON_WM_ERASEBKGND()
40: END_MESSAGE_MAP()
41:
42:
43: /////////////////////////////////////////////////////////////////////////////
44: // Creation
45:
46: #pragma warning(disable:4355)
47: // C4355 is "'this' used in base initializer list" warning
48:
49: CItemWnd::CItemWnd(CMainWnd* pContainer)
50: : m_embedded(pContainer->GetDocument(), this)
51: {
52: m_pContainer = pContainer;
53: m_fVisible = m_fTrackSize = FALSE;
54: m_fCaptured = FALSE;
55: }
56:
57: #pragma warning(default:4355)
58:
59:
60: BOOL CItemWnd::CreateItemWindow(BOOL fShow)
61: {
62: ASSERT(m_pContainer != NULL);
63: CRect rectBounds;
64:
65: if (!GetEmbedded()->GetBounds(&rectBounds))
66: rectBounds.SetRectEmpty(); // server doesn't know about the bounds
67:
68: FixObjectBounds(rectBounds);
69:
70: rectBounds.OffsetRect(2 * GetSystemMetrics(SM_CXFRAME),
71: 2 * GetSystemMetrics(SM_CYFRAME));
72:
73: if (!CWnd::Create(NULL, NULL /* no title */,
74: WS_BORDER | WS_CHILD | WS_CLIPSIBLINGS | WS_THICKFRAME,
75: rectBounds, m_pContainer, 0))
76: {
77: return FALSE;
78: }
79:
80: m_fVisible = fShow;
81: m_fTrackSize = TRUE;
82:
83: GetEmbedded()->SetNames();
84: /* Make the object visible, and paint it if fShow == TRUE */
85: if (fShow)
86: {
87: ShowWindow(SW_SHOW);
88: m_pContainer->SetSelection(this);
89: }
90:
91: return TRUE;
92: }
93:
94: BOOL CItemWnd::RestoreItemWindow(const RECT& rect)
95: {
96: ASSERT(m_pContainer != NULL);
97: CRect rectBounds = rect;
98:
99: rectBounds.OffsetRect(2 * GetSystemMetrics(SM_CXFRAME),
100: 2 * GetSystemMetrics(SM_CYFRAME));
101:
102: if (!CWnd::Create(NULL, NULL /* no title */,
103: WS_BORDER | WS_CHILD | WS_CLIPSIBLINGS | WS_THICKFRAME,
104: rectBounds, m_pContainer, 0))
105: {
106: return FALSE;
107: }
108:
109: GetEmbedded()->SetNames();
110:
111: if (m_fVisible)
112: ShowWindow(SW_SHOW);
113: return TRUE;
114: }
115:
116:
117:
118: /////////////////////////////////////////////////////////////////////////////
119:
120: void CItemWnd::PostNcDestroy()
121: {
122: ASSERT(m_hWnd == NULL); // must be detached
123:
124: if (m_pContainer->GetSelection() == this)
125: m_pContainer->SetSelection(NULL);
126:
127: // finally free up the C++ object and memory
128: // (will destroy embedded object as needed)
129: delete this;
130: }
131:
132:
133: BOOL CItemWnd::OnEraseBkgnd(CDC* pDC)
134: {
135: CBrush myBrush(GetSysColor(COLOR_WINDOW));
136: CRect rect;
137: GetClientRect(&rect);
138: pDC->FillRect(rect, &myBrush);
139: return TRUE; // we handled it
140: }
141:
142:
143: void CItemWnd::OnPaint()
144: {
145: CPaintDC dc(this);
146: CRect rect;
147:
148: // set up a reasonable default context
149: dc.SetTextColor(::GetSysColor(COLOR_WINDOWTEXT));
150: dc.SetBkColor(::GetSysColor(COLOR_WINDOW));
151:
152: // Draw the item
153: GetClientRect(&rect);
154: GetEmbedded()->Draw(&dc, &rect, NULL, &dc);
155: // ignore if can't draw
156: }
157:
158:
159: void CItemWnd::OnSize(UINT, int, int)
160: {
161: Dirty();
162:
163: // Stop tracking size. If user didn't change size, the flag
164: // will be reset later.
165: m_fTrackSize = FALSE;
166: }
167:
168:
169: void CItemWnd::DoVerb(UINT nVerb)
170: // "run" the object
171: {
172: if (GetEmbedded()->GetType() == OT_STATIC)
173: return;
174: CRect rect;
175: GetClientRect(&rect);
176:
177: TRY
178: {
179: GetEmbedded()->Activate(nVerb, TRUE, TRUE, this, &rect);
180: }
181: CATCH (COleException, e)
182: {
183: GetEmbedded()->ReportError(e->m_status);
184: }
185: AND_CATCH (CException, e)
186: {
187: // general error when playing
188: m_pContainer->ErrorMessage(E_FAILED_TO_LAUNCH);
189: }
190: END_CATCH
191: }
192:
193: /////////////////////////////////////////////////////////////////////////////
194: // Mouse messages
195:
196: void CItemWnd::OnLButtonDblClk(UINT, CPoint)
197: {
198: DoVerb(OLEVERB_PRIMARY);
199: }
200:
201: void CItemWnd::OnLButtonDown(UINT, CPoint point)
202: {
203: m_pContainer->SetSelection(this);
204:
205: GetWindowRect(&dragRect);
206: GetParent()->ScreenToClient(&dragRect);
207:
208: dragPt = point;
209:
210: ClientToScreen(&dragPt);
211: GetParent()->ScreenToClient(&dragPt);
212:
213: SetCapture();
214: m_fCaptured = TRUE;
215: }
216:
217: void CItemWnd::OnLButtonUp(UINT, CPoint)
218: {
219: if (!m_fCaptured)
220: return;
221:
222: ReleaseCapture();
223: m_fCaptured = FALSE;
224:
225: /* The object moved */
226: Dirty();
227: }
228:
229: void CItemWnd::OnMouseMove(UINT, CPoint point)
230: {
231: if (!m_fCaptured)
232: return;
233:
234: ClientToScreen(&point);
235: GetParent()->ScreenToClient(&point);
236:
237: dragRect.OffsetRect(point.x - dragPt.x, point.y - dragPt.y);
238: MoveWindow(dragRect);
239: dragPt = point;
240: }
241:
242: /////////////////////////////////////////////////////////////////////////////
243: // Serialization
244:
245: // first WORD in stream is 0x5500 + extra bits
246:
247: void CItemWnd::Serialize(CArchive& ar)
248: {
249: // save the window information + embedded
250: CRect rect;
251:
252: if (ar.IsStoring())
253: {
254: // First save our window part
255: ASSERT(m_fVisible); // only serialize visible window
256: WORD w = 0x5500; // magic value
257: if (m_fTrackSize)
258: w += 1;
259: ar << w;
260:
261: // get window position (parent relative)
262: GetClientRect(&rect);
263: ClientToScreen(&rect);
264: GetParent()->ScreenToClient(&rect);
265: rect -= CPoint(GetSystemMetrics(SM_CXFRAME),
266: GetSystemMetrics(SM_CYFRAME));
267: ar << rect;
268: }
269: else // loading
270: {
271: WORD w;
272: ar >> w;
273:
274: // First load our window part
275: if (HIBYTE(w) != 0x55)
276: {
277: TRACE("Bad magic number in front of an item wnd\n");
278: AfxThrowArchiveException(CArchiveException::generic);
279: }
280: m_fVisible = TRUE;
281: m_fTrackSize = (w & 1) != 0;
282: ar >> rect;
283: }
284:
285: // now do the OLE Embedded part
286: GetEmbedded()->Serialize(ar);
287:
288: if (ar.IsLoading())
289: {
290: // Wrap-up loading - create an ItemWnd as appropriate
291: if (!RestoreItemWindow(rect))
292: AfxThrowArchiveException(CArchiveException::generic);
293: }
294: }
295:
296: /////////////////////////////////////////////////////////////////////////////
297: // Special handling for OLE Client notification
298:
299: void CEmbeddedItem::SetNames()
300: {
301: if (GetType() == OT_EMBEDDED)
302: SetHostNames(AfxGetAppName(), GetName());
303: }
304:
305: // turn on hourglass when waiting for server
306:
307: void CEmbeddedItem::WaitForServer()
308: {
309: m_pView->m_pContainer->Hourglass(TRUE);
310: COleClientItem::WaitForServer();
311: m_pView->m_pContainer->Hourglass(FALSE);
312: }
313:
314: void CEmbeddedItem::OnChange(OLE_NOTIFICATION wNotification)
315: {
316: /* Item just created or we are updating size */
317: if (m_pView->m_hWnd == NULL)
318: return; // no window created yet
319:
320: if (m_pView->CanChangeBounds())
321: {
322: CRect rect;
323:
324: if (GetBounds(&rect))
325: {
326: FixObjectBounds(rect);
327: m_pView->SetInitialBounds(rect);
328: }
329: else
330: {
331: // Blank object
332: if (wNotification == OLE_CLOSED)
333: {
334: // no data received for the object - destroy it
335: // we can't call destroy window here since we are
336: // and OLE callback - so we post a close message instead
337: m_pView->PostMessage(WM_CLOSE);
338: return;
339: }
340: }
341: }
342:
343: m_pView->InvalidateRect(NULL, TRUE); // erase it
344: m_pView->Dirty();
345: }
346:
347: void CItemWnd::SetInitialBounds(const CRect& rect)
348: {
349: BOOL fTrackSizeSave = m_fTrackSize; // save since OnSize will change it
350: SetWindowPos(NULL, 0, 0,
351: rect.right - rect.left + 2*GetSystemMetrics(SM_CXFRAME),
352: rect.bottom - rect.top + 2*GetSystemMetrics(SM_CYFRAME),
353: SWP_NOZORDER | SWP_NOMOVE | SWP_DRAWFRAME);
354: m_fTrackSize = fTrackSizeSave;
355:
356: // show it
357: m_fVisible = TRUE;
358: ShowWindow(SW_SHOW);
359: m_pContainer->SetSelection(this);
360: }
361:
362: /////////////////////////////////////////////////////////////////////////////
363: // A way to get the thick frame window to look good
364: // not a generally useful trick
365:
366: void CItemWnd::Select(BOOL bOn)
367: {
368: if (m_hWnd != NULL)
369: SendMessage(WM_NCACTIVATE, bOn);
370: }
371:
372: /////////////////////////////////////////////////////////////////////////////
373: // Diagnostics
374:
375: #ifdef _DEBUG
376: void CItemWnd::AssertValid() const
377: {
378: ASSERT(m_pContainer != NULL);
379: }
380: #endif
381:
382: /////////////////////////////////////////////////////////////////////////////
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.