前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >文本编辑器

文本编辑器

作者头像
_gongluck
发布2018-03-08 14:24:39
2K0
发布2018-03-08 14:24:39
举报

文本编辑器——记事本类型的应用,可以打开、编辑、保存文本文档。可以增加单词高亮和其它的一些特性。

效果图:

代码语言:javascript
复制
//CGEditorDlg成员
public:
	CString m_filename;//打开文件名
	CRichEditCtrl m_richedit;//富文本框控件
	CString m_text;//富文本框中的文本
	std::set<std::wstring> blueText;//需要变蓝色的单词
	std::set<std::wstring> redText;//需要变红色的单词

	afx_msg void OnBnClickedOk();
	afx_msg void OnBnClickedCancel();
	afx_msg void OnBnClickedButtonsearch();//浏览按钮消息处理
	afx_msg void OnEnChangeRichedit();//富文本框文本变化时消息处理
	afx_msg void OnBnClickedButtonsave();//保存按钮消息处理
	afx_msg void OnEnMsgfilterRichedit(NMHDR *pNMHDR, LRESULT *pResult);//筛选键盘消息,处理tab键
代码语言:javascript
复制
BOOL CGEditorDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	// TODO:  在此添加额外的初始化代码
	m_richedit.SetEventMask(m_richedit.GetEventMask() | ENM_CHANGE | ENM_KEYEVENTS);

	blueText.clear();
	blueText.insert(L"int");
	blueText.insert(L"double");
	blueText.insert(L"float");
	blueText.insert(L"void");
	blueText.insert(L"char");
	redText.clear();
	redText.insert(L"include");
	redText.insert(L"using");
	redText.insert(L"namespace");
	redText.insert(L"return");

	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}
void CGEditorDlg::OnBnClickedButtonsearch()
{
    // TODO:  在此添加控件通知处理程序代码
    CFileDialog dlg(TRUE, TEXT("cpp"), TEXT("text"), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
        TEXT("C源文件(*.c)|*.c|C++源文件(*.cpp)|*.cpp|文本文件(*.txt)|*.txt||"));//open
    if (IDOK == dlg.DoModal())
    {
        //MessageBox(dlg.GetPathName());
        wifstream ifs(dlg.GetPathName().GetBuffer());
        if (!ifs.is_open())
        {
            MessageBox(dlg.GetPathName(), TEXT("文件打开失败"));
        }
        ifs.imbue(std::locale("chs"));
        istreambuf_iterator<wchar_t> beg(ifs), end;
        wstring text(beg, end);
        m_text = text.c_str();
        m_text.Replace(TEXT("\t"), TEXT("    "));
        m_text.Replace(TEXT("\n"), TEXT("\r\n"));
        m_filename = dlg.GetPathName();
        ifs.close();
        UpdateData(FALSE);
        OnEnChangeRichedit();
        SetWindowText(dlg.GetPathName());
    }
}
void CGEditorDlg::OnEnChangeRichedit()
{
    // TODO:  如果该控件是 RICHEDIT 控件,它将不
    // 发送此通知,除非重写 CDialogEx::OnInitDialog()
    // 函数并调用 CRichEditCtrl().SetEventMask(),
    // 同时将 ENM_CHANGE 标志“或”运算到掩码中。

    // TODO:  在此添加控件通知处理程序代码
    UpdateData(TRUE);

    long start, end;
    m_richedit.GetSel(start, end);//保存光标位置

    CHARFORMAT2 fm1, fm2;
    memset(&fm1, 0, sizeof(fm1));
    memset(&fm2, 0, sizeof(fm2));
    //CPoint pos = m_richedit.GetCaretPos();
    m_richedit.GetDefaultCharFormat(fm1);
    m_richedit.GetDefaultCharFormat(fm2);

    m_richedit.SetSel(0, -1);
    m_richedit.SetSelectionCharFormat(fm2);

    fm1.cbSize = sizeof(fm1);
    fm1.dwMask = CFM_COLOR;
    fm1.dwEffects &= ~CFE_AUTOCOLOR;

    setlocale(LC_ALL, "chs");
    m_text.Replace(TEXT("\r\n"), TEXT("\n"));
    wstring word;
    wstring text(m_text.GetBuffer());
    wstring::size_type index1 = 0;
    wstring::size_type index2 = -1;

    while ((index1 = text.find_first_of(L"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", index1)) != wstring::npos)
    {
        index2 = text.find_first_not_of(L"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", index1);
        word = text.substr(index1, index2-index1);//切分出每个单词

        if (blueText.find(word) != blueText.end())
        {
            fm1.crTextColor = RGB(0, 0, 255);
            m_richedit.SetSel(index1,index2);
            m_richedit.SetSelectionCharFormat(fm1);
        }
        else if (redText.find(word) != redText.end())
        {
            fm1.crTextColor = RGB(255, 0, 0);
            m_richedit.SetSel(index1, index2);
            m_richedit.SetSelectionCharFormat(fm1);
        }

        if (index2 == wstring::npos)
            break;
        else
            index1 = index2 + 1;
    }

    //处理一下注释,因为这是后来加上去的,所以在这里处理,整体效率又被拖低了
    index1 = index2 = 0;
    while ((index1 = text.find(wstring(L"\/\/"), index1)) != wstring::npos)
    {
        index2 = text.find_first_of(L"\n", index1);
        fm1.crTextColor = RGB(0, 255, 0);
        m_richedit.SetSel(index1, index2);
        m_richedit.SetSelectionCharFormat(fm1);
        if (index2 == wstring::npos)
            break;
        else
            index1 = index2;
    }

    m_richedit.SetSel(start, end);
    //m_richedit.SetCaretPos(pos);
    //m_richedit.SetSelectionCharFormat(fm2);//???
}
void CGEditorDlg::OnBnClickedButtonsave()
{
    // TODO:  在此添加控件通知处理程序代码
    UpdateData(TRUE);
    if (IDOK == MessageBox(TEXT("确定保存?"), TEXT("保存")))
    {
        ofstream ofs(m_filename.GetBuffer(),ios::trunc);
        if (!ofs.is_open())
        {
            MessageBox(TEXT("文件保存失败!"));
            ofs.close();
            return;
        }
        m_text.Replace(TEXT("\r\n"),TEXT("\n"));
        m_text.Replace(TEXT("    "), TEXT("\t"));
        setlocale(LC_ALL, "chs");
        ofs.write(CStringA(m_text).GetBuffer(), wcstombs(NULL,m_text.GetBuffer(),NULL));
        ofs.close();
    }
}
void CGEditorDlg::OnEnMsgfilterRichedit(NMHDR *pNMHDR, LRESULT *pResult)
{
    MSGFILTER *pMsgFilter = reinterpret_cast<MSGFILTER *>(pNMHDR);
    // TODO:  控件将不发送此通知,除非您重写
    // CDialogEx::OnInitDialog() 函数,以将 EM_SETEVENTMASK 消息发送
    // 到该控件,同时将 ENM_KEYEVENTS 或 ENM_MOUSEEVENTS 标志
    //“或”运算到 lParam 掩码中。

    // TODO:  在此添加控件通知处理程序代码
    if (pMsgFilter->msg == WM_KEYDOWN && pMsgFilter->wParam == VK_TAB)
    {
        UpdateData(TRUE);
        long start, end;
        m_richedit.GetSel(start, end);
        //CPoint pos = m_richedit.GetCaretPos();
        m_text += TEXT("    ");
        UpdateData(FALSE);//原来这里会改变光标的位置!!!
        //m_richedit.SetCaretPos(pos);
        m_richedit.SetSel(start+4, end+4);
        OnEnChangeRichedit();
        *pResult = 1;
    }
    else
        *pResult = 0;
}

工程地址

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017年06月29日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档