home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1996 December / PCWKCD1296.iso / vjplusb / activex / inetsdk / samples / urlpad / paditem.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-29  |  6.0 KB  |  229 lines

  1. //=------------------------------------------------------------------------=
  2. // PadItem.Cpp
  3. //=------------------------------------------------------------------------=
  4. // Copyright 1992-1996 Microsoft Corporation.  All Rights Reserved.
  5. //
  6. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  7. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  8. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  9. // PARTICULAR PURPOSE.
  10. //=--------------------------------------------------------------------------=
  11. //
  12. // implementation of the CEmbeddedItem class
  13. //
  14.  
  15. #include "stdafx.h"
  16. #include "padview.h"
  17. #include "paddoc.h"
  18. #include "paditem.h"
  19. #include <limits.h>
  20. #include <winnls.h>
  21.  
  22. IMPLEMENT_DYNAMIC(CEmbeddedItem, COleServerItem)
  23.  
  24. CEmbeddedItem::CEmbeddedItem(CPadDoc* pContainerDoc)
  25.     : COleServerItem(pContainerDoc, TRUE)
  26. {
  27.     m_nBeg = 0;
  28.     m_nEnd = UINT_MAX;
  29.  
  30.     // support CF_TEXT format
  31.     GetDataSource()->DelayRenderFileData(CF_TEXT);
  32. }
  33.  
  34. BOOL CEmbeddedItem::OnRenderFileData(LPFORMATETC lpFormatEtc, CFile* pFile)
  35. {
  36.     ASSERT(lpFormatEtc != NULL);
  37.     if (lpFormatEtc->cfFormat != CF_TEXT)
  38.         return COleServerItem::OnRenderFileData(lpFormatEtc, pFile);
  39.  
  40.     BOOL bResult = FALSE;
  41.     TRY
  42.     {
  43.         // save contents of this item to the file
  44.         SaveToFile(pFile);
  45.  
  46.         // CF_TEXT has NUL termination
  47.         char chZero = '\0';
  48.         pFile->Write(&chZero, sizeof(char));
  49.  
  50.         bResult = TRUE; // success
  51.     }
  52.     END_TRY
  53.  
  54.     return bResult;
  55. }
  56.  
  57. CPadView* CEmbeddedItem::GetView() const
  58. {
  59.     CDocument* pDoc = GetDocument();
  60.     ASSERT_VALID(pDoc);
  61.     POSITION pos = pDoc->GetFirstViewPosition();
  62.     if (pos == NULL)
  63.         return NULL;
  64.  
  65.     CPadView* pView = (CPadView*)pDoc->GetNextView(pos);
  66.     ASSERT_VALID(pView);
  67.     ASSERT_KINDOF(CPadView, pView);
  68.     return pView;
  69. }
  70.  
  71. void CEmbeddedItem::SaveToFile(CFile* pFile)
  72. {
  73.     CPadView* pView = GetView();
  74.     LPCTSTR lpszText = NULL;
  75.  
  76.     TRY
  77.     {
  78.         // get access to the edit buffer
  79.         lpszText = pView->LockBuffer();
  80.  
  81.         // get range (make sure inside of text length)
  82.         UINT nEnd = pView->GetWindowTextLength();
  83.         UINT nBeg = min(m_nBeg, nEnd);
  84.         nEnd = min(m_nEnd, nEnd);
  85. #ifdef _UNICODE
  86.         // copy to temp buffer, convert, then write to file
  87.         int nLen = WideCharToMultiByte(CP_ACP, 0, lpszText+nBeg, nEnd-nBeg,
  88.             NULL, 0, NULL, NULL);
  89.         char* pszTemp = new char[nLen];
  90.         WideCharToMultiByte(CP_ACP, 0, lpszText+nBeg, nEnd-nBeg,
  91.             pszTemp, nLen, NULL, NULL);
  92.         pFile->Write(pszTemp, nLen);
  93.         delete[] pszTemp;
  94. #else
  95.         // write it out to the file
  96.         pFile->Write(lpszText+nBeg, (nEnd-nBeg) * sizeof(char));
  97. #endif
  98.     }
  99.     END_TRY
  100.  
  101.     // release access to edit buffer
  102.     if (lpszText != NULL)
  103.         pView->UnlockBuffer();
  104. }
  105.  
  106. void CEmbeddedItem::Serialize(CArchive& ar)
  107. {
  108.     if (ar.IsStoring())
  109.     {
  110.         // save just the portion this item refers to
  111.         ar.Flush();
  112.         CFile* pFile = ar.GetFile();
  113.         SaveToFile(pFile);
  114.     }
  115.     else
  116.     {
  117.         // otherwise, read in the entire file
  118.         GetDocument()->Serialize(ar);
  119.     }
  120. }
  121.  
  122. BOOL CEmbeddedItem::OnGetExtent(DVASPECT dwDrawAspect, CSize& rSize)
  123. {
  124.     if (dwDrawAspect != DVASPECT_CONTENT)
  125.         return COleServerItem::OnGetExtent(dwDrawAspect, rSize);
  126.  
  127.     // no drawing will happen if cliprect is NULL
  128.     CClientDC dc(NULL);
  129.     dc.IntersectClipRect(0, 0, 0, 0);
  130.     return OnDraw(&dc, rSize);
  131. }
  132.  
  133. BOOL CEmbeddedItem::OnDraw(CDC* pDC, CSize& rSize)
  134. {
  135.     // get view attached to the item
  136.     CPadView* pView = GetView();
  137.  
  138.     // In some situations, OLE1 servers will ask for the presentation data
  139.     //  during shutdown, even though it is not necessary (since the picture
  140.     //  has not changed).  This will happen when closing a frame window
  141.     //  for example.  By this time all the views are gone and there is no
  142.     //  way to produce the metafile data, since the actual text is
  143.     //  stored by the edit control (the view).  In this case, we simply
  144.     //  fail the call.
  145.     if (pView == NULL)
  146.         return FALSE;
  147.  
  148.     // edit controls have a border around them
  149.     CRect rectClient;
  150.     CRect margin;
  151.  
  152.     { // Calculate correct ClientRect
  153.         pView->GetClientRect(&rectClient);
  154.         rectClient.InflateRect(-1,-1);
  155.  
  156.         if (pView->GetStyle() & WS_HSCROLL)
  157.             rectClient.bottom++;
  158.         if (pView->GetStyle() & WS_VSCROLL)
  159.             rectClient.right++;
  160.     }
  161.  
  162.     { // Calculate margins
  163.         CRect rectEdit;
  164.         pView->GetEditCtrl().GetRect(&rectEdit);
  165.  
  166.         if (rectEdit.IsRectEmpty())
  167.             rectEdit.SetRect(4,4,4,4);
  168.  
  169.         int HorzMargin = rectEdit.left - rectClient.left;
  170.         int VertMargin = rectEdit.top - rectClient.top;
  171.  
  172.         margin.SetRect(HorzMargin,VertMargin,HorzMargin,VertMargin);
  173.  
  174.         if (pView->GetStyle() & WS_HSCROLL)
  175.             margin.bottom++;
  176.         if (pView->GetStyle() & WS_VSCROLL)
  177.             margin.right++;
  178.     }
  179.  
  180.     // get the font from the CEditView
  181.     CFont* pFont = pView->GetFont();
  182.     CFont* pOldFont = NULL;
  183.     if (pFont != NULL)
  184.         pOldFont = pDC->SelectObject(pFont);
  185.  
  186.     // get formatting rectangle
  187.     CRect rect(rectClient);
  188.     rect.left += margin.left;
  189.     rect.top += margin.top;
  190.     rect.right -= margin.right;
  191.     rect.bottom = INT_MAX;
  192.  
  193.     pDC->SetBkMode(TRANSPARENT);
  194.  
  195.     // first just determine the correct extents of the text
  196.     pDC->SaveDC();
  197.     pDC->IntersectClipRect(0, 0, 0, 0); // no drawing with NULL clipping
  198.     if (pView->PrintInsideRect(pDC, rect, m_nBeg, m_nEnd) == 0)
  199.     {
  200.         TEXTMETRIC tm;
  201.         pDC->GetTextMetrics(&tm);
  202.         rect.bottom = rect.top + tm.tmHeight + tm.tmExternalLeading;
  203.     }
  204.     pDC->RestoreDC(-1);
  205.  
  206.     // then, really output the text
  207.     pDC->SetWindowOrg(rect.left-margin.left,rect.top-margin.top);
  208.     pDC->SetWindowExt(margin.left + rect.Width() + margin.right,
  209.         margin.top + rect.Height() + margin.bottom);
  210.     pView->PrintInsideRect(pDC, rect, m_nBeg, m_nEnd);
  211.  
  212.     // adjust for border (rect.left is already adjusted)
  213.     rect.left -= margin.left;
  214.     rect.top -= margin.top;
  215.     rect.right += margin.right;
  216.     rect.bottom += margin.bottom;
  217.  
  218.     // select previous font
  219.     if (pOldFont != NULL)
  220.         pDC->SelectObject(pOldFont);
  221.  
  222.     // return HIMETRIC size
  223.     rSize = rect.Size();
  224.     pDC->LPtoHIMETRIC(&rSize);
  225.     return TRUE;
  226. }
  227.  
  228. /////////////////////////////////////////////////////////////////////////////
  229.