MarkupView.cpp
资源名称:CMarkup.rar [点击查看]
上传用户:hawkcdm
上传日期:2013-02-10
资源大小:411k
文件大小:17k
源码类别:
xml/soap/webservice
开发平台:
Visual C++
- // MarkupView.cpp : implementation of the CMarkupView class
- //
- // Markup Release 6.1 Lite
- // Copyright (C) 1999-2001 First Objective Software, Inc. All rights reserved
- // This entire notice must be retained in this source code
- // Redistributing this source code requires written permission
- // This software is provided "as is", with no warranty.
- // Latest fixes enhancements and documentation at www.firstobject.com
- #include "stdafx.h"
- #include "MarkupApp.h"
- #include "MarkupDoc.h"
- #include "MarkupView.h"
- #define IDC_MARKUP_TREE 1020
- #define IDC_MARKUP_EDIT 1021
- #define IDC_MARKUP_DIVIDER 1022
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- /////////////////////////////////////////////////////////////////////////////
- // CMarkupView
- IMPLEMENT_DYNCREATE(CMarkupView, CView)
- BEGIN_MESSAGE_MAP(CMarkupView, CView)
- //{{AFX_MSG_MAP(CMarkupView)
- ON_WM_CREATE()
- ON_WM_SIZE()
- ON_COMMAND(ID_MARKUP_FIND, OnMarkupFind)
- ON_COMMAND(ID_MARKUP_ADD, OnMarkupAdd)
- ON_COMMAND(ID_MARKUP_ADD_CHILD, OnMarkupAddChild)
- ON_COMMAND(ID_MARKUP_ADD_ATTRIB, OnMarkupAddAttrib)
- ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
- ON_COMMAND(ID_EDIT_CUT, OnEditCut)
- ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
- ON_COMMAND(ID_EDIT_UNDO, OnEditUndo)
- ON_UPDATE_COMMAND_UI(ID_EDIT_UNDO, OnUpdateEditUndo)
- //}}AFX_MSG_MAP
- // Standard printing commands
- ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
- ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
- ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
- ON_EN_CHANGE(IDC_MARKUP_EDIT, OnChangeEdit)
- ON_MESSAGE( WM_APP, OnAppMessage )
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CMarkupView construction/destruction
- CMarkupView::CMarkupView()
- {
- m_nAddAttrib = 0;
- }
- CMarkupView::~CMarkupView()
- {
- }
- BOOL CMarkupView::PreCreateWindow(CREATESTRUCT& cs)
- {
- // TODO: Modify the Window class or styles here by modifying
- // the CREATESTRUCT cs
- return CView::PreCreateWindow(cs);
- }
- /////////////////////////////////////////////////////////////////////////////
- // CMarkupView drawing
- void CMarkupView::OnDraw(CDC* pDC)
- {
- UNREFERENCED_PARAMETER(pDC);
- CMarkupDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- }
- /////////////////////////////////////////////////////////////////////////////
- // CMarkupView printing
- BOOL CMarkupView::OnPreparePrinting(CPrintInfo* pInfo)
- {
- // default preparation
- return DoPreparePrinting(pInfo);
- }
- void CMarkupView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
- {
- // TODO: add extra initialization before printing
- }
- void CMarkupView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
- {
- // TODO: add cleanup after printing
- }
- /////////////////////////////////////////////////////////////////////////////
- // CMarkupView diagnostics
- #ifdef _DEBUG
- void CMarkupView::AssertValid() const
- {
- CView::AssertValid();
- }
- void CMarkupView::Dump(CDumpContext& dc) const
- {
- CView::Dump(dc);
- }
- CMarkupDoc* CMarkupView::GetDocument() // non-debug version is inline
- {
- ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMarkupDoc)));
- return (CMarkupDoc*)m_pDocument;
- }
- #endif //_DEBUG
- /////////////////////////////////////////////////////////////////////////////
- // CMarkupView message handlers
- void CMarkupView::OnInitialUpdate()
- {
- m_pXML = &GetDocument()->m_doc;
- CView::OnInitialUpdate();
- // Maximize first time
- static BOOL bFirst = TRUE;
- if ( bFirst )
- {
- bFirst = FALSE;
- GetParent()->ShowWindow( SW_MAXIMIZE );
- }
- // Divider
- m_divider.m_nFractionOf1000 = 350;
- m_divider.m_enumOrientation = m_divider.MoveHorizontal;
- // Initial resize
- CRect rect;
- GetClientRect( &rect );
- CalcSize( rect.Width(), rect.Height() );
- // Text
- const int nMax = 64000; // Win 95 limit
- m_edit.SetLimitText( nMax );
- CString csText = GetDocument()->m_csText;
- if ( csText.GetLength() > nMax )
- AfxMessageBox( _T("Document is larger than edit buffer maximum") );
- m_edit.SetWindowText( csText );
- GetDocument()->SetParsedFlag( TRUE );
- GetDocument()->SetModifiedFlag( FALSE );
- }
- void CMarkupView::GetEditText( CString& csDoc )
- {
- if ( m_edit.GetSafeHwnd() )
- m_edit.GetWindowText( csDoc );
- }
- CString CMarkupView::SetEditTextFromDoc()
- {
- // Set document in rich edit control
- CString csDoc = m_pXML->GetDoc();
- m_edit.SetWindowText( csDoc );
- GetDocument()->m_csText = csDoc;
- GetDocument()->SetParsedFlag( TRUE );
- return csDoc;
- }
- int CMarkupView::OnCreate(LPCREATESTRUCT lpCreateStruct)
- {
- if (CView::OnCreate(lpCreateStruct) == -1)
- return -1;
- // Create controls
- int nFlags = WS_VISIBLE|WS_CHILD|WS_GROUP;
- if ( ! m_tree.Create( nFlags|TVS_LINESATROOT|TVS_HASLINES|TVS_HASBUTTONS,
- CRect(0,0,0,0), this, IDC_MARKUP_TREE ) )
- return -1;
- m_ilTree.Create(IDB_IL_TREE,16,0,RGB(255,255,255));
- m_tree.SetImageList(&m_ilTree,TVSIL_NORMAL);
- if ( ! m_divider.CreateEx(WS_EX_DLGMODALFRAME,_T("STATIC"),NULL,nFlags|SS_NOTIFY,
- CRect(0,0,0,0),this,IDC_MARKUP_DIVIDER) )
- return -1;
- nFlags = WS_CHILD|WS_VISIBLE|ES_MULTILINE|ES_WANTRETURN|WS_VSCROLL;
- if ( ! m_edit.Create( nFlags, CRect(0,0,0,0), this, IDC_MARKUP_EDIT ) )
- return -1;
- // Get default system font
- HFONT hSystemFont = (HFONT)GetStockObject(SYSTEM_FONT);
- LOGFONT systemFont;
- VERIFY(::GetObject(hSystemFont, sizeof(LOGFONT), (void*)&systemFont));
- // Set a Unicode font as the default
- // If you have a font that does not support the unicode characters you
- // are trying to view, then the characters appear as blocks or blanks
- // If unicode is not desired replace with the following
- // m_font.CreateFontIndirect(&systemFont);
- LOGFONT logFont; memset(&logFont, 0, sizeof(LOGFONT));
- logFont.lfHeight = systemFont.lfHeight + 1;
- logFont.lfWeight = FW_NORMAL;
- logFont.lfCharSet = DEFAULT_CHARSET;
- lstrcpy(logFont.lfFaceName, _T("Lucida Sans Unicode"));
- if ( ! m_font.CreateFontIndirect(&logFont) )
- m_font.CreateFontIndirect(&systemFont);
- m_edit.SetFont( &m_font );
- return 0;
- }
- void CMarkupView::CalcSize( int cx, int cy )
- {
- CRect rectBorder( 0, 0, cx, cy );
- CRect rect( rectBorder );
- int nOffset = m_divider.CalculateOffset( rectBorder.Width() );
- rect.right = rect.left + nOffset;
- m_tree.MoveWindow( &rect );
- rect.left += nOffset;
- rect.right = rect.left + m_divider.m_nWidth;
- m_divider.MoveWindow( &rect );
- rect.left = rect.right;
- rect.right = rectBorder.right;
- m_edit.MoveWindow( &rect );
- m_tree.Invalidate();
- m_divider.Invalidate();
- m_edit.Invalidate();
- }
- void CMarkupView::OnSize(UINT nType, int cx, int cy)
- {
- CView::OnSize(nType, cx, cy);
- if ( m_tree.GetSafeHwnd() )
- CalcSize( cx, cy );
- }
- void CMarkupView::GetNthWisePos( HTREEITEM hItem, CUIntArray& aNths )
- {
- // Populate aNths with sibling number on each level
- // if it is the first sibling, it is set to 1, etc
- while ( hItem )
- {
- HTREEITEM hParentItem = m_tree.GetParentItem( hItem );
- // Calculate Nth position on this level
- aNths.InsertAt( 0, 0, 1 );
- while ( hItem )
- {
- if ( m_tree.GetItemData(hItem) == 0 ) // It is Elem? (not attrib)
- ++aNths[0];
- hItem = m_tree.GetPrevSiblingItem( hItem );
- }
- // Remove if attribute
- if ( aNths[0] == 0 )
- aNths.RemoveAt( 0 );
- // Go to parent item
- hItem = hParentItem;
- }
- }
- void CMarkupView::SetPos( HTREEITEM hItem, BOOL bChild )
- {
- // Synchronize current position in XML document
- CUIntArray aNths;
- GetNthWisePos( hItem, aNths );
- m_pXML->ResetPos();
- int nLev = 0;
- int nCount = aNths[nLev];
- while ( nCount-- )
- m_pXML->FindElem();
- while ( ++nLev < aNths.GetSize() )
- {
- nCount = aNths[nLev];
- while ( nCount-- )
- m_pXML->FindChildElem();
- if ( nLev < aNths.GetSize() - 1 || ! bChild )
- m_pXML->IntoElem();
- }
- }
- void CMarkupView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
- {
- // Refill the tree after load or parse
- //
- UNREFERENCED_PARAMETER(pSender);
- UNREFERENCED_PARAMETER(pHint);
- UNREFERENCED_PARAMETER(lHint);
- CWaitCursor wait;
- if ( lHint )
- {
- m_edit.SetWindowText( GetDocument()->m_csText );
- GetDocument()->SetParsedFlag( TRUE );
- }
- // Find selected position
- HTREEITEM hSelectedItem = m_tree.GetSelectedItem();
- CUIntArray aNths;
- GetNthWisePos( hSelectedItem, aNths );
- hSelectedItem = NULL;
- // Traverse root and immediate children
- // plus any elements on path to the selected position
- m_tree.DeleteAllItems();
- m_pXML->ResetPos();
- BOOL bFound = m_pXML->FindElem();
- HTREEITEM hItem, hParentItem = TVI_ROOT;
- int nLev = 0;
- CUIntArray aCurNth;
- aCurNth.Add(1);
- while ( bFound )
- {
- hItem = AddElemToTree( hParentItem );
- // Select it if this is the correct item
- if ( nLev == aNths.GetSize()-1 && aCurNth[nLev] == aNths[nLev] )
- hSelectedItem = hItem;
- // Is there a child?
- bFound = ElemHasSubItems();
- // Above 2 levels, leave children blank to be filled on expand
- // Set flag indicating whether this element is on path to selection position
- BOOL bOnPath = nLev < aNths.GetSize() && aCurNth[nLev] == aNths[nLev];
- if ( bFound && nLev > 0 && ! bOnPath )
- {
- m_tree.InsertItem( _T(""), hItem );
- bFound = FALSE;
- }
- if ( bFound )
- {
- // Go into child
- m_pXML->ResetChildPos();
- if ( m_pXML->FindChildElem() )
- {
- hParentItem = hItem;
- m_pXML->IntoElem();
- ++nLev;
- aCurNth.SetAtGrow( nLev, 1 );
- }
- else
- {
- bFound = FALSE;
- }
- }
- if ( ! bFound )
- {
- // Look for more on same level or toward root
- while ( (bFound=m_pXML->FindElem()) == 0 && nLev )
- {
- m_tree.Expand( hParentItem, TVE_EXPAND );
- hParentItem = m_tree.GetParentItem(hParentItem);
- m_pXML->OutOfElem();
- --nLev;
- }
- ++aCurNth[nLev];
- }
- }
- // Was corresponding item to previously selected found?
- if ( hSelectedItem )
- {
- m_tree.SelectItem( hSelectedItem );
- m_tree.EnsureVisible( hSelectedItem );
- }
- }
- void CMarkupView::OnChangeEdit()
- {
- GetDocument()->SetModifiedFlag();
- GetDocument()->SetParsedFlag( FALSE );
- }
- LRESULT CMarkupView::OnAppMessage( WPARAM, LPARAM )
- {
- // Post WM_APP, then here set focus to m_edit
- // So that selection in document is visible
- m_edit.SetFocus();
- return 0;
- }
- HTREEITEM CMarkupView::AddElemToTree(HTREEITEM hParentItem)
- {
- HTREEITEM hItem;
- hItem = m_tree.InsertItem( m_pXML->GetTagName(), hParentItem );
- m_tree.SetItemData( hItem, 0 );
- return hItem;
- }
- BOOL CMarkupView::ElemHasSubItems()
- {
- BOOL bElemHasSubItems = FALSE;
- if ( m_pXML->FindChildElem() || ! m_pXML->GetChildData().IsEmpty() )
- bElemHasSubItems = TRUE;
- return bElemHasSubItems;
- }
- BOOL CMarkupView::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
- {
- // NMHDR is { HWND hwndFrom; UINT idFrom; UINT code; }
- NMHDR* pNMHDR = (NMHDR*)lParam;
- // Double-click on tree
- if ( pNMHDR->code == NM_DBLCLK && pNMHDR->idFrom == IDC_MARKUP_TREE )
- {
- if ( m_tree.GetSelectedItem() )
- {
- OnMarkupFind();
- // Message handled
- *pResult = 0;
- return TRUE;
- }
- }
- // Right-click on tree
- if ( pNMHDR->code == NM_RCLICK && pNMHDR->idFrom == IDC_MARKUP_TREE )
- {
- // Create popup menu
- // From resource, use menu.LoadMenu( IDR_MARKUPTREE );
- // and menu.GetSubMenu(0)->TrackPopupMenu()
- CMenu menu;
- UINT nFlags = MF_STRING;
- BOOL bShowMenu = TRUE;
- DWORD dwPos = GetMessagePos();
- CPoint point(LOWORD(dwPos), HIWORD(dwPos));
- ScreenToClient(&point);
- if ( GetDocument()->IsParsed() )
- {
- // Determine item right-clicked on
- HTREEITEM hItem = m_tree.HitTest( point );
- if ( hItem )
- {
- // Select item clicked on
- m_tree.SelectItem( hItem );
- // Is it an attribute?
- BOOL bIsAttrib = m_tree.GetItemData( hItem );
- // Is this the root element or root element attribute?
- BOOL bRootElem = FALSE;
- HTREEITEM hParentItem = m_tree.GetParentItem( hItem );
- if ( ! hParentItem ||
- ( ! m_tree.GetParentItem(hParentItem) && m_tree.GetItemData(hItem)==1 ) )
- bRootElem = TRUE;
- menu.CreatePopupMenu();
- if ( bIsAttrib )
- {
- menu.AppendMenu( nFlags, ID_MARKUP_FIND, _T("&Find Elem") );
- menu.AppendMenu( nFlags, ID_MARKUP_ADD_ATTRIB, _T("Add A&ttrib") );
- }
- else
- {
- menu.AppendMenu( nFlags, ID_MARKUP_FIND, _T("&Find Elem") );
- if ( ! bRootElem )
- menu.AppendMenu( nFlags, ID_MARKUP_ADD, _T("&Add Elem") );
- menu.AppendMenu( nFlags, ID_MARKUP_ADD_CHILD, _T("Add &Child Elem") );
- menu.AppendMenu( nFlags, ID_MARKUP_ADD_ATTRIB, _T("Add A&ttrib") );
- }
- }
- else
- bShowMenu = FALSE;
- }
- else
- {
- menu.CreatePopupMenu();
- menu.AppendMenu( nFlags, ID_FILE_PARSE, _T("&Parse") );
- }
- if ( bShowMenu )
- {
- // Run popup menu
- ClientToScreen(&point);
- menu.TrackPopupMenu(
- TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this );
- }
- // Message handled
- *pResult = 0;
- return TRUE;
- }
- // Expand item in tree
- if ( pNMHDR->code == TVN_ITEMEXPANDING && pNMHDR->idFrom == IDC_MARKUP_TREE )
- {
- NMTREEVIEW* pnmtv = (NMTREEVIEW*)pNMHDR;
- if ( pnmtv->action & TVE_EXPAND )
- {
- // Is the child empty?
- HTREEITEM hParentItem = pnmtv->itemNew.hItem;
- HTREEITEM hItem = m_tree.GetChildItem( hParentItem );
- if ( hItem && m_tree.GetItemText( hItem ).IsEmpty() )
- {
- // Remove blank child
- m_tree.DeleteItem( hItem );
- // Add attribs and child elements to tree
- SetPos( hParentItem );
- while ( m_pXML->FindChildElem() )
- {
- // Go into child
- m_pXML->IntoElem();
- // Add to tree control
- hItem = AddElemToTree( hParentItem );
- // Create empty child under it, if it has data, attribs, or children
- if ( ElemHasSubItems() )
- m_tree.InsertItem( _T(""), hItem );
- // Back to parent to find next child
- m_pXML->OutOfElem();
- }
- }
- }
- }
- return CView::OnNotify(wParam, lParam, pResult);
- }
- void CMarkupView::OnMarkupFind()
- {
- if ( GetDocument()->IsParsed() )
- {
- HTREEITEM hItem = m_tree.GetSelectedItem();
- if ( hItem )
- {
- // Select element
- SetPos( hItem );
- int nStart, nEnd;
- GetDocument()->m_doc.GetOffsets( nStart, nEnd );
- m_edit.SetSel( nStart, nEnd + 1 );
- // Edit control must have focus to display selection
- // Post message so that it gets focus after current message is complete
- PostMessage( WM_APP );
- }
- }
- }
- void CMarkupView::OnMarkupAdd()
- {
- if ( GetDocument()->IsParsed() )
- {
- HTREEITEM hItem = m_tree.GetSelectedItem();
- if ( hItem )
- {
- // Add a new element to the document
- SetPos( hItem );
- CString csName = m_pXML->GetTagName();
- m_pXML->AddElem( csName );
- // Add item to tree
- HTREEITEM hParentItem = m_tree.GetParentItem( hItem );
- hItem = m_tree.InsertItem( csName, hParentItem, hItem );
- m_tree.SetItemData( hItem, 0 );
- // Set document in edit window
- SetEditTextFromDoc();
- }
- }
- }
- void CMarkupView::OnMarkupAddChild()
- {
- if ( GetDocument()->IsParsed() )
- {
- HTREEITEM hParentItem = m_tree.GetSelectedItem();
- if ( hParentItem )
- {
- // Find last child position
- HTREEITEM hItem = m_tree.GetChildItem( hParentItem );
- HTREEITEM hItemSet = hParentItem;
- BOOL bChild = FALSE;
- while ( hItem )
- {
- hItemSet = hItem;
- bChild = TRUE;
- hItem = m_tree.GetNextSiblingItem( hItem );
- }
- SetPos( hItemSet, bChild );
- // Add a new element to the document
- CString csName = _T("ChildOf") + m_pXML->GetTagName();
- m_pXML->AddChildElem( csName );
- // Add item to tree
- hItem = m_tree.InsertItem( csName, hParentItem );
- m_tree.SetItemData( hItem, 0 );
- m_tree.Expand( hParentItem, TVE_EXPAND );
- // Set document in edit window
- SetEditTextFromDoc();
- }
- }
- }
- void CMarkupView::OnMarkupAddAttrib()
- {
- if ( GetDocument()->IsParsed() )
- {
- HTREEITEM hItem = m_tree.GetSelectedItem();
- if ( hItem )
- {
- // Add a new attrib to the element
- SetPos( hItem );
- ++m_nAddAttrib;
- CString csAttribName;
- csAttribName.Format( _T("attrib%d"), m_nAddAttrib );
- CString csAttribValue;
- csAttribValue.Format( _T("val%d"), m_nAddAttrib );
- m_pXML->AddAttrib( csAttribName, csAttribValue );
- // If selected item is attribute, get element item
- if ( m_tree.GetItemData(hItem) == 1 )
- hItem = m_tree.GetParentItem( hItem );
- // Determine last attribute item
- HTREEITEM hAttribItem = TVI_FIRST;
- HTREEITEM hNextChildItem = m_tree.GetChildItem( hItem );
- // Make sure its not an unexpanded tree item already having children
- if ( ! hNextChildItem || ! m_tree.GetItemText(hNextChildItem).IsEmpty() )
- {
- while ( hNextChildItem && m_tree.GetItemData( hNextChildItem ) == 1 )
- {
- hAttribItem = hNextChildItem;
- hNextChildItem = m_tree.GetNextSiblingItem( hNextChildItem );
- }
- }
- m_tree.Expand( hItem, TVE_EXPAND );
- // Set document in edit window
- SetEditTextFromDoc();
- }
- }
- }
- void CMarkupView::OnEditCopy()
- {
- m_edit.Copy();
- }
- void CMarkupView::OnEditCut()
- {
- m_edit.Cut();
- }
- void CMarkupView::OnEditPaste()
- {
- m_edit.Paste();
- }
- void CMarkupView::OnEditUndo()
- {
- m_edit.Undo();
- }
- void CMarkupView::OnUpdateEditUndo(CCmdUI* pCmdUI)
- {
- pCmdUI->Enable( m_edit.CanUndo() );
- }