`

(转)RichEdit 的用法

阅读更多
(转)RichEdit 的用法
2008-05-25 10:47

很不错的源代码

http://www.pudn.com/search_db.asp?keyword=MyRichEdit&x=36&y=16

richedit 常见使用问题
一.常见问题
a.可以编译,不能执行的

 

在需要在相应的对话框中加上 InitInstance void )函数中添加

AfxInitRichEdit();

b.升级默认的Riched版本(默认的有一些bug),如
可在InitInstance中添加
LoadLibrary("RICHED20.DLL")
最后注意 FreeLibrary

如果是CRichEditView基类的可用
BOOL CXXXXXXView::PreCreateWindow(CREATESTRUCT& cs)
{
//装入rich edit version 2.0
if (LoadLibraryA("RICHED20.DLL") == NULL)
{
AfxMessageBox(_T("Fail to load \"riched20.dll\"."),MB_OK | MB_ICONERROR);
PostMessage(WM_QUIT,0,0);
return FALSE;
}

m_strClass = RICHEDIT_CLASSA;//for 2.0 class

return CRichEditView::PreCreateWindow(cs);
}

c.最后追加行
richeditctrl.SetSel(-1, -1);
richeditctrl.ReplaceSel( (LPCTSTR)str );

d.字数限制
CRichEditCtrl::LimitText(long nChars)

e.换行切换
CRichEditView的OnInitialUpdate()函数中加入下面两句:
m_nWordWrap = WrapNone;
WrapChanged();
WrapChanged实际上也是调用
ctrl.SetTargetDevice(NULL, 1); //m_nWordWrap == WrapNone
ctrl.SetTargetDevice(NULL, 0); //m_nWordWrap == WrapToWindow
还有不常用的 m_nWordWrap == WrapToTargetDevice
ctrl.SetTargetDevice(m_dcTarget, GetPrintWidth());
如果是在Dialog中,可使用SetTargetDevice,注意在属性里面加上want return

f.有时候不希望带格式的数据粘贴,可通过PasteSpecial选择性粘贴
pmyRichEditCtrl->PasteSpecial(CF_TEXT);

g.随着输入随着自动滚动条滚动到最后一行
int nFirstVisible = pmyRichEditCtrl->GetFirstVisibleLine();
if (nFirstVisible > 0)
{
    pmyRichEditCtrl->LineScroll(-nFirstVisible, 0);
}

m_cRichEdit.PostMessage(WM_VSCROLL, SB_BOTTOM,0);


h.设置UNDO的次数(只能用在RICHED20以上,即默认不支持,必须升级)
SendMessage(EM_SETTEXTMODE,TM_MULTILEVELUNDO,0);
TM_MULTILEVELUNDO 支持多取消(默认值).可通过EM_SETUNDOLIMIT设置最大次数
SendMessage(EM_SETUNDOLIMIT,100,0);

i.响应OnChange
EM_SETEVENTMASK 设置 ENM_CHANGE
long lMask = GetEventMask();
lMask |= ENM_CHANGE;
lMask &= ~ENM_PROTECTED;
SetEventMask(lMask);

j.设置只读
CRichEditCtrl::SetReadOnly( BOOL bReadOnly = TRUE );
通过设置PROTECTED实现选中的文本只读,参见
http://www.codeguru.com/Cpp/controls/richedit/article.php/c2401/


二.函数应用
a.设置字体(主要是通过SetSelectionCharFormat)
CHARFORMAT cf;
rich.GetSelectionCharFormat(cf);
cf.dwMask|=CFM_BOLD;
cf.dwEffects|=CFE_BOLD;//设置粗体,取消用cf.dwEffects&=~CFE_BOLD;
cf.dwMask|=CFM_ITALIC;
cf.dwEffects|=CFE_ITALIC;//设置斜体,取消用cf.dwEffects&=~CFE_ITALIC;
cf.dwMask|=CFM_UNDERLINE;
cf.dwEffects|=CFE_UNDERLINE;//设置斜体,取消用cf.dwEffects&=~CFE_UNDERLINE;
cf.dwMask|=CFM_COLOR;
cf.crTextColor = RGB(255,0,0);//设置颜色
cf.dwMask|=CFM_SIZE;
cf.yHeight =200;//设置高度
cf.dwMask|=CFM_FACE;
strcpy(cf.szFaceName ,_T("隶书"));//设置字体
rich.SetSelectionCharFormat(cf);

b.设置字体的行间距
要用richedit2.0以上
试试
PARAFORMAT2 pf;
pf.cbSize = sizeof(PARAFORMAT2);
pf.dwMask = PFM_NUMBERING | PFM_OFFSET;
pf.wNumbering = PFN_BULLET;//注意PFM_NUMBERING
pf.dxOffset = 10;
VERIFY(SetParaFormat(pf));
常用的dwMask有
PFM_NUMBERING 成员 wNumbering 才起作用,项目符号,默认用PFN_BULLET
2 使用阿拉伯数字 (1, 2, 3, ...).  
3 使用小写字母 (a, b, c, ...).  
4 使用大写字母 (A, B, C, ...).  
5 使用小写罗马数字 (i, ii, iii, ...).  
6 使用大写罗马数字 (I, II, III, ...).  
7 自定义,字符见成员 wNumberingStart.  
PFM_OFFSET 成员 dxOffset 才起作用,缩进,单位twips
PFM_STARTINDENT 成员 dxStartIndent 才起作用,首行缩进
PFM_SPACEAFTER 成员 dySpaceAfter 才起作用,段间距
PFM_LINESPACING 成员 dyLineSpacing 才起作用,行间距

c.设置CRichEditCtrl(2.0)背景透明
long style = ::GetWindowLong(GetSafeHwnd(), GWL_EXSTYLE);
style &= WS_EX_TRANSPARENT;
::SetWindowLong(GetSafeHwnd(), GWL_EXSTYLE, style);
或 CreateEx,然后把WS_EX_TRANSPARENT样式加上

e.得到内容有三种
1)GetWindowText
2)使用EM_GETTEXTEX
GETTEXTEX gt;
gt.cb = 200;
gt.flags = GT_DEFAULT;
gt.codepage = CP_ACP ;
gt.lpDefaultChar = NULL;
gt.lpUsedDefChar = NULL;
SendMessage(EM_GETTEXTEX,(WPARAM)&gt,(LPARAM)text);
3)StreamOut(主要用于RTF等格式输出)
static DWORD CALLBACK
MyStreamOutCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
    CFile* pFile = (CFile*) dwCookie;

    pFile->Write(pbBuff, cb);
    *pcb = cb;

    return 0;
}


    CFile cFile(TEXT("myfile.rtf"), CFile::modeCreate|CFile::modeWrite);
    EDITSTREAM es;
    es.dwCookie = (DWORD) &cFile;//设置用例参数,以便回调函数调用
    es.pfnCallback = MyStreamOutCallback;
    pmyRichEditCtrl->StreamOut(SF_RTF, es);
读入可以此类推,SetWindowText,EM_SETTEXTEX,StreamIn

f.查找字符串
FINDTEXTEX ft;
ft.chrg.cpMin = 0;
ft.chrg.cpMax = -1;
ft.lpstrText = "|";
long lPos = FindText(0, &ft);

如果要继续查找,修改cpMin,如
int nCount = 0;
do
{
long lPos = GetRichEditCtrl().FindText(0, &ft);
if( -1 == lPos) break;
ft.chrg.cpMin = lPos + strlen(ft.lpstrText);
++nCount;
}while(TRUE);

g.以Html格式保存
目前做法可先转为RTF格式,再通过RTF-to-HTML Converter

http://www.codeguru.com/Cpp/controls/richedit/conversions/article.php/c5377/

h.重载OnProtected函数得到对应的消息,如粘贴等
void CMYichEditorView::OnProtected(NMHDR* pNMHDR, LRESULT* pResult)
{
ENPROTECTED* pEP = (ENPROTECTED*)pNMHDR;

switch (pEP->msg) {
case WM_KEYDOWN://按键,判断pEP->wParam
case WM_PASTE://粘贴
case WM_CUT://剪切
case EM_SETCHARFORMAT:
default:
   break;
};

*pResult = FALSE;
}

三.聊天常用  
a.LINK 链接功能
1.   LoadLibrary(_T("Riched20.dll"));
2. 创建RichEdit2.0控件
CreateEx(0, _T("RichEdit20A"), NULL, WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_TABSTOP
|ES_READONLY|ES_WANTRETURN|ES_MULTILINE,
           rect.left, rect.top, cx, cy,
   pParentWnd->m_hWnd, (HMENU)nID, NULL);
3. 设定选中的文字为链接显示
CHARFORMAT2 cf2;
ZeroMemory(&cf2, sizeof(CHARFORMAT2));//
cf2.cbSize = sizeof(CHARFORMAT2);
cf2.dwMask = CFM_LINK;
cf2.dwEffects |= CFE_LINK;
m_cRichEdit.SendMessage(EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2);
4.支持链接的点击响应
m_cRichEdit.SetEventMask(ENM_LINK);
5.响应链接的点击EN_LINK

BEGIN_MESSAGE_MAP(CMyRichEdit, CRichEditCtrl)
ON_NOTIFY_REFLECT(EN_LINK,OnURL)
END_MESSAGE_MAP()
......

void CMyRichEdit::OnURLClick(NMHDR *pNmhdr, LRESULT *pResult)
{
TCHAR LinkChar[512];
ENLINK *pLink = (ENLINK *)pNmhdr;
if (pLink->msg == WM_LBUTTONUP)
{
SetSel(penLink->chrg);//这是链接的文字范围
long Res = GetSelText((char *)LinkChar);//这是链接文字
                   //后面是你的处理过程
                   ......
          }
}

b.插入位图
http://www.codeguru.com/Cpp/controls/richedit/article.php/c2417/
http://www.codeguru.com/Cpp/controls/richedit/article.php/c5383/

自定义在RichEdit中插入对象的图标
http://www.blogcn.com/user3/jiangsheng/blog/1319738.html
方法基本同Knowledge Base文章Q220844 HOWTO: Insert a Bitmap Into an RTF Document Using the RichEdit Control
只是在最后插入之前调用一下IOleCache::SetData,用一个HGLOBAL作为参数,HGLOBAL里面的数据是一个METAFILEPICT结构,包含自己提供的图片

使用CRichEditView::InsertFileAsObject就可以插入图像。VC++带有一个例子WordPad。
另外可以参考“Insert any HBITMAP (Bitmap) in your RichEdit Control”(http://www.codeguru.com/richedit/richeditrc.html )。

c.显示GIF动画
常用的是通过qq的imageole.dll(也有用Gif89.dll的)
http://www.xiaozhou.net/cooldog/blogview.asp?logID=82
http://www.codeproject.com/richedit/AnimatedEmoticon.asp

在richedit控件中插入动态GIF (Native C++版)
http://blog.joycode.com/jiangsheng/archive/2004/12/15/41209.aspx

d.IRichEditOleCallback的使用
http://61.186.252.131/Expert/topic/905/905844.xml?temp=.8379022

类似 MSN 信息发送框的制作(上)
http://www.vckbase.com/document/viewdoc/?id=1087
内容包含:实现右键菜单,图片插入,读取/写入RTF格式字符串

自定义 CRichEditCtrl 控件
http://www.vckbase.com/document/viewdoc/?id=328
内容包含:鼠标右键消息,消息映射,字体变换


PS.richedit控件升级到2.0后,先把字体设为楷体,输入汉字没有问题,但输入字母时,字母自动跳转为Arial字体,而1.0却没有这个文题,仍然是用楷体显示字母
是一个专门的设计 Dual-font, Smart font apply, 参见 http://61.186.252.131/Expert/topic/913/913807.xml?temp=.3753778


不能显示图片等其他OLE对象

MFC提供的CRichEditCtrl没有提供直接显示图片等OLE对象的属性或方法设置,但是提供了一个接口SetOLECallback( IRichEditOleCallback* pCallback );
要让CRichEditCtrl显示图片,就得在IRichEditOleCallback上下功夫。
IRichEditOleCallback是windows中的接口,它的定义如下:
ContextSensitiveHelp:
    通过该方 法通知应用程序它将以上下文关联方式调度帮助。
DeleteObject:
    通过该方 法发出通知:一个对象即将从RichEdit控件中删除
GetClipboardData:
    通过该方法 允许RichEdit的客户端(调用程序)提供自己的粘贴对象
GetContextMenu:
    通过该方法向 应用程序提出通过鼠标右键事件来获取上下文菜单的请求
GetDragDropEffect:
    通过该方法允许RichEdit的客户端(调用程序)设置拖动操作的效果
GetInPlaceContext:
   通过该方法提供了应用程序级和文档级接口,以及必要的支持In-place激活的信息
GetNewStrorage:
    通过该方 法存储从粘贴板或超文本流(RTF)中读取的新对象
QueryAcceptData:
    通过该方法决定在粘贴操作或拖放操作中引入的数据是否可以被接受。
QueryInsertObject:
    通过该方法向应用程序询问某个对象是否可以被插入
ShowContainerUI:
   
通过该方法告知应用程序是否显示自己的操作界面

大致了解了IRichEditOleCallback接口后,就应该清楚,要显示图片等ole对象,至少应该实现GetNewStorage方法,因为该方法是存储ole对象的接口方法。

以下是接口声明的代码:
    interface IExRichEditOleCallback;   // forward declaration (see below in this header file)

   IExRichEditOleCallback* m_pIRichEditOleCallback;
   BOOL m_bCallbackSet;
  
  
   interface IExRichEditOleCallback : public IRichEditOleCallback
   {
   public:
       IExRichEditOleCallback();
       virtual ~IExRichEditOleCallback();
       int m_iNumStorages;
       IStorage* pStorage;
       DWORD m_dwRef;

       virtual HRESULT STDMETHODCALLTYPE GetNewStorage(LPSTORAGE* lplpstg);
       virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void ** ppvObject);
       virtual ULONG STDMETHODCALLTYPE AddRef();
       virtual ULONG STDMETHODCALLTYPE Release();
       virtual HRESULT STDMETHODCALLTYPE GetInPlaceContext(LPOLEINPLACEFRAME FAR *lplpFrame,
           LPOLEINPLACEUIWINDOW FAR *lplpDoc, LPOLEINPLACEFRAMEINFO lpFrameInfo);
        virtual HRESULT STDMETHODCALLTYPE ShowContainerUI(BOOL fShow);
        virtual HRESULT STDMETHODCALLTYPE QueryInsertObject(LPCLSID lpclsid, LPSTORAGE lpstg, LONG cp);
        virtual HRESULT STDMETHODCALLTYPE DeleteObject(LPOLEOBJECT lpoleobj);
        virtual HRESULT STDMETHODCALLTYPE QueryAcceptData(LPDATAOBJECT lpdataobj, CLIPFORMAT FAR *lpcfFormat,
           DWORD reco, BOOL fReally, HGLOBAL hMetaPict);
        virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode);
        virtual HRESULT STDMETHODCALLTYPE GetClipboardData(CHARRANGE FAR *lpchrg, DWORD reco, LPDATAOBJECT FAR *lplpdataobj);
        virtual HRESULT STDMETHODCALLTYPE GetDragDropEffect(BOOL fDrag, DWORD grfKeyState, LPDWORD pdwEffect);
        virtual HRESULT STDMETHODCALLTYPE GetContextMenu(WORD seltyp, LPOLEOBJECT lpoleobj, CHARRANGE FAR *lpchrg,
           HMENU FAR *lphmenu);
   };

分享到:
评论

相关推荐

    RichEdit控件删除行和自动滚屏

    首先,我们需要了解RichEdit控件的基本用法。RichEdit控件是Microsoft提供的MFC(Microsoft Foundation Classes)库中的一个类,通常用CEdit或CRichEditCtrl表示。通过继承这个类,我们可以获取其丰富的文本处理能力...

    vc richedit 设置字体颜色

    首先,我们需要理解RichEdit控件的基本使用。RichEdit控件是基于Microsoft的Rich Edit API,通常通过MFC(Microsoft Foundation Classes)库中的CRichEditCtrl类进行操作。CRichEditCtrl类提供了一系列的方法,用于...

    使用Rich Edit控件显示文本文件

    在Visual Studio的资源编辑器中,选择控件类型为"其他",然后在属性窗口中将其Class设置为`RICHEDIT`或`RichEdit20A`,这取决于你需要的功能和兼容性需求。 创建控件后,需要在代码中初始化它。在对话框或窗口类的`...

    实现带行号的 richedit 控件

    1. **扩展RichEdit控件**:创建一个继承自标准RichEdit控件的新类,这样我们可以重写或添加新的方法和属性。 2. **计算行号**:每当文本改变或控件滚动时,需要实时计算当前显示的行数,这可能需要监听控件的某些...

    RichEdit选中行高亮显示及加入超链接-代码

    在IT行业中,富文本编辑器(RichEdit)是一种常见的组件,用于在应用程序中提供复杂的文本编辑功能,如格式化文本、插入图片、设置字体样式等。在Delphi编程环境中,我们可以利用其强大的功能来实现一些高级特性,...

    RichEdit中插入图片,文字以及美化设置

    例如,你可以创建一个包含粗体、斜体和颜色的RTF字符串,然后使用`RichEdit::Paste`或`RichEdit::SetWindowText`方法插入。 3. API函数:对于更复杂的操作,如插入特定位置或批量插入,可以使用`EM_SETSEL`选择位置...

    RichEdit链接使用

    3. 检测链接:当收到EM_LINK消息时,需要获取链接的范围(通过msg->nmhdr.code参数),然后使用RichEdit的GetTextRange方法提取链接文本。然后,根据你的自定义规则(比如特定的前缀或后缀)检查这个文本,判断它...

    RichEdit 自动换行关键字高亮

    1. 获取`RichEdit`控件的`ITextDocument`接口:首先,需要包含`riched20.h`头文件,并且使用`CoCreateInstance`函数创建`IRichEditOle`接口实例,然后通过`IRichEditOle::GetDocument`方法获取`ITextDocument`接口。...

    delphi 控件richedit 操作,类似记事本查找,替换,字体设计等

    这个方法允许你在RichEdit控件的文本中搜索指定的字符串。例如: ```delphi var StartPos: Integer; begin StartPos := RichEdit1.SelStart; while (StartPos <= RichEdit1.TextLength) do begin if RichEdit1...

    RichEdit 回车换行的2种方法

    ### RichEdit 控件回车换行的两种方法 在Windows编程中,经常需要用到文本编辑功能。其中,`RichEdit`控件因其丰富的编辑能力和自定义选项而被广泛应用于各种应用程序中。本文将详细介绍如何使`RichEdit`控件在用户...

    RICHEDIT复制简单方法

    ### RICHEDIT复制方法详解 #### 一、RICHEDIT简介 RICHEDIT是一种支持丰富文本格式化的编辑器控制,可以...这种方法不仅适用于Delphi环境下的开发工作,对于其他使用类似RICHEDIT控件的开发场景也具有一定的参考价值。

    RichEdit的使用

    `StreamIn`和`StreamOut`方法允许读写RTF(Rich Text Format)或纯文本,使得数据可以在不同RichEdit控件之间传递。 为了响应用户的交互,比如点击按钮改变字体或颜色,你需要在`RichEditTestDlg.cpp`中定义消息...

    VC++显示RichEdit控件的实例源码

    总的来说,这个"VC++显示RichEdit控件的实例源码"是一个实用的教学资源,通过分析和理解源码,开发者可以掌握在VC++环境下使用RichEdit控件进行富文本编辑的基本方法。同时,这也展示了MFC框架下控件操作的通用性,...

    RichEdit的几个实例

    **标题:“RichEdit的几个实例”** 在计算机编程领域,特别是在Windows应用...通过研究和实践这些实例,你不仅可以掌握`RichEdit`的基本用法,还能了解到如何在实际项目中灵活应用,提高Windows应用程序的用户体验。

    RichEdit图文混排

    在C++Builder6的RichEdit中,可以使用`EM_INSERTIMAGE`消息或TRichView组件的InsertImage方法来插入图片。图片的位置可以通过设置其左上角相对于文本的坐标,或者通过设置图像的对齐方式来调整。此外,还要考虑文本...

    有背景图片的richedit

    描述中提到的方法是通过设置RichEdit控件的`WS_EX_TRANSPARENT`扩展窗口风格,并在父窗口中绘制背景图片。`WS_EX_TRANSPARENT`风格使得控件变得透明,允许底层窗口的内容透过显示。这样,我们可以在父窗口的 WM_...

    richedit.rar

    而"richedit.rar"这个压缩包文件,显然与Duilib中的RichEdit控件有关,这是一个增强型的文本编辑器控件,适用于创建聊天窗口或者其他需要展示丰富内容的应用场景。 RichEdit控件相比于标准的Edit控件,支持更多的...

    RichEdit 简单应用

    输出文本内容到RichEdit控件,可以使用CRichEditCtrl的SetWindowText或AppendText方法。SetWindowText会替换当前的所有文本,而AppendText则会在现有文本后追加新的文本。例如: ```cpp m_richEdit.SetWindowText(_...

    richedit显示bmp图片

    通常,RichEdit控件默认并不直接支持显示图片,因此需要通过一些特殊的方法来实现这一功能,这可能涉及到自定义绘制、消息处理以及对RTF格式的深入理解。 从标签“网上下载的”我们可以推测,这可能是一个从网络上...

    在SDK中使用Rich Edit控件,以及使用LISTVIEW,PROGRESS等控件

    Rich Edit 控件是一个特殊的控件,在不使用 MFC 的情况下,需要手动加载 RichEdit DLL。可以在响应主窗口的 WM_CREATE 消息中加载 DLL,使用 LoadLibrary 函数加载 RICHED32.DLL,然后创建控件。在程序退出时,需要...

Global site tag (gtag.js) - Google Analytics