VC编程:使用CRichEditCtrl与正则实现XML高亮编辑器
小职 2018-07-05 来源 : 阅读 1128 评论 0

摘要:本文主要向大家介绍了VC编程的使用CRichEditCtrl与正则实现XML高亮编辑器,通过具体的内容向大家展示,希望对大家学习VC编程有所帮助。

本文主要向大家介绍了VC编程的使用CRichEditCtrl与正则实现XML高亮编辑器,通过具体的内容向大家展示,希望对大家学习VC编程有所帮助。

最近与XML打交道比较多,为了便于XML格式内容在界面上的编辑,结合正则写了这个简单的XML高亮编辑器,因为是全文解析的,遇到大文件XML时,会慢一些。代码里所使用的正则库是deelx,也可以换成其他的正则库。

派生自CRichEditCtrl的类CKofXMLRichEditCtrl,代码如下:

/** 
 * \file KofXMLRichEditCtrl.h 
 * 
 * \author 无幻 
 * \date 2012-3-28 
 * 
 * 简单的XML文件高亮编辑器类 
 */ 
 
#pragma once 
 
#include <tom.h> 
#include <Richole.h> 
 
#define XML_COLOR_TEXT RGB(0, 0, 0) 
#define XML_COLOR_STRING RGB(163, 21, 21) 
#define XML_COLOR_TAGS RGB(0, 0, 255) 
#define XML_COLOR_COMMENT RGB(0, 128, 0) 
#define XML_COLOR_BACKGROUND RGB(255, 255, 255) 
 
class CKofXMLRichEditCtrl : public CRichEditCtrl 
{ 
    DECLARE_DYNAMIC(CKofXMLRichEditCtrl) 
 
public: 
    CKofXMLRichEditCtrl(); 
    virtual ~CKofXMLRichEditCtrl(); 
 
protected: 
    void InitXmlRichEdit(); 
    void ColorXml(); 
    DECLARE_MESSAGE_MAP() 
    virtual void PreSubclassWindow(); 
    afx_msg void OnEnChange(); 
 
private: 
    IRichEditOle *m_pRichEditOle; 
    ITextDocument *m_pTextDocument;  
};

   

实现文件如下:

/**  
 * \file KofXMLRichEditCtrl.cpp  
 *  
 * \author 无幻  
 * \date 2012-3-28  
 *  
 * 简单的XML文件高亮编辑器类  
 */  
  
#include "stdafx.h"  
#include "deelx.h"  
#include "KofXMLRichEditCtrl.h"  
  
IMPLEMENT_DYNAMIC(CKofXMLRichEditCtrl, CRichEditCtrl)  
  
CKofXMLRichEditCtrl::CKofXMLRichEditCtrl()  
{  
    m_pRichEditOle = NULL;  
    m_pTextDocument = NULL;  
}  
  
CKofXMLRichEditCtrl::~CKofXMLRichEditCtrl()  
{  
    if (m_pTextDocument)  
    {  
        m_pTextDocument->Release();  
        m_pTextDocument = NULL;  
    }  
    if (m_pRichEditOle)  
    {  
        m_pRichEditOle->Release();  
        m_pRichEditOle = NULL;  
    }  
}  
  
BEGIN_MESSAGE_MAP(CKofXMLRichEditCtrl, CRichEditCtrl)  
    ON_CONTROL_REFLECT(EN_CHANGE, &CKofXMLRichEditCtrl::OnEnChange)  
END_MESSAGE_MAP()  
  
void CKofXMLRichEditCtrl::PreSubclassWindow()  
{  
    m_pRichEditOle = GetIRichEditOle();  
    if (m_pRichEditOle)  
    {  
        if (S_OK != m_pRichEditOle->QueryInterface(__uuidof(ITextDocument), (LPVOID*)&m_pTextDocument))  
        {  
            m_pTextDocument = NULL;  
        }  
    }  
    InitXmlRichEdit();  
    CRichEditCtrl::PreSubclassWindow();  
}  
  
void CKofXMLRichEditCtrl::InitXmlRichEdit()  
{  
    // 关闭自动字体切换  
    SendMessage(EM_SETLANGOPTIONS, 0, 0);   
  
    // 设置文本内容变化响应事件掩码  
    SetEventMask(GetEventMask() | ENM_CHANGE);   
  
    // 设置默认字体  
    CHARFORMAT cf;  
    ZeroMemory(&cf, sizeof(CHARFORMAT));  
    cf.cbSize = sizeof(CHARFORMAT);  
    cf.dwMask = CFM_FACE | CFM_CHARSET | CFM_COLOR;  
    cf.bCharSet = ANSI_CHARSET;  
    cf.dwEffects = 0;  
    cf.crTextColor = XML_COLOR_TEXT;  
    CFileFind fFind;  
    if (fFind.FindFile(_T("C:\\WINDOWS\\Fonts\\CONSOLA.TTF")))  
    {  
        _tcscpy_s(cf.szFaceName, _T("Consolas"));  
    }   
    else  
    {  
        _tcscpy_s(cf.szFaceName, _T("Courier New"));  
    }  
    fFind.Close();  
    SetDefaultCharFormat(cf);  
  
    // 设置背景色  
    SetBackgroundColor(FALSE, XML_COLOR_BACKGROUND);  
}  
  
void CKofXMLRichEditCtrl::ColorXml()  
{  
    CString strValue;  
    GetWindowText(strValue);  
    if (strValue.IsEmpty())  
    {  
        return;  
    }  
  
    //SetSel会把\r\n当成一个字符位  
    strValue.Replace(_T("\r\n"), _T("\n"));  
  
    //转成Unicode统一当成一个字符  
    CStringW strValueW(strValue);  
  
    CHARFORMAT cf;  
    ZeroMemory(&cf, sizeof(CHARFORMAT));  
    cf.cbSize = sizeof(CHARFORMAT);  
    cf.dwMask = CFM_COLOR;  
    cf.dwEffects = 0;  
  
    CStringW strText; 
    long lBegin, lEnd; 
    int iHorzPos, iVertPos; 
 
    GetSel(lBegin, lEnd); 
    iHorzPos = GetScrollPos(SB_HORZ); 
    iVertPos = GetScrollPos(SB_VERT); 
    SetRedraw(FALSE);  
    m_pTextDocument->Undo(tomSuspend, NULL);  
  
    SetSel(0, -1);  
    cf.crTextColor = XML_COLOR_TEXT;  
    SetSelectionCharFormat(cf);  
    static CRegexpT<wchar_t> regexpTags(L"<([^>]*)>");            //找寻<>标签  
    static CRegexpT<wchar_t> regexpString(L"\"([^\"]*)\"");        //找寻""字符串  
    static CRegexpT<wchar_t> regexpComment(L"<!--((?s).*?)-->");//找寻<!-- -->注释  
  
    MatchResult resultTags = regexpTags.Match(strValueW);   
    while (resultTags.IsMatched())  
    {   
        strText = strValueW.Mid(resultTags.GetStart(), resultTags.GetEnd() - resultTags.GetStart());              
        SetSel(resultTags.GetStart(), resultTags.GetEnd());  
        cf.crTextColor = XML_COLOR_TAGS;  
        SetSelectionCharFormat(cf);  
  
        MatchResult resultString = regexpString.Match(strText);  
        while (resultString.IsMatched())  
        {  
            SetSel(resultTags.GetStart() + resultString.GetStart(),  
                resultTags.GetStart() + resultString.GetEnd());  
            cf.crTextColor = XML_COLOR_STRING;  
            SetSelectionCharFormat(cf);  
            resultString = regexpString.Match(strText,  resultString.GetEnd());   
        }  
        resultTags = regexpTags.Match(strValueW, resultTags.GetEnd());   
    }  
    MatchResult resultComment = regexpComment.Match(strValueW);  
    while (resultComment.IsMatched())  
    {  
        SetSel(resultComment.GetStart(), resultComment.GetEnd());  
        cf.crTextColor = XML_COLOR_COMMENT;  
        SetSelectionCharFormat(cf);  
        resultComment = regexpComment.Match(strValueW, resultComment.GetEnd());  
    }  
  
    SetSel(lBegin, lEnd);  
    SendMessage(WM_HSCROLL, MAKELONG(SB_THUMBPOSITION, iHorzPos), 0); 
    SendMessage(WM_VSCROLL, MAKELONG(SB_THUMBPOSITION, iVertPos), 0); 
    SetRedraw(TRUE);  
    RedrawWindow();  
    m_pTextDocument->Undo(tomResume, NULL);  
}  
  
void CKofXMLRichEditCtrl::OnEnChange()  
{  
    if (m_pTextDocument)  
    {  
        ColorXml();  
    }  
}

 

步骤如下:
1.打开VC2008,新建基于对话框工程,名称:MyXmlViewer;
2.在对话框上放置一个RichEdit 2.0控件,ID号改为:IDC_RICHEDIT_XML,设置其Multiline属性、Horizontal Scroll属性、Vertical Scroll属性、Want Return属性;
3.在应用程序类实现文件,添加以下代码:

    AfxInitRichEdit2(); 

   

4.包含"kofxmlricheditctrl.h"头文件,然后关联IDC_RICHEDIT_XML的变量即可,如下:

#include "kofxmlricheditctrl.h" 
 
class CMyXmlViewerDlg : public CDialog 
{ 
    //... 
public: 
    CKofXMLRichEditCtrl m_RichEdit; 
}; 
 
void CMyXmlViewerDlg::DoDataExchange(CDataExchange* pDX) 
{ 
    CDialog::DoDataExchange(pDX); 
    DDX_Control(pDX, IDC_RICHEDIT_XML, m_RichEdit); 
}

   

5.效果如下所示:

 

VC编程:使用CRichEditCtrl与正则实现XML高亮编辑器

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标编程语言VC/MFC频道!

本文由 @小职 发布于职坐标。未经许可,禁止转载。
喜欢 | 1 不喜欢 | 0
看完这篇文章有何感觉?已经有1人表态,100%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程