MarkupView.cpp
上传用户:hawkcdm
上传日期:2013-02-10
资源大小:411k
文件大小:17k
源码类别:

xml/soap/webservice

开发平台:

Visual C++

  1. // MarkupView.cpp : implementation of the CMarkupView class
  2. //
  3. // Markup Release 6.1 Lite
  4. // Copyright (C) 1999-2001 First Objective Software, Inc. All rights reserved
  5. // This entire notice must be retained in this source code
  6. // Redistributing this source code requires written permission
  7. // This software is provided "as is", with no warranty.
  8. // Latest fixes enhancements and documentation at www.firstobject.com
  9. #include "stdafx.h"
  10. #include "MarkupApp.h"
  11. #include "MarkupDoc.h"
  12. #include "MarkupView.h"
  13. #define IDC_MARKUP_TREE 1020
  14. #define IDC_MARKUP_EDIT 1021
  15. #define IDC_MARKUP_DIVIDER 1022
  16. #ifdef _DEBUG
  17. #define new DEBUG_NEW
  18. #undef THIS_FILE
  19. static char THIS_FILE[] = __FILE__;
  20. #endif
  21. /////////////////////////////////////////////////////////////////////////////
  22. // CMarkupView
  23. IMPLEMENT_DYNCREATE(CMarkupView, CView)
  24. BEGIN_MESSAGE_MAP(CMarkupView, CView)
  25. //{{AFX_MSG_MAP(CMarkupView)
  26. ON_WM_CREATE()
  27. ON_WM_SIZE()
  28. ON_COMMAND(ID_MARKUP_FIND, OnMarkupFind)
  29. ON_COMMAND(ID_MARKUP_ADD, OnMarkupAdd)
  30. ON_COMMAND(ID_MARKUP_ADD_CHILD, OnMarkupAddChild)
  31. ON_COMMAND(ID_MARKUP_ADD_ATTRIB, OnMarkupAddAttrib)
  32. ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
  33. ON_COMMAND(ID_EDIT_CUT, OnEditCut)
  34. ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
  35. ON_COMMAND(ID_EDIT_UNDO, OnEditUndo)
  36. ON_UPDATE_COMMAND_UI(ID_EDIT_UNDO, OnUpdateEditUndo)
  37. //}}AFX_MSG_MAP
  38. // Standard printing commands
  39. ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
  40. ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
  41. ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
  42. ON_EN_CHANGE(IDC_MARKUP_EDIT, OnChangeEdit)
  43. ON_MESSAGE( WM_APP, OnAppMessage )
  44. END_MESSAGE_MAP()
  45. /////////////////////////////////////////////////////////////////////////////
  46. // CMarkupView construction/destruction
  47. CMarkupView::CMarkupView()
  48. {
  49. m_nAddAttrib = 0;
  50. }
  51. CMarkupView::~CMarkupView()
  52. {
  53. }
  54. BOOL CMarkupView::PreCreateWindow(CREATESTRUCT& cs)
  55. {
  56. // TODO: Modify the Window class or styles here by modifying
  57. //  the CREATESTRUCT cs
  58. return CView::PreCreateWindow(cs);
  59. }
  60. /////////////////////////////////////////////////////////////////////////////
  61. // CMarkupView drawing
  62. void CMarkupView::OnDraw(CDC* pDC)
  63. {
  64. UNREFERENCED_PARAMETER(pDC);
  65. CMarkupDoc* pDoc = GetDocument();
  66. ASSERT_VALID(pDoc);
  67. }
  68. /////////////////////////////////////////////////////////////////////////////
  69. // CMarkupView printing
  70. BOOL CMarkupView::OnPreparePrinting(CPrintInfo* pInfo)
  71. {
  72. // default preparation
  73. return DoPreparePrinting(pInfo);
  74. }
  75. void CMarkupView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
  76. {
  77. // TODO: add extra initialization before printing
  78. }
  79. void CMarkupView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
  80. {
  81. // TODO: add cleanup after printing
  82. }
  83. /////////////////////////////////////////////////////////////////////////////
  84. // CMarkupView diagnostics
  85. #ifdef _DEBUG
  86. void CMarkupView::AssertValid() const
  87. {
  88. CView::AssertValid();
  89. }
  90. void CMarkupView::Dump(CDumpContext& dc) const
  91. {
  92. CView::Dump(dc);
  93. }
  94. CMarkupDoc* CMarkupView::GetDocument() // non-debug version is inline
  95. {
  96. ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMarkupDoc)));
  97. return (CMarkupDoc*)m_pDocument;
  98. }
  99. #endif //_DEBUG
  100. /////////////////////////////////////////////////////////////////////////////
  101. // CMarkupView message handlers
  102. void CMarkupView::OnInitialUpdate() 
  103. {
  104. m_pXML = &GetDocument()->m_doc;
  105. CView::OnInitialUpdate();
  106. // Maximize first time
  107. static BOOL bFirst = TRUE;
  108. if ( bFirst )
  109. {
  110. bFirst = FALSE;
  111. GetParent()->ShowWindow( SW_MAXIMIZE );
  112. }
  113. // Divider
  114. m_divider.m_nFractionOf1000 = 350;
  115. m_divider.m_enumOrientation = m_divider.MoveHorizontal;
  116. // Initial resize
  117. CRect rect;
  118. GetClientRect( &rect );
  119. CalcSize( rect.Width(), rect.Height() );
  120. // Text
  121. const int nMax = 64000; // Win 95 limit
  122. m_edit.SetLimitText( nMax );
  123. CString csText = GetDocument()->m_csText;
  124. if ( csText.GetLength() > nMax )
  125. AfxMessageBox( _T("Document is larger than edit buffer maximum") );
  126. m_edit.SetWindowText( csText );
  127. GetDocument()->SetParsedFlag( TRUE );
  128. GetDocument()->SetModifiedFlag( FALSE );
  129. }
  130. void CMarkupView::GetEditText( CString& csDoc )
  131. {
  132. if ( m_edit.GetSafeHwnd() )
  133. m_edit.GetWindowText( csDoc );
  134. }
  135. CString CMarkupView::SetEditTextFromDoc()
  136. {
  137. // Set document in rich edit control
  138. CString csDoc = m_pXML->GetDoc();
  139. m_edit.SetWindowText( csDoc );
  140. GetDocument()->m_csText = csDoc;
  141. GetDocument()->SetParsedFlag( TRUE );
  142. return csDoc;
  143. }
  144. int CMarkupView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
  145. {
  146. if (CView::OnCreate(lpCreateStruct) == -1)
  147. return -1;
  148. // Create controls
  149. int nFlags = WS_VISIBLE|WS_CHILD|WS_GROUP;
  150. if ( ! m_tree.Create( nFlags|TVS_LINESATROOT|TVS_HASLINES|TVS_HASBUTTONS,
  151. CRect(0,0,0,0), this, IDC_MARKUP_TREE ) )
  152. return -1;
  153. m_ilTree.Create(IDB_IL_TREE,16,0,RGB(255,255,255));
  154. m_tree.SetImageList(&m_ilTree,TVSIL_NORMAL);
  155. if ( ! m_divider.CreateEx(WS_EX_DLGMODALFRAME,_T("STATIC"),NULL,nFlags|SS_NOTIFY,
  156. CRect(0,0,0,0),this,IDC_MARKUP_DIVIDER) )
  157. return -1;
  158. nFlags = WS_CHILD|WS_VISIBLE|ES_MULTILINE|ES_WANTRETURN|WS_VSCROLL;
  159. if ( ! m_edit.Create( nFlags, CRect(0,0,0,0), this, IDC_MARKUP_EDIT ) )
  160. return -1;
  161. // Get default system font
  162. HFONT hSystemFont = (HFONT)GetStockObject(SYSTEM_FONT);
  163. LOGFONT systemFont;
  164. VERIFY(::GetObject(hSystemFont, sizeof(LOGFONT), (void*)&systemFont));
  165. // Set a Unicode font as the default
  166. // If you have a font that does not support the unicode characters you
  167. // are trying to view, then the characters appear as blocks or blanks
  168. // If unicode is not desired replace with the following
  169. // m_font.CreateFontIndirect(&systemFont);
  170. LOGFONT logFont; memset(&logFont, 0, sizeof(LOGFONT));
  171. logFont.lfHeight = systemFont.lfHeight + 1;
  172. logFont.lfWeight = FW_NORMAL;
  173. logFont.lfCharSet = DEFAULT_CHARSET;
  174. lstrcpy(logFont.lfFaceName, _T("Lucida Sans Unicode"));
  175. if ( ! m_font.CreateFontIndirect(&logFont) )
  176. m_font.CreateFontIndirect(&systemFont);
  177. m_edit.SetFont( &m_font );
  178. return 0;
  179. }
  180. void CMarkupView::CalcSize( int cx, int cy )
  181. {
  182. CRect rectBorder( 0, 0, cx, cy );
  183. CRect rect( rectBorder );
  184. int nOffset = m_divider.CalculateOffset( rectBorder.Width() );
  185. rect.right = rect.left + nOffset;
  186. m_tree.MoveWindow( &rect );
  187. rect.left += nOffset;
  188. rect.right = rect.left + m_divider.m_nWidth;
  189. m_divider.MoveWindow( &rect );
  190. rect.left = rect.right;
  191. rect.right = rectBorder.right;
  192. m_edit.MoveWindow( &rect );
  193. m_tree.Invalidate();
  194. m_divider.Invalidate();
  195. m_edit.Invalidate();
  196. }
  197. void CMarkupView::OnSize(UINT nType, int cx, int cy) 
  198. {
  199. CView::OnSize(nType, cx, cy);
  200. if ( m_tree.GetSafeHwnd() )
  201. CalcSize( cx, cy );
  202. }
  203. void CMarkupView::GetNthWisePos( HTREEITEM hItem, CUIntArray& aNths )
  204. {
  205. // Populate aNths with sibling number on each level
  206. // if it is the first sibling, it is set to 1, etc
  207. while ( hItem )
  208. {
  209. HTREEITEM hParentItem = m_tree.GetParentItem( hItem );
  210. // Calculate Nth position on this level
  211. aNths.InsertAt( 0, 0, 1 );
  212. while ( hItem )
  213. {
  214. if ( m_tree.GetItemData(hItem) == 0 ) // It is Elem? (not attrib)
  215. ++aNths[0];
  216. hItem = m_tree.GetPrevSiblingItem( hItem );
  217. }
  218. // Remove if attribute
  219. if ( aNths[0] == 0 )
  220. aNths.RemoveAt( 0 );
  221. // Go to parent item
  222. hItem = hParentItem;
  223. }
  224. }
  225. void CMarkupView::SetPos( HTREEITEM hItem, BOOL bChild )
  226. {
  227. // Synchronize current position in XML document
  228. CUIntArray aNths;
  229. GetNthWisePos( hItem, aNths );
  230. m_pXML->ResetPos();
  231. int nLev = 0;
  232. int nCount = aNths[nLev];
  233. while ( nCount-- )
  234. m_pXML->FindElem();
  235. while ( ++nLev < aNths.GetSize() )
  236. {
  237. nCount = aNths[nLev];
  238. while ( nCount-- )
  239. m_pXML->FindChildElem();
  240. if ( nLev < aNths.GetSize() - 1 || ! bChild )
  241. m_pXML->IntoElem();
  242. }
  243. }
  244. void CMarkupView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) 
  245. {
  246. // Refill the tree after load or parse
  247. //
  248. UNREFERENCED_PARAMETER(pSender);
  249. UNREFERENCED_PARAMETER(pHint);
  250. UNREFERENCED_PARAMETER(lHint);
  251. CWaitCursor wait;
  252. if ( lHint )
  253. {
  254. m_edit.SetWindowText( GetDocument()->m_csText );
  255. GetDocument()->SetParsedFlag( TRUE );
  256. }
  257. // Find selected position
  258. HTREEITEM hSelectedItem = m_tree.GetSelectedItem();
  259. CUIntArray aNths;
  260. GetNthWisePos( hSelectedItem, aNths );
  261. hSelectedItem = NULL;
  262. // Traverse root and immediate children
  263. // plus any elements on path to the selected position
  264. m_tree.DeleteAllItems();
  265. m_pXML->ResetPos();
  266. BOOL bFound = m_pXML->FindElem();
  267. HTREEITEM hItem, hParentItem = TVI_ROOT;
  268. int nLev = 0;
  269. CUIntArray aCurNth;
  270. aCurNth.Add(1);
  271. while ( bFound )
  272. {
  273. hItem = AddElemToTree( hParentItem );
  274. // Select it if this is the correct item
  275. if ( nLev == aNths.GetSize()-1 && aCurNth[nLev] == aNths[nLev] )
  276. hSelectedItem = hItem;
  277. // Is there a child?
  278. bFound = ElemHasSubItems();
  279. // Above 2 levels, leave children blank to be filled on expand
  280. // Set flag indicating whether this element is on path to selection position
  281. BOOL bOnPath = nLev < aNths.GetSize() && aCurNth[nLev] == aNths[nLev];
  282. if ( bFound && nLev > 0 && ! bOnPath )
  283. {
  284. m_tree.InsertItem( _T(""), hItem );
  285. bFound = FALSE;
  286. }
  287. if ( bFound )
  288. {
  289. // Go into child
  290. m_pXML->ResetChildPos();
  291. if ( m_pXML->FindChildElem() )
  292. {
  293. hParentItem = hItem;
  294. m_pXML->IntoElem();
  295. ++nLev;
  296. aCurNth.SetAtGrow( nLev, 1 );
  297. }
  298. else
  299. {
  300. bFound = FALSE;
  301. }
  302. }
  303. if ( ! bFound )
  304. {
  305. // Look for more on same level or toward root
  306. while ( (bFound=m_pXML->FindElem()) == 0 && nLev )
  307. {
  308. m_tree.Expand( hParentItem, TVE_EXPAND );
  309. hParentItem = m_tree.GetParentItem(hParentItem);
  310. m_pXML->OutOfElem();
  311. --nLev;
  312. }
  313. ++aCurNth[nLev];
  314. }
  315. }
  316. // Was corresponding item to previously selected found?
  317. if ( hSelectedItem )
  318. {
  319. m_tree.SelectItem( hSelectedItem );
  320. m_tree.EnsureVisible( hSelectedItem );
  321. }
  322. }
  323. void CMarkupView::OnChangeEdit() 
  324. {
  325. GetDocument()->SetModifiedFlag();
  326. GetDocument()->SetParsedFlag( FALSE );
  327. }
  328. LRESULT CMarkupView::OnAppMessage( WPARAM, LPARAM )
  329. {
  330. // Post WM_APP, then here set focus to m_edit
  331. // So that selection in document is visible
  332. m_edit.SetFocus();
  333. return 0;
  334. }
  335. HTREEITEM CMarkupView::AddElemToTree(HTREEITEM hParentItem)
  336. {
  337. HTREEITEM hItem;
  338. hItem = m_tree.InsertItem( m_pXML->GetTagName(), hParentItem );
  339. m_tree.SetItemData( hItem, 0 );
  340. return hItem;
  341. }
  342. BOOL CMarkupView::ElemHasSubItems()
  343. {
  344. BOOL bElemHasSubItems = FALSE;
  345. if ( m_pXML->FindChildElem() || ! m_pXML->GetChildData().IsEmpty() )
  346. bElemHasSubItems = TRUE;
  347. return bElemHasSubItems;
  348. }
  349. BOOL CMarkupView::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult) 
  350. {
  351. // NMHDR is { HWND hwndFrom; UINT idFrom; UINT code; }
  352. NMHDR* pNMHDR = (NMHDR*)lParam;
  353. // Double-click on tree
  354. if ( pNMHDR->code == NM_DBLCLK && pNMHDR->idFrom == IDC_MARKUP_TREE )
  355. {
  356. if ( m_tree.GetSelectedItem() )
  357. {
  358. OnMarkupFind();
  359. // Message handled
  360. *pResult = 0;
  361. return TRUE;
  362. }
  363. }
  364. // Right-click on tree
  365. if ( pNMHDR->code == NM_RCLICK && pNMHDR->idFrom == IDC_MARKUP_TREE )
  366. {
  367. // Create popup menu
  368. // From resource, use menu.LoadMenu( IDR_MARKUPTREE );
  369. // and menu.GetSubMenu(0)->TrackPopupMenu()
  370. CMenu menu;
  371. UINT nFlags = MF_STRING;
  372. BOOL bShowMenu = TRUE;
  373. DWORD dwPos = GetMessagePos();
  374. CPoint point(LOWORD(dwPos), HIWORD(dwPos));
  375. ScreenToClient(&point);
  376. if ( GetDocument()->IsParsed() )
  377. {
  378. // Determine item right-clicked on
  379. HTREEITEM hItem = m_tree.HitTest( point );
  380. if ( hItem )
  381. {
  382. // Select item clicked on
  383. m_tree.SelectItem( hItem );
  384. // Is it an attribute?
  385. BOOL bIsAttrib = m_tree.GetItemData( hItem );
  386. // Is this the root element or root element attribute?
  387. BOOL bRootElem = FALSE;
  388. HTREEITEM hParentItem = m_tree.GetParentItem( hItem );
  389. if ( ! hParentItem ||
  390. ( ! m_tree.GetParentItem(hParentItem) && m_tree.GetItemData(hItem)==1 ) )
  391. bRootElem = TRUE;
  392. menu.CreatePopupMenu();
  393. if ( bIsAttrib )
  394. {
  395. menu.AppendMenu( nFlags, ID_MARKUP_FIND, _T("&Find Elem") );
  396. menu.AppendMenu( nFlags, ID_MARKUP_ADD_ATTRIB, _T("Add A&ttrib") );
  397. }
  398. else
  399. {
  400. menu.AppendMenu( nFlags, ID_MARKUP_FIND, _T("&Find Elem") );
  401. if ( ! bRootElem )
  402. menu.AppendMenu( nFlags, ID_MARKUP_ADD, _T("&Add Elem") );
  403. menu.AppendMenu( nFlags, ID_MARKUP_ADD_CHILD, _T("Add &Child Elem") );
  404. menu.AppendMenu( nFlags, ID_MARKUP_ADD_ATTRIB, _T("Add A&ttrib") );
  405. }
  406. }
  407. else
  408. bShowMenu = FALSE;
  409. }
  410. else
  411. {
  412. menu.CreatePopupMenu();
  413. menu.AppendMenu( nFlags, ID_FILE_PARSE, _T("&Parse") );
  414. }
  415. if ( bShowMenu )
  416. {
  417. // Run popup menu
  418. ClientToScreen(&point);
  419. menu.TrackPopupMenu(
  420. TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this );
  421. }
  422. // Message handled
  423. *pResult = 0;
  424. return TRUE;
  425. }
  426. // Expand item in tree
  427. if ( pNMHDR->code == TVN_ITEMEXPANDING && pNMHDR->idFrom == IDC_MARKUP_TREE )
  428. {
  429. NMTREEVIEW* pnmtv = (NMTREEVIEW*)pNMHDR;
  430. if ( pnmtv->action & TVE_EXPAND )
  431. {
  432. // Is the child empty?
  433. HTREEITEM hParentItem = pnmtv->itemNew.hItem;
  434. HTREEITEM hItem = m_tree.GetChildItem( hParentItem );
  435. if ( hItem && m_tree.GetItemText( hItem ).IsEmpty() )
  436. {
  437. // Remove blank child
  438. m_tree.DeleteItem( hItem );
  439. // Add attribs and child elements to tree
  440. SetPos( hParentItem );
  441. while ( m_pXML->FindChildElem() )
  442. {
  443. // Go into child
  444. m_pXML->IntoElem();
  445. // Add to tree control
  446. hItem = AddElemToTree( hParentItem );
  447. // Create empty child under it, if it has data, attribs, or children
  448. if ( ElemHasSubItems() )
  449. m_tree.InsertItem( _T(""), hItem );
  450. // Back to parent to find next child
  451. m_pXML->OutOfElem();
  452. }
  453. }
  454. }
  455. }
  456. return CView::OnNotify(wParam, lParam, pResult);
  457. }
  458. void CMarkupView::OnMarkupFind() 
  459. {
  460. if ( GetDocument()->IsParsed() )
  461. {
  462. HTREEITEM hItem = m_tree.GetSelectedItem();
  463. if ( hItem )
  464. {
  465. // Select element
  466. SetPos( hItem );
  467. int nStart, nEnd;
  468. GetDocument()->m_doc.GetOffsets( nStart, nEnd );
  469. m_edit.SetSel( nStart, nEnd + 1 );
  470. // Edit control must have focus to display selection
  471. // Post message so that it gets focus after current message is complete
  472. PostMessage( WM_APP );
  473. }
  474. }
  475. }
  476. void CMarkupView::OnMarkupAdd() 
  477. {
  478. if ( GetDocument()->IsParsed() )
  479. {
  480. HTREEITEM hItem = m_tree.GetSelectedItem();
  481. if ( hItem )
  482. {
  483. // Add a new element to the document
  484. SetPos( hItem );
  485. CString csName = m_pXML->GetTagName();
  486. m_pXML->AddElem( csName );
  487. // Add item to tree
  488. HTREEITEM hParentItem = m_tree.GetParentItem( hItem );
  489. hItem = m_tree.InsertItem( csName, hParentItem, hItem );
  490. m_tree.SetItemData( hItem, 0 );
  491. // Set document in edit window
  492. SetEditTextFromDoc();
  493. }
  494. }
  495. }
  496. void CMarkupView::OnMarkupAddChild() 
  497. {
  498. if ( GetDocument()->IsParsed() )
  499. {
  500. HTREEITEM hParentItem = m_tree.GetSelectedItem();
  501. if ( hParentItem )
  502. {
  503. // Find last child position
  504. HTREEITEM hItem = m_tree.GetChildItem( hParentItem );
  505. HTREEITEM hItemSet = hParentItem;
  506. BOOL bChild = FALSE;
  507. while ( hItem )
  508. {
  509. hItemSet = hItem;
  510. bChild = TRUE;
  511. hItem = m_tree.GetNextSiblingItem( hItem );
  512. }
  513. SetPos( hItemSet, bChild );
  514. // Add a new element to the document
  515. CString csName = _T("ChildOf") + m_pXML->GetTagName();
  516. m_pXML->AddChildElem( csName );
  517. // Add item to tree
  518. hItem = m_tree.InsertItem( csName, hParentItem );
  519. m_tree.SetItemData( hItem, 0 );
  520. m_tree.Expand( hParentItem, TVE_EXPAND );
  521. // Set document in edit window
  522. SetEditTextFromDoc();
  523. }
  524. }
  525. }
  526. void CMarkupView::OnMarkupAddAttrib() 
  527. {
  528. if ( GetDocument()->IsParsed() )
  529. {
  530. HTREEITEM hItem = m_tree.GetSelectedItem();
  531. if ( hItem )
  532. {
  533. // Add a new attrib to the element
  534. SetPos( hItem );
  535. ++m_nAddAttrib;
  536. CString csAttribName;
  537. csAttribName.Format( _T("attrib%d"), m_nAddAttrib );
  538. CString csAttribValue;
  539. csAttribValue.Format( _T("val%d"), m_nAddAttrib );
  540. m_pXML->AddAttrib( csAttribName, csAttribValue );
  541. // If selected item is attribute, get element item
  542. if ( m_tree.GetItemData(hItem) == 1 )
  543. hItem = m_tree.GetParentItem( hItem );
  544. // Determine last attribute item
  545. HTREEITEM hAttribItem = TVI_FIRST;
  546. HTREEITEM hNextChildItem = m_tree.GetChildItem( hItem );
  547. // Make sure its not an unexpanded tree item already having children
  548. if ( ! hNextChildItem || ! m_tree.GetItemText(hNextChildItem).IsEmpty() )
  549. {
  550. while ( hNextChildItem && m_tree.GetItemData( hNextChildItem ) == 1 )
  551. {
  552. hAttribItem = hNextChildItem;
  553. hNextChildItem = m_tree.GetNextSiblingItem( hNextChildItem );
  554. }
  555. }
  556. m_tree.Expand( hItem, TVE_EXPAND );
  557. // Set document in edit window
  558. SetEditTextFromDoc();
  559. }
  560. }
  561. }
  562. void CMarkupView::OnEditCopy() 
  563. {
  564. m_edit.Copy();
  565. }
  566. void CMarkupView::OnEditCut() 
  567. {
  568. m_edit.Cut();
  569. }
  570. void CMarkupView::OnEditPaste() 
  571. {
  572. m_edit.Paste();
  573. }
  574. void CMarkupView::OnEditUndo() 
  575. {
  576. m_edit.Undo();
  577. }
  578. void CMarkupView::OnUpdateEditUndo(CCmdUI* pCmdUI) 
  579. {
  580. pCmdUI->Enable( m_edit.CanUndo() );
  581. }