鱼C论坛

 找回密码
 立即注册

RichEdit使用大全

已有 458 次阅读2013-8-9 09:36 |个人分类:WIN32学习

.常见问题

a.
可以编译,不能执行的
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;
ZeroMemory(&cf, sizeof(CHARFORMAT));
cf.cbSize = sizeof(CHARFORMAT);
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
使用阿拉伯数字 (1, 2, 3, ...).  
使用小写字母 (a, b, c, ...).  
使用大写字母 (A, B, C, ...).  
使用小写罗马数字 (i, ii, iii, ...).  
使用大写罗马数字 (I, II, III, ...).  
自定义,字符见成员 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)>,(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动画
常用的是通过qqimageole.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


路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)

facelist

您需要登录后才可以评论 登录 | 立即注册

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-18 02:28

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

返回顶部