// MarkupPadEdit.cpp // // (c)1998-2025 Codejock Software, All Rights Reserved. // // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN // CONSENT OF CODEJOCK SOFTWARE. // // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED // IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A // SINGLE COMPUTER. // // CONTACT INFORMATION: // support@codejock.com // http://www.codejock.com // ///////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "resource.h" #include "MarkupPadEdit.h" #include "MarkupPadDoc.h" #include "MarkupPadView.h" #include "MainFrm.h" #ifdef _DEBUG # define new DEBUG_NEW # undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CMarkupPadEdit IMPLEMENT_DYNCREATE(CMarkupPadEdit, CXTPSyntaxEditView) CMarkupPadEdit::CMarkupPadEdit() : m_pPane(NULL) { CXTPNonClientMetrics ncm; STRCPY_S(ncm.lfMessageFont.lfFaceName, LF_FACESIZE, _T("Courier New")); ncm.lfMessageFont.lfHeight = -XTP_DPI_Y(14); m_fnt.CreateFontIndirect(&ncm.lfMessageFont); m_bFirstDoc = TRUE; m_bError = FALSE; } CMarkupPadEdit::~CMarkupPadEdit() { } BEGIN_MESSAGE_MAP(CMarkupPadEdit, CXTPSyntaxEditView) //{{AFX_MSG_MAP(CMarkupPadEdit) ON_CONTROL_REFLECT(EN_CHANGE, OnChange) ON_WM_CONTEXTMENU() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CMarkupPadEdit diagnostics #ifdef _DEBUG void CMarkupPadEdit::AssertValid() const { CXTPSyntaxEditView::AssertValid(); } void CMarkupPadEdit::Dump(CDumpContext& dc) const { CXTPSyntaxEditView::Dump(dc); } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CMarkupPadEdit message handlers void CMarkupPadEdit::OnInitialUpdate() { CXTPSyntaxEditView::OnInitialUpdate(); SetFont(&m_fnt); SendMessage(EM_SETTEXTMODE, TM_PLAINTEXT | TM_MULTILEVELUNDO); SendMessage(EM_SETEVENTMASK, 0, ENM_CHANGE); if (m_bFirstDoc) { CFrameWnd* pMainFrame = (CFrameWnd*)AfxGetMainWnd(); if (pMainFrame) { CXTPStatusBar* pStatusBar = (CXTPStatusBar*)pMainFrame->GetDlgItem(AFX_IDW_STATUS_BAR); pStatusBar->GetMarkupContext()->AddHandler( CXTPMarkupHyperlink::m_pClickEvent, CreateMarkupClassDelegate(this, &CMarkupPadEdit::OnStatusBarHyperlinkClick)); } } if (GetDocument()->GetPathName().IsEmpty() && m_bFirstDoc) { GetEditCtrl().SetText( _T("\r\n") _T(" Enter Text Here\r\n")); } m_bFirstDoc = FALSE; OnChange(); GetDocument()->SetModifiedFlag(FALSE); } void CMarkupPadEdit::SetOwnerPane(CXTPDockingPane* pPane) { _ASSERTE(pPane); m_pPane = pPane; } void CMarkupPadEdit::RefreshColors(UINT nTheme) { CString sIni = _T("EditConfig\\SyntaxEdit.ini"); CString sSchema = _T("EditConfig\\Schemas\\_XAML.schclass"); COLORREF clrBackColor; COLORREF clrLineNumberBackColor; COLORREF clrLineNumberTextColor; switch (nTheme) { case ID_THEMEOFFICE2016_COLORFUL_ACCESS: case ID_THEMEOFFICE2016_COLORFUL_EXCEL: case ID_THEMEOFFICE2016_COLORFUL_ONENOTE: case ID_THEMEOFFICE2016_COLORFUL_OUTLOOK: case ID_THEMEOFFICE2016_COLORFUL_POWERPOINT: case ID_THEMEOFFICE2016_COLORFUL_PUBLISHER: case ID_THEMEOFFICE2016_COLORFUL_WORD: case ID_THEMEOFFICE2016_WHITE_ACCESS: case ID_THEMEOFFICE2016_WHITE_EXCEL: case ID_THEMEOFFICE2016_WHITE_ONENOTE: case ID_THEMEOFFICE2016_WHITE_OUTLOOK: case ID_THEMEOFFICE2016_WHITE_POWERPOINT: case ID_THEMEOFFICE2016_WHITE_PUBLISHER: case ID_THEMEOFFICE2016_WHITE_WORD: case ID_THEMEOFFICE2016_DARKGRAY_ACCESS: case ID_THEMEOFFICE2016_DARKGRAY_EXCEL: case ID_THEMEOFFICE2016_DARKGRAY_ONENOTE: case ID_THEMEOFFICE2016_DARKGRAY_OUTLOOK: case ID_THEMEOFFICE2016_DARKGRAY_POWERPOINT: case ID_THEMEOFFICE2016_DARKGRAY_PUBLISHER: case ID_THEMEOFFICE2016_DARKGRAY_WORD: clrBackColor = RGB(246, 246, 246); clrLineNumberBackColor = RGB(246, 246, 246); clrLineNumberTextColor = RGB(43, 145, 175); break; case ID_THEMEOFFICE2016_BLACK_ACCESS: case ID_THEMEOFFICE2016_BLACK_EXCEL: case ID_THEMEOFFICE2016_BLACK_ONENOTE: case ID_THEMEOFFICE2016_BLACK_OUTLOOK: case ID_THEMEOFFICE2016_BLACK_POWERPOINT: case ID_THEMEOFFICE2016_BLACK_PUBLISHER: case ID_THEMEOFFICE2016_BLACK_WORD: clrBackColor = RGB(28, 28, 28); clrLineNumberBackColor = RGB(28, 28, 28); clrLineNumberTextColor = RGB(86, 156, 214); break; default: clrBackColor = RGB(255, 255, 255); clrLineNumberBackColor = RGB(255, 255, 255); clrLineNumberTextColor = RGB(43, 145, 175); break; } GetEditCtrl().GetPaintManager()->SetBackColor(clrBackColor, FALSE); GetEditCtrl().GetPaintManager()->SetLineNumberBackColor(clrLineNumberBackColor, FALSE); GetEditCtrl().GetPaintManager()->SetLineNumberTextColor(clrLineNumberTextColor, FALSE); GetEditCtrl().SetSelMargin(FALSE); if (GetEditCtrl().GetEditBuffer()) GetEditCtrl().GetEditBuffer()->SetFileExt(_T(".XAML")); GetEditCtrl().SetConfigFile(CXTPSyntaxEditCtrl::GetModulePath() + sIni, TRUE); { CStdioFile file; CString strLine; CString strINI; CString strSchema; if (file.Open(CXTPSyntaxEditCtrl::GetModulePath() + sIni, CFile::modeRead)) { while (file.ReadString(strLine)) { strINI += strLine + _T("\r\n"); } file.Close(); } else { AfxMessageBox(_T("Could not load file")); } strLine = _T(""); strSchema = _T(""); if (file.Open(CXTPSyntaxEditCtrl::GetModulePath() + sSchema, CFile::modeRead)) { while (file.ReadString(strLine)) { strSchema += strLine + _T("\r\n"); } file.Close(); } else { AfxMessageBox(_T("Could not load file")); } GetEditCtrl().SetSyntaxAndColorScheme(strSchema, strINI, FALSE, FALSE); } } LRESULT CMarkupPadEdit::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { if (message == WM_NCPAINT) { CXTPSyntaxEditView::WindowProc(message, wParam, lParam); CWindowDC dc(this); CXTPWindowRect rWindow(this); rWindow.OffsetRect(-rWindow.TopLeft()); theApp.m_csPane.DrawBorders(&dc, rWindow, m_pPane); return TRUE; } return CXTPSyntaxEditView::WindowProc(message, wParam, lParam); } LPWSTR CMarkupPadEdit::GetUnicodeText() { if (!GetEditCtrl().GetText().IsEmpty()) { #ifdef UNICODE int len = GetEditCtrl().GetText().GetLength(); LPWSTR lpBuffer = new WCHAR[len + 1]; STRCPY_S(lpBuffer, XTPToSizeTChecked(len) + 1, GetEditCtrl().GetText()); return lpBuffer; #else UINT nCodePage = XTPResourceManager()->GetLanguageInfo()->nCodePage; int nDestLen = MultiByteToWideChar(nCodePage, 0, GetEditCtrl().GetText(), -1, NULL, 0); WCHAR* lpBuffer = new WCHAR[XTPToUIntChecked(nDestLen)]; MultiByteToWideChar(nCodePage, 0, GetEditCtrl().GetText(), -1, lpBuffer, nDestLen); return lpBuffer; #endif } return NULL; } CString CreateMarkupError(LPCTSTR lpszLastError) { LPCTSTR lpszIndex = _tcsstr(lpszLastError, _T(". Line ")); if (lpszIndex == NULL) return lpszLastError; ((LPTSTR)lpszIndex)[1] = 0; CString str; str.Format(_T("%s %s"), lpszLastError, lpszIndex + 2); ((LPTSTR)lpszIndex)[1] = ' '; return str; } void CMarkupPadEdit::OnChange() { USES_CONVERSION; CMarkupPadDoc* pDocument = (CMarkupPadDoc*)GetDocument(); POSITION pos = pDocument->GetFirstViewPosition(); CMarkupPadView* pView = (CMarkupPadView*)pDocument->GetNextView(pos); LPWSTR lpszMarkup = GetUnicodeText(); _int64 nPerfomanceEnd; _int64 nPerfomanceStart; QueryPerformanceCounter((LARGE_INTEGER*)&nPerfomanceStart); CXTPMarkupParser sc; if (lpszMarkup) sc.SetBuffer(lpszMarkup, lpszMarkup + wcslen(lpszMarkup)); CXTPMarkupBuilder builder(pView); CXTPMarkupUIElement* pUIElement = builder.Parse(&sc); if (lpszMarkup) delete[] lpszMarkup; QueryPerformanceCounter((LARGE_INTEGER*)&nPerfomanceEnd); TRACE(_T("Parse = %i \n"), int(nPerfomanceEnd - nPerfomanceStart)); BOOL bError = m_bError; if (pUIElement) { MARKUP_RELEASE(pView->m_pUIElement); pView->m_pUIElement = pUIElement; bError = FALSE; UpdateViews(); GetParentFrame()->SetMessageText(_T("Done.")); } else { bError = TRUE; GetParentFrame()->SetMessageText(CreateMarkupError(builder.GetLastError())); } if (m_bError != bError) { m_bError = bError; CHARFORMAT cf; ZeroMemory(&cf, sizeof(CHARFORMAT)); cf.cbSize = sizeof(CHARFORMAT); cf.dwMask = CFM_COLOR; cf.crTextColor = m_bError ? RGB(200, 0, 0) : theApp.m_csPane.m_clrMarkupText; SendMessage(EM_SETCHARFORMAT, 0, (LPARAM)&cf); SendMessage(EM_SETBKGNDCOLOR, 0, (LPARAM)theApp.m_csPane.m_clrBack); } else { CHARFORMAT cf; ZeroMemory(&cf, sizeof(CHARFORMAT)); cf.cbSize = sizeof(CHARFORMAT); cf.dwMask = CFM_COLOR; cf.crTextColor = m_bError ? RGB(200, 0, 0) : theApp.m_csPane.m_clrMarkupText; SendMessage(EM_SETCHARFORMAT, 0, (LPARAM)&cf); SendMessage(EM_SETBKGNDCOLOR, 0, (LPARAM)theApp.m_csPane.m_clrBack); } pDocument->SetModifiedFlag(TRUE); } void CMarkupPadEdit::UpdateViews() { CDocument* pDocument = GetDocument(); POSITION pos = pDocument->GetFirstViewPosition(); while (pos) { CView* pView = pDocument->GetNextView(pos); if (pView != this) { pView->Invalidate(FALSE); break; } } } void CMarkupPadEdit::OnStatusBarHyperlinkClick(CXTPMarkupObject* pSender, CXTPMarkupRoutedEventArgs* pArgs) { if (pSender->IsKindOf(MARKUP_TYPE(CXTPMarkupHyperlink))) { CXTPMarkupRun* pRun = (CXTPMarkupRun*)((CXTPMarkupHyperlink*)pSender)->GetInlines()->GetInline(0); CString strText = pRun->GetText(); int nLine = 0, nPosition = 0; if (SCANF_S(strText, _T("Line %i, position %i"), &nLine, &nPosition) == 2) { int nPos = nPosition + (int)SendMessage(EM_LINEINDEX, nLine - 1); SendMessage(EM_SETSEL, nPos, nPos); } pArgs->SetHandled(); } } void CMarkupPadEdit::OnContextMenu(CWnd* pWnd, CPoint point) { CMenu menu; menu.LoadMenu(IDR_MENU_CONTEXT); if (point == CPoint(-1, -1)) GetCursorPos(&point); ((CXTPFrameWnd*)AfxGetMainWnd()) ->GetCommandBars() ->TrackPopupMenuEx(menu.GetSubMenu(0), 0, point.x, point.y, pWnd); } BOOL CMarkupPadEdit::OnEditChanged(NMHDR* pNMHDR, LRESULT* pResult) { XTP_EDIT_NMHDR_EDITCHANGED* pNMHDR_EC = (XTP_EDIT_NMHDR_EDITCHANGED*)pNMHDR; UpdateSiblings(pNMHDR_EC); OnChange(); *pResult = 1; return TRUE; }