|
|
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.