home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgLangD.iso / C++-7 / DISK8 / MFC / SAMPLES / OCLIENT / ITEMWND.CP$ / itemwnd
Encoding:
Text File  |  1992-03-16  |  8.5 KB  |  383 lines

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