home *** CD-ROM | disk | FTP | other *** search
- // svrnode.cpp : implementation of the CServerNode class
- //
- // This is a part of the Microsoft Foundation Classes C++ library.
- // Copyright (C) 1992-1995 Microsoft Corporation
- // All rights reserved.
- //
- // This source code is only intended as a supplement to the
- // Microsoft Foundation Classes Reference and Microsoft
- // QuickHelp and/or WinHelp documentation provided with the library.
- // See these sources for detailed information regarding the
- // Microsoft Foundation Classes product.
-
-
- #include "stdafx.h"
- #include <afxpriv.h> // for CSharedFile
- #include <malloc.h> // for _alloca
-
- #include "$$root$$.h"
- #include "svritem.h"
- #include "svrdoc.h"
- #include "svrview.h"
-
- #ifdef _DEBUG
- #undef THIS_FILE
- static char BASED_CODE THIS_FILE[] = __FILE__;
- #endif
-
- /////////////////////////////////////////////////////////////////////////////
- // Local dialogs used for implementation
-
- class CChangeNameDlg : public CDialog
- {
- // Construction
- public:
- CChangeNameDlg(CWnd* pParent = NULL);
-
- // Dialog Data
- //{{AFX_DATA(CChangeNameDlg)
- enum { IDD = IDD_CHANGE_NAME };
- int m_shape;
- CString m_strDescription;
- CString m_strLinkKey;
- CEdit m_editDescription;
- CButton m_btnOK;
- //}}AFX_DATA
-
- // Implementation
- protected:
- virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
- virtual BOOL OnInitDialog();
- // Generated message map functions
- //{{AFX_MSG(CChangeNameDlg)
- afx_msg void OnChange();
- //}}AFX_MSG
- DECLARE_MESSAGE_MAP()
- };
-
- class CAddNodeDlg : public CDialog
- {
- // Construction
- public:
- CAddNodeDlg(CWnd* pParent = NULL); // standard constructor
-
- // Dialog Data
- //{{AFX_DATA(CAddNodeDlg)
- enum { IDD = IDD_ADD_NODE };
- CString m_strDescription;
- CString m_strLinkKey;
- int m_shape;
- CEdit m_editDescription;
- CButton m_btnOK;
- //}}AFX_DATA
-
- // Implementation
- protected:
- virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
- virtual BOOL OnInitDialog();
-
- // Generated message map functions
- //{{AFX_MSG(CAddNodeDlg)
- afx_msg void OnChange();
- //}}AFX_MSG
- DECLARE_MESSAGE_MAP()
- };
-
- /////////////////////////////////////////////////////////////////////////////
- // CServerNode
-
- IMPLEMENT_SERIAL(CServerNode, CObject, 0);
-
- CServerNode::CServerNode(CServerDoc* pServerDoc)
- {
- m_shape = shapeRect;
- m_bHideChildren = FALSE;
- m_pDocument = pServerDoc;
-
- m_pServerItem = NULL; // will get connected if need be
- }
-
- // Special "new" operator for root node
- CServerNode* CServerNode::CreateRootNode(CServerDoc* pDoc)
- {
- CServerNode* pRoot = NULL;
- TRY
- {
- pRoot = new CServerNode(pDoc);
- pRoot->InitRootNode();
- }
- CATCH(CException, e)
- {
- delete pRoot;
- pRoot = NULL;
- }
- END_CATCH
-
- return pRoot;
- }
-
- // Special constructor for root node
- void CServerNode::InitRootNode()
- {
- DeleteChildNodes(); // initalized root node has no children
-
- m_strDescription = "Root node";
- m_strLinkKey = "%ROOT%"; // link name for root
- UpdateItemName();
- }
-
- BOOL CServerNode::FindAndDelete(CServerNode* pNode)
- {
- POSITION pos = m_listChild.GetHeadPosition();
- while (pos != NULL)
- {
- POSITION posPrev = pos;
- CServerNode *pChild = (CServerNode*)m_listChild.GetNext(pos);
- if (pChild == pNode)
- {
- m_listChild.RemoveAt(posPrev);
- delete pNode;
- return TRUE;
- }
- if (pChild->FindAndDelete(pNode) == TRUE)
- return TRUE;
- }
- return FALSE;
- }
-
- CServerNode* CServerNode::FindNode(LPCTSTR pszItemName)
- {
- // return this node if it matches!
- if (GetItemName() == pszItemName)
- return this;
-
- POSITION pos = m_listChild.GetHeadPosition();
- while (pos != NULL)
- {
- CServerNode* pChild = (CServerNode*)m_listChild.GetNext(pos);
- if (pChild->GetItemName() == pszItemName)
- return pChild;
-
- // recurse down the tree
- pChild = pChild->FindNode(pszItemName);
- if (pChild != NULL)
- return pChild;
- }
- return NULL;
- }
-
- void CServerNode::DeleteChildNodes()
- {
- // delete child nodes
- POSITION pos = m_listChild.GetHeadPosition();
- while (pos != NULL)
- delete m_listChild.GetNext(pos);
- m_listChild.RemoveAll();
- }
-
- CServerNode::~CServerNode()
- {
- // if we are the root of a document, clear it
- if (GetDocument()->m_pRoot == this)
- GetDocument()->m_pRoot = NULL;
-
- // if we are attached to a server item, detach from it
- if (m_pServerItem != NULL)
- m_pServerItem->m_pServerNode = NULL;
-
- // delete all of the child nodes of this node
- DeleteChildNodes();
- }
-
- BOOL CServerNode::IsChild(const CServerNode* pPotentialChild) const
- {
- if (pPotentialChild == this)
- return TRUE;
- POSITION pos = m_listChild.GetHeadPosition();
- while (pos != NULL)
- {
- CServerNode* pNode = (CServerNode*)m_listChild.GetNext(pos);
- if (pNode->IsChild(pPotentialChild))
- return TRUE;
- }
- return FALSE;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CServerNode bounding rect helpers
-
- #define CX_INSET 4
- #define CY_INSET 2
-
- // calc node size for arbitrary dc and return
- // (result is in logical units for the given DC)
- void CServerNode::CalcNodeSize(CDC* pDC, CSize& sizeNode)
- {
- ASSERT(pDC != NULL);
- sizeNode = pDC->GetTextExtent(m_strDescription,
- m_strDescription.GetLength());
- sizeNode += CSize(CX_INSET * 2, CY_INSET * 2);
- }
-
- // calculate bounding rect using pointer to member for each node
- void CServerNode::CalcBounding(CDC* pDC, CPoint& ptStart, CSize& sizeMax)
- {
- ASSERT(sizeMax.cx >= 0 && sizeMax.cy >= 0);
- ASSERT(ptStart.x >= 0 && ptStart.y >= 0);
-
- CSize sizeNode;
- CalcNodeSize(pDC, sizeNode);
-
- ptStart.y += sizeNode.cy + CY_SEPARATOR;
- if (ptStart.y > sizeMax.cy)
- sizeMax.cy = ptStart.y;
-
- if (ptStart.x + sizeNode.cx > sizeMax.cx)
- sizeMax.cx = ptStart.x + sizeNode.cx;
- ptStart.x += CX_INDENT;
- // add in the kids
- if (!m_bHideChildren)
- {
- POSITION pos = m_listChild.GetHeadPosition();
- while (pos != NULL)
- {
- CServerNode* pNode = (CServerNode*)m_listChild.GetNext(pos);
- pNode->CalcBounding(pDC, ptStart, sizeMax);
- }
- }
- ptStart.x -= CX_INDENT;
- }
-
- $$IF(WANTS_TEXTVIEW)
- /////////////////////////////////////////////////////////////////////////////
- // CSTextView drawing helpers
-
- BOOL CServerNode::GetNodeText(CString *strBuf, int TAB)
- {
- *strBuf+= m_strDescription ;
- //Insert a return
- *strBuf+= "\r\n" ;
- return TRUE;
- }
-
- int CServerNode::GetTreeText(CString * strBuf, int TAB)
- {
- ASSERT(strBuf != NULL);
-
- // Indent if we need to.
- for(int i = 0; i< TAB; i++)
- *strBuf+= "\t" ;
-
- GetNodeText(strBuf, TAB);
- if (m_listChild.GetCount() == 0 || m_bHideChildren)
- return TAB; // nothing more to draw
-
- // draw the kids
- POSITION pos = m_listChild.GetHeadPosition();
- while (pos != NULL)
- {
- CServerNode *pChild = (CServerNode*)m_listChild.GetNext(pos);
- // draw the child node
- pChild->GetTreeText(strBuf, TAB +1);
- }
- return TAB;
- }
-
- $$ENDIF
- /////////////////////////////////////////////////////////////////////////////
- // CServerNode drawing helpers
-
- BOOL CServerNode::Draw(CDC* pDC, CPoint pt, BOOL bSelected, CSize sizeNode)
- {
- CRect rect(pt, sizeNode);
- if (!pDC->RectVisible(&rect))
- return TRUE;
-
- // draw a the bounding shape
- BOOL bOK = TRUE;
-
- CPen* pOldPen = NULL;
- CPen penHilite;
- int nPenStyle = (m_bHideChildren) ? PS_DASH : PS_SOLID;
- COLORREF crPen = (bSelected) ? RGB(255,0,0) : RGB(0,0,0);
- if (penHilite.CreatePen(nPenStyle, 0, crPen))
- pOldPen = pDC->SelectObject(&penHilite);
-
- switch (m_shape)
- {
- case shapeRect:
- bOK = pDC->Rectangle(rect);
- break;
- case shapeRound:
- bOK = pDC->RoundRect(rect, CPoint(7, 7));
- break;
- case shapeOval: // really just a rounder rounded rect
- bOK = pDC->RoundRect(rect, CPoint(14, 14));
- break;
- default:
- TRACE1("Error: unknown shape %d\n", m_shape);
- bOK = FALSE;
- break;
- }
- if (pOldPen != NULL)
- pDC->SelectObject(pOldPen);
-
- if (!bOK)
- return FALSE;
-
- // inset a bit
- rect.InflateRect(-CX_INSET, -CY_INSET);
-
- if (!pDC->ExtTextOut(rect.left, rect.top, ETO_OPAQUE, rect,
- m_strDescription, m_strDescription.GetLength(), NULL))
- return FALSE;
-
- // all OK
- return TRUE;
- }
-
- int CServerNode::DrawTree(CDC* pDC, CPoint ptStart, CServerNode* pNodeSel)
- {
- ASSERT(pDC != NULL);
- ASSERT(ptStart.x >= 0 && ptStart.y >= 0);
-
- // root node starts here
- int cyDrawn = 0;
- CSize sizeNode;
- CalcNodeSize(pDC, sizeNode);
- Draw(pDC, ptStart, this == pNodeSel, sizeNode);
- cyDrawn += sizeNode.cy + CY_SEPARATOR;
-
- if (m_listChild.GetCount() == 0 || m_bHideChildren)
- return cyDrawn; // nothing more to draw
-
- // indent for the kids
- CPoint ptKid(ptStart.x + CX_INDENT, ptStart.y + cyDrawn);
-
- // draw the kids
- int yMid = 0;
- POSITION pos = m_listChild.GetHeadPosition();
- while (pos != NULL)
- {
- CServerNode *pChild = (CServerNode*)m_listChild.GetNext(pos);
-
- // add the little line
- yMid = ptKid.y + (sizeNode.cy)/2;
- pDC->MoveTo(ptStart.x + CX_BACKDENT, yMid);
- pDC->LineTo(ptKid.x, yMid);
-
- // draw the child node
- int cyKid = pChild->DrawTree(pDC, ptKid, pNodeSel);
- if (cyKid == -1)
- return -1; // error
-
- cyDrawn += cyKid;
- ptKid.y += cyKid;
- }
- ASSERT(ptKid.y == ptStart.y + cyDrawn);
-
- // draw the connecting line (down to last yMid)
- ASSERT(yMid != 0);
- int xLine = ptStart.x + CX_BACKDENT;
- pDC->MoveTo(xLine, ptStart.y + sizeNode.cy);
- pDC->LineTo(xLine, yMid);
- return cyDrawn;
- }
-
- // Serializes to file or to embedded OLE stream
- void CServerNode::Serialize(CArchive& ar)
- {
- CObject::Serialize(ar);
- if (ar.IsStoring())
- {
- ar << (WORD)m_shape;
-
- ASSERT(m_strLinkKey.IsEmpty() || m_strDescription != m_strLinkKey);
- if (m_pServerItem != NULL)
- ar << m_pServerItem->GetItemName();
- else
- ar << m_strLinkKey;
- ar << m_strDescription;
- ar << (WORD)m_bHideChildren;
- }
- else
- {
- // get back-pointer to document
- m_pDocument = (CServerDoc*)ar.m_pDocument;
-
- WORD wTemp;
- ar >> wTemp; m_shape = (EShape)wTemp;
- if (m_shape >= shapeMax)
- m_shape = shapeRect;
- ar >> m_strLinkKey >> m_strDescription;
- UpdateItemName();
- ar >> wTemp;
- m_bHideChildren = (BOOL)wTemp;
- }
- m_listChild.Serialize(ar);
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CServerNode support for CF_TEXT format
-
- void CServerNode::SaveAsText(CArchive& ar, int nLevel)
- {
- ASSERT(ar.IsStoring());
-
- // indent node text
- char szTabs[MAX_LEVEL];
- int nTabs = min(nLevel, MAX_LEVEL);
- memset(szTabs, '\t', nTabs);
- ar.Write(szTabs, nTabs);
-
- // write node text itself
- #ifdef _UNICODE
- int nLen = m_strDescription.GetLength();
- char* psz = (char*)_alloca(nLen+1);
- wcstombs(psz, m_strDescription, nLen+1);
- ar.Write(psz, nLen);
- #else
- ar.Write(m_strDescription, m_strDescription.GetLength()*sizeof(TCHAR));
- #endif
-
- // terminate line with CRLF
- static char BASED_CODE szCRLF[] = "\r\n";
- ar.Write(szCRLF, sizeof(szCRLF)-1);
-
- // write kids
- POSITION pos = m_listChild.GetHeadPosition();
- while (pos != NULL)
- {
- CServerNode* pNode = (CServerNode*)m_listChild.GetNext(pos);
- pNode->SaveAsText(ar, nLevel+1);
- }
- }
-
- void CServerNode::UpdateItemName()
- {
- // empty link key if same as description (it is redundant)
- if (m_strLinkKey == m_strDescription)
- m_strLinkKey.Empty();
-
- // update link name in item if attached
- if (m_pServerItem != NULL)
- {
- CString* pstr;
- if (m_strLinkKey.IsEmpty())
- pstr = &m_strDescription;
- else
- pstr = &m_strLinkKey;
- m_pServerItem->SetItemName(*pstr);
-
- // empty link key since it is redundant with the server item
- m_strLinkKey.Empty();
- }
- }
-
- const CString& CServerNode::GetItemName()
- {
- // use item name in server item if connected
- if (m_pServerItem != NULL)
- return m_pServerItem->GetItemName();
-
- // use description or link key depending on state of link key
- else if (m_strLinkKey.IsEmpty())
- return m_strDescription;
- else
- return m_strLinkKey;
- }
-
- BOOL CServerNode::PromptChangeNode()
- {
- CChangeNameDlg dlg;
- dlg.m_strDescription = m_strDescription;
- dlg.m_strLinkKey = GetItemName();
- if (dlg.m_strLinkKey == dlg.m_strDescription)
- dlg.m_strLinkKey.Empty(); // leave empty for tracking link name
- dlg.m_shape = m_shape;
-
- if (dlg.DoModal() == IDOK)
- {
- m_strDescription = dlg.m_strDescription;
- m_strLinkKey = dlg.m_strLinkKey;
- UpdateItemName(); // syncronize names as appropriate
- m_shape = (EShape)dlg.m_shape;
- return TRUE;
- }
- return FALSE;
- }
-
- ////////////////////////////////////////////////////////////////
- // Creating child nodes
-
- // Special constructor for child node
- CServerNode* CServerNode::CreateChildNode(LPCTSTR lpszDescription)
- {
- CServerNode* pNew = NULL;
- TRY
- {
- pNew = new CServerNode(GetDocument());
- pNew->m_strDescription = lpszDescription;
- // both item name and description start out the same
-
- // add as the last child
- m_listChild.AddTail(pNew);
- }
- CATCH (CException, e)
- {
- delete pNew;
- pNew = NULL;
- }
- END_CATCH
-
- return pNew;
- }
-
- CServerNode* CServerNode::PromptNewChildNode()
- {
- CAddNodeDlg dlg;
- dlg.m_shape = (EShape)shapeRect;
- if (dlg.DoModal() != IDOK)
- return NULL;
-
- CServerNode* pNew = CreateChildNode(dlg.m_strDescription);
- if (pNew == NULL)
- AfxThrowMemoryException();
- pNew->m_shape = (EShape)dlg.m_shape;
- pNew->m_strLinkKey = dlg.m_strLinkKey;
- pNew->UpdateItemName();
-
- return pNew;
- }
-
- CServerNode* CServerNode::GetNext(CServerNode* pNode, BOOL bInit)
- {
- static BOOL bFound;
- if (bInit)
- bFound = FALSE;
-
- if (pNode == this)
- bFound = TRUE;
- if (!m_bHideChildren)
- {
- POSITION pos = m_listChild.GetHeadPosition();
- while (pos != NULL)
- {
- CServerNode* pChild = (CServerNode*)m_listChild.GetNext(pos);
- if (bFound)
- return pChild;
- pChild = pChild->GetNext(pNode, FALSE);
- if (pChild != NULL)
- return pChild;
- }
- }
- // if reached top and last level return original
- if (bInit)
- return pNode;
- else
- return NULL;
- }
-
- CServerNode* CServerNode::GetPrev(CServerNode* pNode,BOOL bInit)
- {
- static CServerNode* pPrev;
- if (bInit)
- pPrev = this;
-
- if (pNode == this)
- return pPrev;
-
- pPrev = this;
-
- if (!m_bHideChildren)
- {
- POSITION pos = m_listChild.GetHeadPosition();
- while (pos != NULL)
- {
- CServerNode* pCur = (CServerNode*)m_listChild.GetNext(pos);
- CServerNode* pChild = pCur->GetPrev(pNode, FALSE);
- if (pChild != NULL)
- return pChild;
- }
- }
- if (bInit)
- return pPrev;
- else
- return NULL;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CChangeNameDlg dialog
-
- CChangeNameDlg::CChangeNameDlg(CWnd* pParent)
- : CDialog(CChangeNameDlg::IDD, pParent)
- {
- //{{AFX_DATA_INIT(CChangeNameDlg)
- //}}AFX_DATA_INIT
- }
-
- BOOL CChangeNameDlg::OnInitDialog()
- {
- CDialog::OnInitDialog();
- OnChange(); // after DDX
- return TRUE;
- }
-
- void CChangeNameDlg::DoDataExchange(CDataExchange* pDX)
- {
- CDialog::DoDataExchange(pDX);
- //{{AFX_DATA_MAP(CChangeNameDlg)
- DDX_CBIndex(pDX, IDC_COMBO1, m_shape);
- DDX_Text(pDX, IDC_EDIT1, m_strDescription);
- DDX_Text(pDX, IDC_EDIT2, m_strLinkKey);
- DDX_Control(pDX, IDC_EDIT1, m_editDescription);
- DDX_Control(pDX, IDOK, m_btnOK);
- //}}AFX_DATA_MAP
- }
-
- BEGIN_MESSAGE_MAP(CChangeNameDlg, CDialog)
- //{{AFX_MSG_MAP(CChangeNameDlg)
- ON_EN_CHANGE(IDC_EDIT1, OnChange)
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
-
-
- void CChangeNameDlg::OnChange()
- {
- if (m_btnOK.m_hWnd)
- m_btnOK.EnableWindow(m_editDescription.GetWindowTextLength() > 0);
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CAddNodeDlg dialog
-
- CAddNodeDlg::CAddNodeDlg(CWnd* pParent /*=NULL*/)
- : CDialog(CAddNodeDlg::IDD, pParent)
- {
- //{{AFX_DATA_INIT(CAddNodeDlg)
- //}}AFX_DATA_INIT
- }
-
- BOOL CAddNodeDlg::OnInitDialog()
- {
- CDialog::OnInitDialog();
- OnChange(); // after DDX
- return TRUE;
- }
-
- void CAddNodeDlg::DoDataExchange(CDataExchange* pDX)
- {
- CDialog::DoDataExchange(pDX);
- //{{AFX_DATA_MAP(CAddNodeDlg)
- DDX_Text(pDX, IDC_EDIT1, m_strDescription);
- DDX_Text(pDX, IDC_EDIT2, m_strLinkKey);
- DDX_CBIndex(pDX, IDC_COMBO1, m_shape);
- DDX_Control(pDX, IDC_EDIT1, m_editDescription);
- DDX_Control(pDX, IDOK, m_btnOK);
- //}}AFX_DATA_MAP
- }
-
-
- BEGIN_MESSAGE_MAP(CAddNodeDlg, CDialog)
- //{{AFX_MSG_MAP(CAddNodeDlg)
- ON_EN_CHANGE(IDC_EDIT1, OnChange)
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
-
- void CAddNodeDlg::OnChange()
- {
- if (m_btnOK.m_hWnd)
- m_btnOK.EnableWindow(m_editDescription.GetWindowTextLength() > 0);
- }
-
- //////////////////////////////////////////////////////////////////////////////
- // CServerItem construction
-
- CServerItem::CServerItem(CServerDoc* pServerDoc, CServerNode* pServerNode)
- : COleServerItem(pServerDoc, TRUE)
- {
- // need to attach this server item to the node in the document
- ASSERT_VALID(pServerNode);
- m_pServerNode = pServerNode;
- pServerNode->m_pServerItem = this;
- pServerNode->UpdateItemName();
-
- // support CF_TEXT format
- GetDataSource()->DelayRenderFileData(CF_TEXT);
- }
-
- CServerItem::~CServerItem()
- {
- if (m_pServerNode != NULL)
- {
- m_pServerNode->m_pServerItem = NULL;
- m_pServerNode->m_strLinkKey = GetItemName();
- m_pServerNode->UpdateItemName();
- }
- }
-
- //////////////////////////////////////////////////////////////////////////////
- // CServerItem verb handling
-
- void CServerItem::OnOpen()
- {
- if (IsLinkedItem() && m_pServerNode != NULL)
- {
- // for linked items, try to select this node in the document
- CServerDoc* pDoc = GetDocument();
- ASSERT(pDoc != NULL);
- POSITION pos = pDoc->GetFirstViewPosition();
- ASSERT(pos != NULL);
- CServerView* pView = (CServerView*)pDoc->GetNextView(pos);
- ASSERT(pView->IsKindOf(RUNTIME_CLASS(CServerView)));
-
- pView->SetSelection(m_pServerNode);
- pView->ScrollToItem(m_pServerNode, TRUE);
- }
- COleServerItem::OnOpen();
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CServerItem drawing
-
- BOOL CServerItem::OnGetExtent(DVASPECT dwDrawAspect, CSize& rSize)
- {
- if (dwDrawAspect != DVASPECT_CONTENT)
- return COleServerItem::OnGetExtent(dwDrawAspect, rSize);
-
- // determine extent based on screen dc
- rSize = CSize(0, 0);
- if (m_pServerNode != NULL)
- {
- CClientDC dc(NULL);
- dc.SetMapMode(MM_ANISOTROPIC);
- CServerDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- CPoint ptStart(CX_MARGIN, CY_MARGIN);
- pDoc->CalcBounding(&dc, m_pServerNode, ptStart, rSize);
- rSize.cx += CX_MARGIN;
- dc.LPtoHIMETRIC(&rSize); // convert pixels to HIMETRIC
- }
- return TRUE;
- }
-
- BOOL CServerItem::OnDraw(CDC* pDC, CSize& rSize)
- {
- if (m_pServerNode != NULL)
- {
- // determine extent of this item in the document
- CServerDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- rSize = CSize(0, 0);
- CPoint ptStart(CX_MARGIN, CY_MARGIN);
- pDoc->CalcBounding(pDC, m_pServerNode, ptStart, rSize);
- rSize.cx += CX_MARGIN;
-
- // prepare to draw and remember the extent in himetric units
- pDC->SetWindowOrg(0, 0);
- pDC->SetWindowExt(rSize);
- pDC->SetViewportExt(rSize); // Note: only affects the m_hAttribDC
-
- pDC->LPtoHIMETRIC(&rSize); // convert pixels to HIMETRIC
-
- // CServerDoc::DrawTree selects and releases font automatically
- pDoc->DrawTree(pDC, ptStart, NULL, m_pServerNode);
- }
- return TRUE;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CServerItem clipboard handling
-
- void CServerItem::Serialize(CArchive& ar)
- {
- // serialize font info from document (so it looks like a document)
- CServerDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- pDoc->SerializeFontInfo(ar);
-
- // serialize node info
- ASSERT_VALID(m_pServerNode);
- m_pServerNode->Serialize(ar);
- }
-
- BOOL CServerItem::OnRenderFileData(LPFORMATETC lpFormatEtc, CFile* pFile)
- {
- ASSERT(lpFormatEtc != NULL);
- if (lpFormatEtc->cfFormat != CF_TEXT)
- return COleServerItem::OnRenderFileData(lpFormatEtc, pFile);
-
- BOOL bResult = FALSE;
- if (m_pServerNode != NULL)
- {
- TRY
- {
- // save as text
- CArchive ar(pFile, CArchive::store);
- m_pServerNode->SaveAsText(ar, 0);
- ar << (BYTE)'\0'; // terminate with NUL character
- bResult = TRUE;
- }
- END_TRY
- }
- return bResult;
- }
-
- // OnGetClipboardData is used by CopyToClipboard and DoDragDrop
- COleDataSource* CServerItem::OnGetClipboardData(BOOL bIncludeLink,
- LPPOINT pptOffset, LPSIZE pSize)
- {
- ASSERT_VALID(this);
-
- if (m_pServerNode == NULL)
- return NULL;
-
- COleDataSource* pDataSource = new COleDataSource;
- TRY
- {
- GetNativeClipboardData(pDataSource);
- GetClipboardData(pDataSource, bIncludeLink, pptOffset, pSize);
- }
- CATCH_ALL(e)
- {
- delete pDataSource;
- THROW_LAST();
- }
- END_CATCH_ALL
-
- ASSERT_VALID(pDataSource);
- return pDataSource;
- }
-
- void CServerItem::GetNativeClipboardData(COleDataSource *pDataSource)
- {
- ASSERT_VALID(this);
- ASSERT(CServerDoc::m_cfPrivate != NULL);
-
- // Create a shared file and associate a CArchive with it
- CSharedFile file;
- CArchive ar(&file,CArchive::store);
-
- // Serialize selected objects to the archive
- m_pServerNode->Serialize(ar);
- ar.Close();
-
- // put on local format instead of or in addation to
- pDataSource->CacheGlobalData(CServerDoc::m_cfPrivate,file.Detach());
- }
-
- /////////////////////////////////////////////////////////////////////////////
-