[分享]RichEdit控件的使用

满衣兄 2011-05-12 10:19:29
我们在使用聊天工具的时候经常会看到消息显示为各种颜色、字体、下划线、超链接识别等效果,使用微软为我们提供的RichEdit控件就可以达到这样的效果,但是RichEdit控件使用起来并不简单,甚至于在使用的时候让我们的窗体中充斥着RichEdit的代码,下面让我们重新封装这个控件,以方面我们以后的使用。
一、效果图:

二、源码:
RichEditCtrlEx.h


/////////////////////////////////////////////////////////////////////////////
// Name: RICHEDITCTRLEX.H
// Purpose: CRichEditCtrlEx
// Author: yfq
// Modified by:
// Created: 2010/12/24 11:01
// RCS-ID:
// Copyright:
// Licence:
/////////////////////////////////////////////////////////////////////////////

#ifndef __RICHEDITCTRLEX_H__
#define __RICHEDITCTRLEX_H__

class CRichEditCtrlEx : public CRichEditCtrl
{
DECLARE_DYNCREATE(CRichEditCtrlEx)
public:
CRichEditCtrlEx(void);
~CRichEditCtrlEx(void);

void Initlize();
/**
* 最后追加一行
*
* @param text -[in] -要追加的文本
*
* @param newline -[in] -是否换行
*
* @param link -[in] -是否带超链接
*
* @param nLinkBegin -[in] -超链接起始位置(索引从0开始)
*
* @param nLinkCount -[in] -超链接字符数
*
* @return -[NONE]
*/
void Append(LPCSTR text,bool newline = false,bool link = false,int nLinkBegin = 0,int nLinkCount = 0);

/**
* 获得文本
*
* @param nBegin -[in] -开始位置
*
* @param nEnd -[in] -结束位置
*
* @param text -[out] -得到的文本
*
* @return -[NONE]
*/
void GetText(int nBegin,int nEnd,CString& text);

/**
* 新增文字时是否滚动到底部
*
* @param bottom -[in] -否滚动到底部
*
* @return -[NONE]
*/
void SetScrollBottom(bool bottom=true);
void StopScroll();

/**
* 设置字体
*
* @param nBegin -[in] -开始位置
*
* @param nEnd -[in] -结束位置
*
* @param bold -[in] -粗体
*
* @param italic -[in] -斜体
*
* @param underline -[in] -下划线
*
* @param color -[in] -颜色
*
* @param size -[in] -文字大小
*
* @return -[NONE]
*/
void SetTextFont(int nBegin,int nEnd,bool bold,bool italic,bool underline,COLORREF color=0,int size=0);

/**
* 为选中的文本添加超链接
*
* @return -[NONE]
*/
void AddLink();

/**
* 取消选中文本添的超链接
*
* @return -[NONE]
*/
void CancelLink();

/**
* 校验URL是否合法文件路径,依据为rfc2396
* 这个函数只做粗略的校验,不完全符合RFC2369
* 仅支持IPV4
*
*/
BOOL CheckURL(const CString &szUrl, CString &szMsg);

void OnSize(CWnd* pParent);
void OnSize(CRect& rect);
void OnSpecifySize(CWnd* pParent);
bool IsCreate();
void Clear();
void SetEditFocus(bool focus);

/**
* 显示指定颜色的边框
*
* @param bShow -[in] -是否显示边框
*
* @param nColor -[in] -边框颜色
*
* @return -[NONE]
*/
void ShowBorderLine(BOOL bShow,COLORREF nColor = RGB(53, 104, 187));

/**
* 设置左侧偏移
*
* @param nOffset -[in] -偏移量
*
* @return -[NONE]
*/
void SetLeftOffset(int nOffset);
public:
afx_msg void OnPaint();
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg BOOL OnLink(NMHDR *in_pNotifyHeader, LRESULT *out_pResult);
afx_msg void OnSetFocus(CWnd* pOldWnd);
DECLARE_MESSAGE_MAP()

private:
CWnd* m_pParentWnd;
bool m_bBottom;
BOOL m_ShowBorder;
COLORREF m_BorderColor;
bool m_bCreate;
bool m_bFocus;
};

#endif //__RICHEDITCTRLEX_H__

...全文
3518 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
暮色已沉 2013-11-07
  • 打赏
  • 举报
回复
正好在找这种自己重新写的新控件类的用法,谢谢~!
warrior1 2011-09-16
  • 打赏
  • 举报
回复
楼主真的试过链接也能设置颜色?!
请不要想当然,你去试一下就知道你的代码对不对了!!!!!
x2010072710 2011-05-26
  • 打赏
  • 举报
回复
分享一下
__lhy 2011-05-26
  • 打赏
  • 举报
回复
多谢分享
Eleven 2011-05-26
  • 打赏
  • 举报
回复
不二星空 2011-05-26
  • 打赏
  • 举报
回复
RichEdit 好像很难。。。
ilyyangminglong1 2011-05-26
  • 打赏
  • 举报
回复
谢谢分享
满衣兄 2011-05-12
  • 打赏
  • 举报
回复
3、初始化控件
在窗体的OnInitDialog()中添加代码:m_RichEdit.Initlize();
4、其它函数的使用见代码注释

本文来源:http://www.looiy.com/?p=74
满衣兄 2011-05-12
  • 打赏
  • 举报
回复
RichEditCtrlEx.cpp

#include "StdAfx.h"
#include <afxinet.h>
#include "RichEditCtrlEx.h"

#pragma warning(disable:4996)

CRichEditCtrlEx::CRichEditCtrlEx(void)
{
m_ShowBorder = TRUE;
m_BorderColor = RGB(53, 104, 187);
m_bBottom = true;
m_bCreate = false;
m_bFocus = true;
AfxInitRichEdit2();
}

CRichEditCtrlEx::~CRichEditCtrlEx(void)
{
}

IMPLEMENT_DYNCREATE(CRichEditCtrlEx, CRichEditCtrl)
BEGIN_MESSAGE_MAP(CRichEditCtrlEx, CRichEditCtrl)
ON_WM_RBUTTONDOWN()
ON_WM_LBUTTONDBLCLK()
ON_WM_PAINT()
ON_NOTIFY_REFLECT_EX(EN_LINK, OnLink)
ON_WM_SETFOCUS()
END_MESSAGE_MAP()

void CRichEditCtrlEx::Initlize()
{
m_bBottom = true;
m_bCreate = true;
SetEventMask(GetEventMask() | ENM_LINK) ;
//SendMessage(EM_AUTOURLDETECT, TRUE, 0);
SetOptions(ECOOP_OR, ECO_AUTOVSCROLL);
LimitText(0xFFFFFFFF);
SetBackgroundColor(FALSE,RGB(248,248,248));
SetLeftOffset(150);
}
void CRichEditCtrlEx::Append(LPCSTR text,bool newline,bool link,int nLinkBegin,int nLinkCount)
{
int nPrvTotal = GetTextLengthEx( GTL_DEFAULT, 1200 );
SetSel(-1,-1);
ReplaceSel((LPCTSTR)text);
if (newline)
{
Append("\r\n");
}
if (link)
{
if (!newline)
{
Append("\r\n");
}
int nTotal = GetTextLengthEx( GTL_DEFAULT, 1200 ) - 1;
if( nTotal > 0)
{
if (nLinkCount>nTotal-nPrvTotal)
{
nLinkCount = nTotal-nPrvTotal;
}
SetSel( nPrvTotal+nLinkBegin, nPrvTotal+nLinkBegin+nLinkCount );
AddLink();
}
}
// 随着输入随着自动滚动条滚动到最后一行
if (m_bBottom)
{
PostMessage(WM_VSCROLL, SB_BOTTOM,0);
}
}
void CRichEditCtrlEx::GetText(int nBegin,int nEnd,CString& text)
{
CHARRANGE CharRange;
CharRange.cpMin = nBegin;
CharRange.cpMax = nEnd;
SetSel(CharRange);
CHAR szTmp[1024] = {0};
GetSelText(szTmp);
text.Format("%s",szTmp);
}
void CRichEditCtrlEx::SetScrollBottom(bool bottom)
{
m_bBottom = bottom;
}
void CRichEditCtrlEx::StopScroll()
{
m_bBottom = !m_bBottom;
if (m_bBottom)
{
PostMessage(WM_VSCROLL, SB_BOTTOM,0);
}
}
void CRichEditCtrlEx::SetTextFont(int nBegin,int nEnd,bool bold,bool italic,bool underline,COLORREF color,int size)
{
SetSel(nBegin,nEnd);
CHARFORMAT2 cf,oldCf;
GetSelectionCharFormat(oldCf);
GetSelectionCharFormat(cf);
if (bold)
{
cf.dwMask|=CFM_BOLD;
cf.dwEffects|=CFE_BOLD; //设置粗体,取消用cf.dwEffects&=~CFE_BOLD;
}
if (italic)
{
cf.dwMask|=CFM_ITALIC;
cf.dwEffects|=CFE_ITALIC; //设置斜体,取消用cf.dwEffects&=~CFE_ITALIC;
}
if (underline)
{
cf.dwMask|=CFM_UNDERLINE;
cf.dwEffects|=CFE_UNDERLINE; //设置下划线,取消用cf.dwEffects&=~CFE_UNDERLINE;
}
if (color)
{
cf.dwEffects &= ~CFE_AUTOCOLOR; //这个最重要,设选中文字颜色的时候也要注意,dwEffects一定不能有CEF_AUTOCOLOR的属性
cf.dwMask|=CFM_COLOR;
cf.crTextColor = color; //设置颜色
}
if (size)
{
cf.dwMask|=CFM_SIZE;
cf.yHeight =200; //设置高度
}
cf.dwMask|=CFM_FACE;
strcpy(cf.szFaceName ,_T("宋体"));//设置字体
SetSelectionCharFormat(cf);
SetSel(-1,-1);
SetSelectionCharFormat(oldCf);
}
void CRichEditCtrlEx::AddLink()
{
CHARFORMAT2 cf2;
ZeroMemory(&cf2, sizeof(CHARFORMAT2));
cf2.cbSize = sizeof(CHARFORMAT2);

cf2.dwMask |= CFM_LINK;
cf2.dwEffects |= CFE_LINK;

cf2.dwEffects &= ~CFE_AUTOCOLOR; //这个最重要,设选中文字颜色的时候也要注意,dwEffects一定不能有CEF_AUTOCOLOR的属性
cf2.dwMask |= CFM_COLOR;
cf2.crTextColor = RGB( 255, 112, 5 );

SetSelectionCharFormat(cf2);
SetSel( -1, -1 );
}

void CRichEditCtrlEx::CancelLink()
{
CHARFORMAT2 cf2;
ZeroMemory(&cf2, sizeof(CHARFORMAT2));
cf2.cbSize = sizeof(CHARFORMAT2);
cf2.dwMask = CFM_LINK;
cf2.dwEffects &= ~CFE_LINK;

SendMessage(EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2);
SetSel( -1, -1 );
}
BOOL CRichEditCtrlEx::CheckURL(const CString &szUrl, CString &szMsg)
{
DWORD dwService = 0;
DWORD dwValid = AFX_INET_SERVICE_FTP|AFX_INET_SERVICE_HTTP|AFX_INET_SERVICE_HTTPS|AFX_INET_SERVICE_FILE;
CString strServer;
CString strObject;
INTERNET_PORT port;

BOOL bValid = AfxParseURL(szUrl, dwService, strServer, strObject, port);
if (!bValid)
{
szMsg = szUrl + " \n不是一个合法的下载地址URL";
return FALSE;
}
return TRUE;
}
BOOL CRichEditCtrlEx::OnLink(NMHDR *pNotifyHeader, LRESULT *pResult)
{
ENLINK *pEnLink = reinterpret_cast<ENLINK *>(pNotifyHeader);
CString strURL;
*pResult = 0;
CHAR szTmpLink[512] = {0};
switch (pNotifyHeader->code)
{
case EN_LINK:
switch (pEnLink->msg)
{
case WM_LBUTTONUP:
SetSel(pEnLink->chrg);
GetSelText(szTmpLink);
strURL.Format("%s",szTmpLink);
CString strMsg;
if (CheckURL(strURL,strMsg))
{
ShellExecute(GetSafeHwnd(), _T("open"), strURL, NULL, NULL, SW_SHOWNORMAL);
}
break;
}
break;
}
return *pResult;
}

// We need to handle the OnSize message to ensure that the most recent
// line of text is visible.
void CRichEditCtrlEx::OnSize(UINT nType, int cx, int cy)
{
CRichEditCtrl::OnSize(nType, cx, cy);
}
void CRichEditCtrlEx::OnSize(CWnd* pParent)
{
if (!m_bCreate)
{
return;
}
CRect parentRect;
pParent->GetClientRect(parentRect);
parentRect.bottom = parentRect.bottom - 5;
parentRect.top = parentRect.top + 5;
parentRect.left = parentRect.left + 5;
parentRect.right = parentRect.right - 5;
MoveWindow(parentRect,TRUE);
}
void CRichEditCtrlEx::OnSize(CRect& rect)
{
if (!m_bCreate)
{
return;
}
rect.bottom = rect.bottom - 5;
rect.top = rect.top + 5;
rect.left = rect.left + 5;
rect.right = rect.right - 5;
MoveWindow(rect,TRUE);
}
void CRichEditCtrlEx::OnSpecifySize(CWnd* pParent)
{
if (!m_bCreate)
{
return;
}
CRect parentRect;
pParent->GetClientRect(parentRect);
parentRect.left = 5;
parentRect.top = 197;
parentRect.right -= 5;
parentRect.bottom -= 5;
MoveWindow(parentRect,TRUE);

}
void CRichEditCtrlEx::OnPaint()
{
if (!m_ShowBorder)
{
CRichEditCtrl::OnPaint();
return;
}
CRichEditCtrl::OnPaint();
CClientDC dc(this);
if (!m_pParentWnd)
{
return;
}
CRect rect;
GetWindowRect(rect);
rect.left-=1;
rect.top-=1;
rect.right+=1;
rect.bottom+=1;
ScreenToClient(rect);
dc.Draw3dRect(rect,m_BorderColor,m_BorderColor);
}
// 如果控件可以获得焦点,则当控件有焦点时会自动滚动到底部,所以要屏蔽一下
void CRichEditCtrlEx::OnSetFocus(CWnd* pOldWnd)
{
if (!m_bFocus)
{
return;
}
CRichEditCtrl::OnSetFocus(pOldWnd);
}

bool CRichEditCtrlEx::IsCreate()
{
return m_bCreate;
}
void CRichEditCtrlEx::Clear()
{
if (GetWindowLong(this->m_hWnd,GWL_STYLE) & ES_READONLY)
{
SetReadOnly(FALSE);
CRichEditCtrl::Clear();
SetReadOnly();
}
else
{
CRichEditCtrl::Clear();
}
}
void CRichEditCtrlEx::SetEditFocus(bool focus)
{
m_bFocus = focus;
}
void CRichEditCtrlEx::ShowBorderLine(BOOL bShow,COLORREF nColor)
{
m_ShowBorder = bShow;
}
void CRichEditCtrlEx::SetLeftOffset(int nOffset)
{
PARAFORMAT2 PF_his;
PF_his.dwMask = PFM_ALIGNMENT|PFM_STARTINDENT;
PF_his.wAlignment = PFA_LEFT;
PF_his.dxStartIndent = nOffset;
SetParaFormat(PF_his);
}
#pragma warning(default:4996)

三、使用方法
1、在窗体上放一个Rich Edit 2.0 Control,修改属性,例如,你需要多行显示则要把Multiline属性设置为TRUE,如果需要垂直滚动条则需要把Vertical Scroll属性设置为TRUE
2、为新添加的RichEdit控件关联控件变量:
在头文件中声明CRichEditCtrlEx m_RichEdit;
在DoDataExchange中写入DDX_Control(pDX, IDC_RICHEDIT21, m_RichEdit);

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧