📄 pmarkupdemoview.cpp
字号:
// PMarkupDemoView.cpp : implementation of the CPMarkupDemoView class
//
#include "stdafx.h"
#include "PMarkupDemo.h"
#include "PMarkupDemoDoc.h"
#include "PMarkupDemoView.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
/////////////////////////////////////////////////////////////////////////////
// CPMarkupDemoView
IMPLEMENT_DYNCREATE(CPMarkupDemoView, CView)
BEGIN_MESSAGE_MAP(CPMarkupDemoView, CView)
//{{AFX_MSG_MAP(CPMarkupDemoView)
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
ON_EN_CHANGE(IDC_MARKUP_EDIT, OnChangeEdit)
ON_MESSAGE( WM_APP, OnAppMessage )
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CPMarkupDemoView construction/destruction
CPMarkupDemoView::CPMarkupDemoView()
{
m_nAddAttrib = 0;
}
CPMarkupDemoView::~CPMarkupDemoView()
{
}
BOOL CPMarkupDemoView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CPMarkupDemoView drawing
void CPMarkupDemoView::OnDraw(CDC* pDC)
{
CPMarkupDemoDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
}
/////////////////////////////////////////////////////////////////////////////
// CPMarkupDemoView diagnostics
#ifdef _DEBUG
void CPMarkupDemoView::AssertValid() const
{
CView::AssertValid();
}
void CPMarkupDemoView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CPMarkupDemoDoc* CPMarkupDemoView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CPMarkupDemoDoc)));
return (CPMarkupDemoDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CPMarkupDemoView message handlers
void CPMarkupDemoView::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 CPMarkupDemoView::GetEditText( CString& csDoc )
{
if ( m_edit.GetSafeHwnd() )
m_edit.GetWindowText( csDoc );
}
CString CPMarkupDemoView::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 CPMarkupDemoView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
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 CPMarkupDemoView::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 CPMarkupDemoView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
if ( m_tree.GetSafeHwnd() )
CalcSize( cx, cy );
}
void CPMarkupDemoView::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 CPMarkupDemoView::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 CPMarkupDemoView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
{
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 CPMarkupDemoView::OnChangeEdit()
{
GetDocument()->SetModifiedFlag();
GetDocument()->SetParsedFlag( FALSE );
}
LRESULT CPMarkupDemoView::OnAppMessage( WPARAM, LPARAM )
{
// Post WM_APP, then here set focus to m_edit
// So that selection in document is visible
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -