SVRVIEW.CPP
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:29k
源码类别:
Windows编程
开发平台:
Visual C++
- // svrview.cpp : implementation of the CServerView 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 "afxdlgs.h" // for FileOpen
- #include "$$root$$.h"
- #include "svrdoc.h"
- #include "svrview.h"
- #include "svritem.h"
- #include "zoomdlg.h"
- $$IF(WANTS_TEXTVIEW)
- #include "textview.h"
- $$ENDIF
- #ifdef _DEBUG
- #undef THIS_FILE
- static char BASED_CODE THIS_FILE[] = __FILE__;
- #endif
- CServerNode* NEAR CServerView::m_pDragNode = NULL;
- static int ReadString(CArchive& ar, char* pString, int nMaxLen);
- static BOOL FindItemRect(CDC* pDC, CServerNode* pItemFind, LPRECT lpRect,
- CPoint& ptStart, CServerNode* pRoot);
- static CServerNode* HitDetect(CDC* pDC, CPoint point,
- CPoint& ptStart, CServerNode* pRoot);
- /////////////////////////////////////////////////////////////////////////////
- // support for zooming
- static int NEAR rgiZoomFactor[] =
- {
- 25, 50, 75, 100, 125, 150, 175, 200, 250, 300
- };
- /////////////////////////////////////////////////////////////////////////////
- // CServerView
- IMPLEMENT_DYNCREATE(CServerView, CScrollView)
- BEGIN_MESSAGE_MAP(CServerView, CScrollView)
- //{{AFX_MSG_MAP(CServerView)
- ON_COMMAND(ID_CHANGE_NAME, OnChangeName)
- ON_COMMAND(ID_ADD_NODE, OnAddNode)
- ON_UPDATE_COMMAND_UI(ID_CHANGE_NAME, OnUpdateHasSel)
- ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
- ON_WM_LBUTTONDOWN()
- ON_WM_RBUTTONDOWN()
- ON_COMMAND(ID_IMPORT_TEXT, OnImportText)
- ON_COMMAND(ID_VIEW_ZOOMCUSTOM, OnViewZoomCustom)
- ON_COMMAND(ID_EDIT_CUT, OnEditCut)
- ON_WM_LBUTTONDBLCLK()
- ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
- ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE, OnUpdateEditPaste)
- ON_WM_CREATE()
- ON_COMMAND(ID_EDIT_CLEAR, OnEditClear)
- ON_COMMAND(ID_TREE_COLLAPSEBRANCH, OnTreeCollapsebranch)
- ON_COMMAND(ID_TREE_EXPANDALL, OnTreeExpandall)
- ON_COMMAND(ID_TREE_EXPANDBRANCH, OnTreeExpandbranch)
- ON_COMMAND(ID_TREE_EXPANDONELEVEL, OnTreeExpandonelevel)
- ON_UPDATE_COMMAND_UI(ID_TREE_COLLAPSEBRANCH, OnUpdateTreeCollapsebranch)
- ON_UPDATE_COMMAND_UI(ID_TREE_EXPANDONELEVEL, OnUpdateTreeExpandonelevel)
- ON_UPDATE_COMMAND_UI(ID_TREE_EXPANDALL, OnUpdateTreeExpandall)
- ON_UPDATE_COMMAND_UI(ID_TREE_EXPANDBRANCH, OnUpdateTreeExpandbranch)
- ON_WM_KEYDOWN()
- ON_UPDATE_COMMAND_UI(ID_ADD_NODE, OnUpdateHasSel)
- ON_UPDATE_COMMAND_UI(ID_EDIT_COPY, OnUpdateHasSel)
- ON_UPDATE_COMMAND_UI(ID_IMPORT_TEXT, OnUpdateHasSel)
- ON_UPDATE_COMMAND_UI(ID_EDIT_CUT, OnUpdateHasSel)
- ON_UPDATE_COMMAND_UI(ID_EDIT_CLEAR, OnUpdateHasSel)
- $$IF(WANTS_TEXTVIEW)
- ON_COMMAND(ID_VIEW_TEXT_VIEW, OnViewTextView)
- $$ENDIF
- ON_WM_SIZE()
- //}}AFX_MSG_MAP
- ON_COMMAND_RANGE(ID_VIEW_ZOOM25, ID_VIEW_ZOOM300, OnZoom)
- ON_UPDATE_COMMAND_UI_RANGE(ID_VIEW_ZOOM25, ID_VIEW_ZOOM300, OnUpdateZoom)
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CServerView construction/destruction
- CServerView::CServerView()
- {
- m_pSelectedNode = NULL;
- m_ptStart = CPoint(CX_MARGIN, CY_MARGIN); // upper left position
- // initialize zoom state (100% from size cache)
- m_zoomNum = CSize(100, 100);
- m_zoomDenom = CSize(100, 100);
- m_prevDropEffect = DROPEFFECT_NONE;
- }
- CServerView::~CServerView()
- {
- }
- /////////////////////////////////////////////////////////////////////////////
- // Attributes -- public
- void CServerView::SetSelection(CServerNode* pNewSel, CDC* pDC)
- {
- if (pNewSel == m_pSelectedNode)
- return; // already set
- InvalidateItem(m_pSelectedNode, pDC);
- m_pSelectedNode = pNewSel;
- InvalidateItem(m_pSelectedNode, pDC);
- }
- void CServerView::SetSelection(CServerNode* pNewSel)
- {
- CServerDC dc(this);
- SetSelection(pNewSel, &dc);
- }
- /////////////////////////////////////////////////////////////////////////////
- // Operations -- public
- void CServerView::SetScrollInfo()
- {
- CServerNode* pRoot = GetDocument()->m_pRoot;
- ASSERT(pRoot != NULL);
- //BLOCK: determine new scrolling sizes
- CSize sizeLine;
- CSize sizePage;
- CSize sizeTotal;
- {
- CServerDC dc(this);
- pRoot->CalcNodeSize(&dc, sizeLine);
- sizeLine.cx = sizeDefault.cx;
- sizeLine.cy += CY_SEPARATOR;
- sizePage.cx = sizeDefault.cx;
- sizePage.cy = sizeLine.cy * 10;
- // set the scroll sizes dependent on the zoom factor
- dc.LPtoDP(&sizePage);
- dc.LPtoDP(&sizeLine);
- sizeTotal = CalcActualViewSize(&dc);
- // subtract out the right and bottom margins
- // these are not interesting and this way we avoid
- // some problems with nonlinear scaling of fonts
- CSize sizeMargin(CX_MARGIN, CY_MARGIN);
- CRect rect(CPoint(0, 0), sizeMargin);
- dc.LPtoDP(rect);
- sizeTotal -= rect.Size();
- }
- SetScrollSizes(MM_TEXT, sizeTotal, sizePage, sizeLine);
- }
- BOOL CServerView::SetZoomFactor(CSize zoomNum, CSize zoomDenom)
- {
- if (zoomDenom != m_zoomDenom || zoomNum != m_zoomNum)
- {
- // sync to new zoom factor
- m_zoomNum = zoomNum;
- m_zoomDenom = zoomDenom;
- // resync to new sizes
- Invalidate();
- return TRUE;
- }
- return FALSE;
- }
- void CServerView::UpdateServerView()
- {
- CServerDoc* pDoc = GetDocument();
- pDoc->SetModifiedFlag();
- pDoc->UpdateAllItems(NULL);
- pDoc->UpdateAllViews(NULL);
- }
- CSize CServerView::CalcActualViewSize(CDC *pDC)
- {
- return CalcActualItemSize(GetDocument()->m_pRoot, pDC);
- }
- CSize CServerView::CalcActualItemSize(CServerNode* pItem, CDC *pDC)
- {
- CSize sizeTotal(0, 0);
- CPoint ptStart = m_ptStart;
- pItem->CalcBounding(pDC, ptStart, sizeTotal);
- sizeTotal.cx += CX_MARGIN;
- // sizeTotal is the extent in logical coords
- // convert from logical to device
- CRect rc(CPoint(0,0),sizeTotal);
- pDC->LPtoDP(rc);
- return rc.Size();
- }
- CSize CServerView::CalcScaledViewSize()
- {
- return CalcScaledItemSize(GetDocument()->m_pRoot);
- }
- CSize CServerView::CalcScaledItemSize(CServerNode* pItem)
- {
- CServerDC dc(this);
- // set extent to 100%
- dc.SetViewportExt(CSize(1,1));
- dc.SetWindowExt(CSize(1,1));
- CSize sizeTotal(0, 0);
- CPoint ptStart = m_ptStart;
- pItem->CalcBounding(&dc, ptStart, sizeTotal);
- sizeTotal.cx += CX_MARGIN;
- // sizeTotal is the native extent in device coords
- sizeTotal.cx = MulDiv(sizeTotal.cx,m_zoomNum.cx,m_zoomDenom.cx);
- sizeTotal.cy = MulDiv(sizeTotal.cy,m_zoomNum.cy,m_zoomDenom.cy);
- return sizeTotal;
- }
- CServerNode* CServerView::DoPasteItem(COleDataObject* pDataObject)
- {
- ASSERT(pDataObject != NULL);
- ASSERT_VALID(this);
- ASSERT(m_pSelectedNode != NULL);
- BeginWaitCursor();
- CServerNode* pItem = new CServerNode(GetDocument());
- ASSERT_VALID(pItem);
- TRY
- {
- if (pDataObject->IsDataAvailable(CServerDoc::m_cfPrivate))
- DoPasteNative(pDataObject,pItem);
- else if (pDataObject->IsDataAvailable(CF_TEXT))
- DoPasteText(pDataObject,pItem);
- else
- AfxThrowNotSupportedException();
- }
- CATCH_ALL(e)
- {
- // general cleanup
- TRACE0("failed to embed/link an OLE objectn");
- delete pItem;
- pItem = NULL;
- }
- END_CATCH_ALL
- EndWaitCursor();
- // update the document and views
- SetSelection(pItem);
- return pItem;
- }
- void CServerView::DoPasteNative(COleDataObject *pDataObject,CServerNode *pItem)
- {
- ASSERT(m_pSelectedNode != NULL);
- // get file refering to clipboard data
- CFile *pFile = pDataObject->GetFileData(CServerDoc::m_cfPrivate);
- if (pFile == NULL)
- return;
- // connect the file to the archive and read the contents
- CArchive ar(pFile, CArchive::load);
- ar.m_pDocument = GetDocument(); // for COleClientItem serialize
- pItem->Serialize(ar);
- ar.Close();
- delete pFile;
- // add the item to selected node
- m_pSelectedNode->m_listChild.AddHead(pItem);
- }
- void CServerView::DoPasteText(COleDataObject *pDataObject, CServerNode*)
- {
- ASSERT(m_pSelectedNode != NULL);
- // get file refering to clipboard data
- CFile *pFile = pDataObject->GetFileData(CF_TEXT);
- if (pFile == NULL)
- return;
- // connect the file to the archive and read the contents
- CArchive ar(pFile, CArchive::load);
- DoImportText(ar);
- ar.Close();
- delete pFile;
- }
- void CServerView::DoImportText(CArchive &ar)
- {
- // read in lines appending items from this node
- char szNode[256];
- #ifdef _UNICODE
- TCHAR szT[256];
- #endif
- int nCurLevel = 0;
- CServerNode* parents[MAX_LEVEL];
- parents[0] = m_pSelectedNode; // must have a parent at the current level
- while (ReadString(ar, szNode, sizeof(szNode)) != NULL)
- {
- int cch = strlen(szNode);
- if (cch == 0)
- continue;
- if (szNode[cch-1] != 'n')
- {
- AfxMessageBox(
- _T("Text file contains too long a line - aborting readn"));
- break; // leaves items loaded so far
- }
- szNode[cch-1] = ' ';
- // check the indentation level
- char* pch = szNode;
- while (*pch == 't')
- pch++;
- int nLevel = (pch - szNode)+1;
- ASSERT(nLevel >= 1); // levels are 1 based, 0 is the root
- if (*pch == ' ')
- continue; // skip blank lines
- if (nLevel > nCurLevel + 1 || nLevel >= MAX_LEVEL)
- {
- AfxMessageBox(
- _T("Text file contains too many tabs = aborting readn"));
- break; // leaves items loaded so far
- }
- #ifdef _UNICODE
- _mbstowcsz(szT, pch, sizeof(szT)/sizeof(szT[0]));
- parents[nLevel] = parents[nLevel-1]->CreateChildNode(szT);
- #else
- parents[nLevel] = parents[nLevel-1]->CreateChildNode(pch);
- #endif
- nCurLevel = nLevel;
- }
- if (nCurLevel == 0)
- return; // nothing added
- UpdateServerView();
- }
- void CServerView::ScrollToItem(CServerNode *pItem, BOOL bScrollUp)
- {
- CServerDC dc(this);
- CRect rect;
- CPoint ptStart = m_ptStart;
- if (FindItemRect(&dc, pItem, &rect, ptStart, GetDocument()->m_pRoot))
- {
- CRect rc;
- dc.LPtoDP(rect);
- if (GetDocument()->IsInPlaceActive())
- {
- CRect rcPos,rcClip;
- GetDocument()->GetItemPosition(&rcPos);
- GetDocument()->GetItemClipRect(&rcClip);
- rc.IntersectRect(&rcPos,&rcClip);
- rc.OffsetRect(-rcPos.left,-rcPos.top);
- if (!rc.PtInRect(rect.TopLeft()) || !rc.PtInRect(rect.BottomRight()))
- {
- CSize size(0, 0);
- // scroll inplace site
- if (bScrollUp)
- size.cy = rect.top - rc.top;
- else
- size.cy = rect.bottom + rcPos.top - rcClip.bottom;
- GetDocument()->ScrollContainerBy(size);
- }
- }
- else
- {
- GetClientRect(rc);
- if (!rc.PtInRect(rect.TopLeft()) || !rc.PtInRect(rect.BottomRight()))
- {
- CPoint ptDevScroll = GetDeviceScrollPosition();
- if (bScrollUp)
- ScrollToPosition(CPoint(0,rect.top + ptDevScroll.y));
- else
- ScrollToPosition(
- CPoint(0,ptDevScroll.y + rect.bottom - rc.Height()));
- }
- }
- }
- }
- void CServerView::Locate(int nCount, BOOL bScrollUp)
- {
- CServerNode* pRoot = GetDocument()->m_pRoot;
- CServerNode* pItem = pRoot;
- if (m_pSelectedNode == NULL)
- SetSelection(pRoot);
- if (nCount == 0) // goto top or bottom depending on direction
- {
- if (bScrollUp)
- pItem = pRoot;
- else
- {
- while (pItem->HasChildren())
- pItem = (CServerNode *)(pItem->m_listChild.GetTail());
- }
- }
- else if (bScrollUp)
- {
- pItem = m_pSelectedNode;
- while (nCount--)
- pItem = pRoot->GetPrev(pItem);
- }
- else // going down
- {
- pItem = m_pSelectedNode;
- while (nCount--)
- pItem = pRoot->GetNext(pItem);
- }
- ScrollToItem(pItem, bScrollUp);
- SetSelection(pItem);
- UpdateWindow();
- }
- void CServerView::InvalidateItem(CServerNode *pItem, CDC* pDC)
- {
- if (pItem != NULL)
- {
- CRect rect;
- CPoint ptStart = m_ptStart;
- if (FindItemRect(pDC, pItem, &rect, ptStart, GetDocument()->m_pRoot))
- {
- pDC->LPtoDP(rect);
- InvalidateRect(rect, FALSE);
- }
- }
- }
- void CServerView::InvalidateItem(CServerNode* pItem)
- {
- CServerDC dc(this);
- InvalidateItem(pItem, &dc);
- }
- void CServerView::ToggleSelectedItem()
- {
- if (m_pSelectedNode != NULL && m_pSelectedNode->HasChildren())
- {
- if (m_pSelectedNode->m_bHideChildren)
- OnTreeExpandonelevel();
- else
- OnTreeCollapsebranch();
- }
- }
- /////////////////////////////////////////////////////////////////////////////
- // Implementation
- void CServerView::OnDraw(CDC* pDC)
- {
- if (GetDocument()->DrawTree(pDC, m_ptStart, m_pSelectedNode) == -1)
- TRACE0("Error: CServerDoc::DrawTree failed!!n");
- }
- void CServerView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
- {
- CScrollView::OnUpdate(pSender, lHint, pHint);
- CServerDoc* pDoc = GetDocument();
- CServerNode* pRoot = pDoc->m_pRoot;
- ASSERT(pRoot != NULL);
- if (m_pSelectedNode == NULL)
- m_pSelectedNode = pRoot;
- if (pDoc->IsInPlaceActive())
- {
- ASSERT_VALID(pDoc->m_pRoot);
- CRect rect;
- pDoc->GetItemPosition(rect);
- // adjust rect for new size of view
- rect.BottomRight() = rect.TopLeft() + CalcScaledViewSize();
- pDoc->RequestPositionChange(rect);
- // may resize the window before returning
- }
- SetScrollInfo();
- }
- void CServerView::OnInitialUpdate()
- {
- // initialize zoom state (100% from size cache)
- m_zoomNum = CSize(100, 100);
- m_zoomDenom = CSize(100, 100);
- // call base class last (will call OnUpdate)
- CScrollView::OnInitialUpdate();
- }
- void CServerView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo)
- {
- CScrollView::OnPrepareDC(pDC, pInfo);
- pDC->SetMapMode(MM_ANISOTROPIC);
- pDC->SetViewportExt(m_zoomNum);
- pDC->SetWindowExt(m_zoomDenom);
- }
- void CServerView::SelectAtPoint(CPoint point, CPoint& pointHit)
- {
- CServerDC dc(this);
- // change the selection as appropriate
- pointHit = m_ptStart;
- CServerNode* pSelection = HitDetect(&dc, point, pointHit,
- GetDocument()->m_pRoot);
- // now set the selection to new hit-tested node
- SetSelection(pSelection, &dc);
- }
- void CServerView::DoBranch(CServerNode *pItem, BOOL bHide)
- {
- if (pItem->HasChildren())
- {
- pItem->m_bHideChildren = bHide;
- POSITION pos = pItem->m_listChild.GetHeadPosition();
- while (pos != NULL)
- DoBranch((CServerNode *)pItem->m_listChild.GetNext(pos),bHide);
- }
- }
- BOOL CServerView::OnDrop(COleDataObject* pDataObject, DROPEFFECT, CPoint)
- {
- ASSERT_VALID(this);
- OnDragLeave();
- if (DoPasteItem(pDataObject) != NULL)
- {
- UpdateServerView();
- return TRUE;
- }
- else
- return FALSE;
- }
- DROPEFFECT CServerView::OnDragEnter(COleDataObject* pDataObject,
- DWORD grfKeyState, CPoint point)
- {
- ASSERT(m_prevDropEffect == DROPEFFECT_NONE);
- return OnDragOver(pDataObject, grfKeyState, point);
- }
- DROPEFFECT CServerView::OnDragOver(COleDataObject* pDataObject,
- DWORD grfKeyState, CPoint point)
- {
- DROPEFFECT dropEffect = DROPEFFECT_NONE;
- if (pDataObject->IsDataAvailable(CServerDoc::m_cfPrivate) ||
- pDataObject->IsDataAvailable(CF_TEXT))
- {
- CPoint pointHit;
- SelectAtPoint(point, pointHit);
- UpdateWindow();
- if (m_pSelectedNode != NULL)
- {
- // don't allow a node to drop on itself
- if (m_pDragNode == m_pSelectedNode)
- dropEffect = DROPEFFECT_NONE;
- // if drop target is a child of drag source
- // then don't drop
- else if (m_pDragNode != NULL && m_pDragNode->IsChild(m_pSelectedNode))
- dropEffect = DROPEFFECT_NONE;
- // check for force link
- else if ((grfKeyState & (MK_CONTROL|MK_SHIFT)) == (MK_CONTROL|MK_SHIFT))
- dropEffect = DROPEFFECT_COPY;
- // check for force copy
- else if ((grfKeyState & MK_CONTROL) == MK_CONTROL)
- dropEffect = DROPEFFECT_COPY;
- // check for force move
- else if ((grfKeyState & MK_ALT) == MK_ALT)
- dropEffect = DROPEFFECT_MOVE;
- // if m_pDragNode == NULL then not dropping on self
- // so make default effect be copy
- // if dropping on self make default be move
- else
- dropEffect = (m_pDragNode == NULL) ? DROPEFFECT_COPY :
- DROPEFFECT_MOVE;
- }
- }
- m_prevDropEffect = dropEffect;
- return dropEffect;
- }
- void CServerView::OnDragLeave()
- {
- m_prevDropEffect = DROPEFFECT_NONE;
- }
- /////////////////////////////////////////////////////////////////////////////
- // CServerView commands
- void CServerView::OnUpdateHasSel(CCmdUI* pCmdUI)
- {
- pCmdUI->Enable(m_pSelectedNode != NULL);
- }
- void CServerView::OnChangeName()
- {
- if (m_pSelectedNode != NULL && m_pSelectedNode->PromptChangeNode())
- {
- GetDocument()->SetModifiedFlag();
- GetDocument()->UpdateAllItems(NULL);
- GetDocument()->UpdateAllViews(NULL);
- }
- }
- void CServerView::OnAddNode()
- {
- if (m_pSelectedNode == NULL)
- AfxThrowNotSupportedException();
- CServerNode* pNew;
- if ((pNew = m_pSelectedNode->PromptNewChildNode()) == NULL)
- return;
- SetSelection(pNew);
- UpdateServerView();
- }
- void CServerView::OnEditCopy()
- {
- ASSERT_VALID(this);
- if (m_pSelectedNode == NULL)
- return;
- // get a server item suitable to generate the clipboard data
- CServerItem* pItem = m_pSelectedNode->m_pServerItem;
- if (pItem == NULL)
- pItem = new CServerItem(GetDocument(), m_pSelectedNode);
- ASSERT_VALID(pItem);
- pItem->CopyToClipboard(TRUE);
- }
- void CServerView::OnLButtonDown(UINT, CPoint point)
- {
- // m_pDragNode != NULL only when drag in progress
- ASSERT(m_pDragNode == NULL);
- CPoint pointHit;
- SelectAtPoint(point, pointHit);
- UpdateWindow();
- // maybe start drag drop operation on selection
- if (m_pSelectedNode != NULL)
- {
- // record current selection because a drop back in same view
- // will change the current selection
- m_pDragNode = m_pSelectedNode;
- // determine rectangle of object we'll be dragging
- CServerDC dc(this);
- CSize size = CalcActualItemSize(m_pSelectedNode, &dc);
- CRect rect(pointHit, size);
- // get a server item suitable to generate the clipboard data
- CServerItem* pItem = m_pSelectedNode->m_pServerItem;
- if (pItem == NULL)
- pItem = new CServerItem(GetDocument(), m_pSelectedNode);
- ASSERT_VALID(pItem);
- // rect must be in screen co-ordinates
- dc.LPtoDP(&rect);
- CPoint ptOffset = point - rect.TopLeft();
- ClientToScreen(&rect);
- // drag the object
- if (pItem->DoDragDrop(rect, ptOffset, TRUE,
- DROPEFFECT_COPY | DROPEFFECT_MOVE) == DROPEFFECT_MOVE)
- {
- // the object was moved, need to delete/move depending on dest
- CServerDoc* pDoc = GetDocument();
- if (m_pSelectedNode == m_pDragNode)
- SetSelection(pDoc->m_pRoot->GetPrev(m_pSelectedNode));
- if (m_pDragNode == pDoc->m_pRoot)
- pDoc->m_pRoot->InitRootNode();
- else
- pDoc->m_pRoot->FindAndDelete(m_pDragNode);
- // if drop was not back in same view clear selected node
- UpdateServerView();
- }
- m_pDragNode = NULL;
- }
- }
- void CServerView::OnRButtonDown(UINT /*nFlags*/, CPoint point)
- {
- // make sure window is active
- GetParentFrame()->ActivateFrame();
- CPoint pointHit;
- SelectAtPoint(point, pointHit); // select node first
- UpdateWindow();
- int iSub;
- if (m_pSelectedNode == NULL ||
- (iSub = m_pSelectedNode->GetPopupMenuIndex()) == -1)
- return; // nothing if no selection or no popup
- CMenu popups;
- if (!popups.LoadMenu(IDR_POPUPS))
- AfxThrowResourceException();
- CMenu* pMenu = popups.GetSubMenu(iSub);
- ASSERT(pMenu != NULL);
- ClientToScreen(&point);
- pMenu->TrackPopupMenu(TPM_CENTERALIGN | TPM_RIGHTBUTTON,
- point.x, point.y, AfxGetMainWnd());
- }
- void CServerView::OnImportText()
- {
- if (m_pSelectedNode == NULL)
- AfxThrowNotSupportedException();
- CFileDialog dlg(TRUE, _T("txt"), NULL,
- OFN_FILEMUSTEXIST | OFN_HIDEREADONLY,
- _T("Text Files (*.txt)|*.txt|All Files (*.*)|*.*||"));
- if (dlg.DoModal() != IDOK)
- return; // stay with old data file
- OpenTextFile(dlg.GetPathName());
- }
- void CServerView::OpenTextFile(CString Name)
- {
- CFile file;
- if (!file.Open(Name, CFile::modeRead))
- {
- AfxMessageBox(_T("Failed to open text file"));
- return;
- }
- CArchive ar(&file,CArchive::load);
- DoImportText(ar);
- ar.Close();
- file.Close();
- }
- static int ReadString(CArchive& ar, char* pString, int nMaxLen)
- {
- int nCount = 0;
- char ch;
- pString[nCount] = (char)0;
- TRY
- {
- do
- {
- ar >> (BYTE&)ch;
- // watch out for ^Z (EOF under DOS)
- if (ch == 0x1A)
- break;
- // combine "rn" pair into single "n"
- if (ch == 'n' && nCount != 0 && pString[nCount-1] == 'r')
- nCount--;
- //Remove any extra r
- if (ch == 'r' && nCount != 0 && pString[nCount-1] == 'r')
- nCount--;
- pString[nCount++] = ch;
- } while (nCount < nMaxLen-1 && ch != 'n');
- }
- END_TRY
- // insert newline if missing
- if (nCount != 0 && pString[nCount-1] != 'n' && nCount < nMaxLen-1)
- pString[nCount++] = 'n';
- pString[nCount] = (char)0;
- return nCount;
- }
- /////////////////////////////////////////////////////////////////////////////
- // Zooming user interface
- void CServerView::OnZoom(UINT nID)
- {
- ASSERT(nID >= ID_VIEW_ZOOM25 && nID <= ID_VIEW_ZOOM300);
- CSize zoomDenom;
- CSize zoomNum;
- // all of our zoom factors use denominator of 100
- zoomDenom.cx = 100;
- zoomDenom.cy = 100;
- // get zoom factor numerator and set it
- ASSERT(nID-ID_VIEW_ZOOM25 < sizeof(rgiZoomFactor)/sizeof(rgiZoomFactor[0]));
- int iZoomFactor = rgiZoomFactor[nID-ID_VIEW_ZOOM25];
- zoomNum.cx = iZoomFactor;
- zoomNum.cy = iZoomFactor;
- // change the zoom factor to new zoom factor
- SetZoomFactor(zoomNum, zoomDenom);
- SetScrollInfo();
- }
- void CServerView::OnUpdateZoom(CCmdUI* pCmdUI)
- {
- UINT nID = pCmdUI->m_nID;
- if (m_zoomDenom.cx == 100 && m_zoomDenom.cy == 100 &&
- nID != ID_VIEW_ZOOMCUSTOM)
- {
- ASSERT(nID-ID_VIEW_ZOOM25 <
- sizeof(rgiZoomFactor)/sizeof(rgiZoomFactor[0]));
- int iZoomFactor = rgiZoomFactor[nID-ID_VIEW_ZOOM25];
- if (iZoomFactor == m_zoomNum.cx && iZoomFactor == m_zoomNum.cy)
- {
- pCmdUI->SetCheck(TRUE);
- return;
- }
- }
- // default to not checked
- pCmdUI->SetCheck(FALSE);
- }
- void CServerView::OnViewZoomCustom()
- {
- // prepare dialog data
- CZoomDlg dlg;
- dlg.m_zoomX = m_zoomNum.cx;
- dlg.m_zoomY = m_zoomNum.cy;
- // launch dialog
- if (dlg.DoModal() == IDOK)
- {
- // set new zoom factors
- CSize zoomNum(dlg.m_zoomX, dlg.m_zoomY);
- SetZoomFactor(zoomNum, m_zoomDenom);
- SetScrollInfo();
- }
- }
- /////////////////////////////////////////////////////////////////////////////
- void CServerView::OnEditCut()
- {
- ASSERT(m_pSelectedNode != NULL);
- CServerDoc* pDoc = GetDocument();
- OnEditCopy();
- if (m_pSelectedNode == pDoc->m_pRoot)
- pDoc->m_pRoot->InitRootNode();
- else if (pDoc->m_pRoot->FindAndDelete(m_pSelectedNode))
- m_pSelectedNode = NULL;
- UpdateServerView();
- }
- void CServerView::OnLButtonDblClk(UINT /*nFlags*/, CPoint point)
- {
- CPoint pointHit;
- SelectAtPoint(point, pointHit);
- ToggleSelectedItem();
- }
- void CServerView::OnEditPaste()
- {
- COleDataObject clipboardData;
- clipboardData.AttachClipboard();
- DoPasteItem(&clipboardData);
- UpdateServerView();
- }
- void CServerView::OnUpdateEditPaste(CCmdUI* pCmdUI)
- {
- // determine if private or standard OLE formats are on the clipboard
- COleDataObject dataObj;
- BOOL bEnable = m_pSelectedNode != NULL &&
- dataObj.AttachClipboard() &&
- (dataObj.IsDataAvailable(CServerDoc::m_cfPrivate) ||
- dataObj.IsDataAvailable(CF_TEXT));
- // enable command based on availability
- pCmdUI->Enable(bEnable);
- }
- int CServerView::OnCreate(LPCREATESTRUCT lpCreateStruct)
- {
- if (CScrollView::OnCreate(lpCreateStruct) == -1)
- return -1;
- // register drop target
- m_dropTarget.Register(this);
- // setup scroll state so it is possible to calculate the extent
- SetScrollSizes(MM_TEXT, CSize(0, 0));
- return 0;
- }
- void CServerView::OnEditClear()
- {
- CServerNode* pRoot = GetDocument()->m_pRoot;
- if (m_pSelectedNode == NULL)
- return;
- if (m_pSelectedNode == pRoot)
- pRoot->InitRootNode();
- else
- {
- CServerNode *pItem = pRoot->GetPrev(m_pSelectedNode);
- if (pRoot->FindAndDelete(m_pSelectedNode))
- m_pSelectedNode = pRoot->GetNext(pItem);
- }
- UpdateServerView();
- }
- void CServerView::OnTreeCollapsebranch()
- {
- DoBranch(m_pSelectedNode,TRUE);
- UpdateServerView();
- }
- void CServerView::OnTreeExpandall()
- {
- DoBranch(GetDocument()->m_pRoot,FALSE);
- UpdateServerView();
- }
- void CServerView::OnTreeExpandbranch()
- {
- DoBranch(m_pSelectedNode,FALSE);
- UpdateServerView();
- }
- void CServerView::OnTreeExpandonelevel()
- {
- if (m_pSelectedNode->HasChildren())
- {
- m_pSelectedNode->m_bHideChildren = FALSE;
- UpdateServerView();
- }
- }
- void CServerView::OnUpdateTreeCollapsebranch(CCmdUI* pCmdUI)
- {
- pCmdUI->Enable(m_pSelectedNode != NULL && m_pSelectedNode->HasChildren() &&
- !m_pSelectedNode->m_bHideChildren);
- }
- void CServerView::OnUpdateTreeExpandonelevel(CCmdUI* pCmdUI)
- {
- pCmdUI->Enable(m_pSelectedNode != NULL && m_pSelectedNode->HasChildren() &&
- m_pSelectedNode->m_bHideChildren);
- }
- void CServerView::OnUpdateTreeExpandall(CCmdUI* pCmdUI)
- {
- pCmdUI->Enable(GetDocument()->m_pRoot != NULL &&
- GetDocument()->m_pRoot->HasChildren());
- }
- void CServerView::OnUpdateTreeExpandbranch(CCmdUI* pCmdUI)
- {
- pCmdUI->Enable(m_pSelectedNode != NULL && m_pSelectedNode->HasChildren());
- }
- void CServerView::OnKeyDown(UINT nChar, UINT /*nRepCnt*/, UINT /*nFlags*/)
- {
- switch (nChar)
- {
- case VK_RETURN:
- ToggleSelectedItem();
- break;
- case VK_UP:
- Locate(1, TRUE);
- break;
- case VK_DOWN:
- Locate(1, FALSE);
- break;
- case VK_HOME:
- Locate(0, TRUE);
- break;
- case VK_END:
- Locate(0, FALSE);
- break;
- case VK_PRIOR:
- Locate(10, TRUE);
- break;
- case VK_NEXT:
- Locate(10, FALSE);
- break;
- }
- }
- void CServerView::OnSize(UINT nType, int cx, int cy)
- {
- // update scroll bar size before handling the size message
- // (this avoids multiple updates during in-place activation)
- SetScrollInfo();
- CScrollView::OnSize(nType, cx, cy);
- }
- /////////////////////////////////////////////////////////////////////////////
- // CServerDC class -- helper for setting up and cleaning up DC
- CServerDC::CServerDC(CServerView *pView) : CClientDC(pView)
- {
- pView->OnPrepareDC(this);
- pOldFont = pView->GetDocument()->SelectDocFont(this, font);
- }
- CServerDC::~CServerDC()
- {
- if (pOldFont != NULL)
- SelectObject(pOldFont);
- }
- /////////////////////////////////////////////////////////////////////////////
- // non-member static functions
- // calculate the bounding rect for a given item in the context of this view
- static BOOL FindItemRect(CDC* pDC, CServerNode* pItemFind, LPRECT lpRect,
- CPoint& ptStart, CServerNode* pRoot)
- {
- ASSERT(pItemFind != NULL);
- ASSERT(lpRect != NULL);
- ASSERT(pRoot != NULL);
- CSize sizeNode;
- pRoot->CalcNodeSize(pDC, sizeNode);
- if (pItemFind == pRoot)
- {
- // item rect does not include separator
- lpRect->right = (lpRect->left = ptStart.x) + sizeNode.cx;
- lpRect->bottom = (lpRect->top = ptStart.y) + sizeNode.cy;
- return TRUE;
- }
- CPoint pt(CX_INDENT, CY_SEPARATOR);
- ptStart.x += CX_INDENT; // not essential for calculation
- ptStart.y += sizeNode.cy + CY_SEPARATOR;
- // check the kids
- if (!pRoot->m_bHideChildren)
- {
- POSITION pos = pRoot->m_listChild.GetHeadPosition();
- while (pos != NULL)
- {
- CServerNode* pChild = (CServerNode*) (pRoot->m_listChild.GetNext(pos));
- if (FindItemRect(pDC, pItemFind, lpRect, ptStart, pChild))
- return TRUE; // found
- }
- }
- ptStart.x -= CX_INDENT;
- return FALSE;
- }
- // calculate the bounding rect for a given item in the context of this view
- static CServerNode* HitDetect(CDC* pDC, CPoint point,
- CPoint& ptStart, CServerNode* pRoot)
- {
- ASSERT(pRoot != NULL);
- CSize sizeNode;
- pRoot->CalcNodeSize(pDC, sizeNode);
- CRect rect(ptStart, sizeNode);
- pDC->LPtoDP(rect);
- if (rect.PtInRect(point))
- return pRoot;
- ptStart.x += CX_INDENT;
- ptStart.y += sizeNode.cy + CY_SEPARATOR;
- CPoint pt = ptStart;
- pDC->LPtoDP(&pt);
- if (pt.y >= point.y)
- return FALSE; // no point in looking any lower
- // check the kids
- if (!pRoot->m_bHideChildren)
- {
- POSITION pos = pRoot->m_listChild.GetHeadPosition();
- while (pos != NULL)
- {
- CServerNode* pChild = (CServerNode*) (pRoot->m_listChild.GetNext(pos));
- CServerNode* pItem = HitDetect(pDC, point, ptStart, pChild);
- if (pItem != NULL)
- return pItem; // found
- }
- }
- ptStart.x -= CX_INDENT;
- return NULL;
- }
- /////////////////////////////////////////////////////////////////////////////
- // CServerView diagnostics
- #ifdef _DEBUG
- void CServerView::AssertValid() const
- {
- CScrollView::AssertValid();
- }
- void CServerView::Dump(CDumpContext& dc) const
- {
- CScrollView::Dump(dc);
- }
- #endif //_DEBUG
- $$IF(WANTS_TEXTVIEW)
- void CServerView::OnViewTextView()
- {
- // Show the active document in text view.
- CServerDoc* pServerDoc = GetDocument();
- CDocument * pNewDoc ;
- pNewDoc = ((CServerApp *)AfxGetApp())->pDocTxtTemplate->OpenDocumentFile(NULL);
- //Detach the view from the newly created doc and attach it to the CServerDoc document
- POSITION pos = pNewDoc->GetFirstViewPosition() ;
- CTextView * pTxtvw = ( CTextView *)pNewDoc->GetNextView(pos) ;
- pNewDoc->RemoveView(pTxtvw) ;
- pServerDoc->AddView(pTxtvw) ;
- pTxtvw->RedrawText() ; // Do an initial draw of textview
- }
- void CServerView::CreateTextView()
- {
- OnViewTextView() ;
- }
- $$ENDIF //WANTS_TEXTVIEW