一.常見(jiàn)問(wèn)題
a.可以編譯,不能執(zhí)行的
AfxInitRichEdit();
b.升級(jí)默認(rèn)的Riched版本(默認(rèn)的有一些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 );
顯示回車(chē)換行:
設(shè)屬性:"Multi lines"選為T(mén)rue。
設(shè)屬性:"want return "選為T(mén)rue。
d.字?jǐn)?shù)限制
CRichEditCtrl::LimitText(long nChars)
e.換行切換
CRichEditView的OnInitialUpdate()函數(shù)中加入下面兩句:
m_nWordWrap = WrapNone;
WrapChanged();
WrapChanged實(shí)際上也是調(diào)用
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.有時(shí)候不希望帶格式的數(shù)據(jù)粘貼,可通過(guò)PasteSpecial選擇性粘貼
pmyRichEditCtrl->PasteSpecial(CF_TEXT);
g.隨著輸入隨著自動(dòng)滾動(dòng)條滾動(dòng)到最后一行
int nFirstVisible = pmyRichEditCtrl->GetFirstVisibleLine();
if (nFirstVisible > 0)
{
pmyRichEditCtrl->LineScroll(-nFirstVisible, 0);
}
或
m_cRichEdit.PostMessage(WM_VSCROLL, SB_BOTTOM,0);
h.設(shè)置UNDO的次數(shù)(只能用在RICHED20以上,即默認(rèn)不支持,必須升級(jí))
SendMessage(EM_SETTEXTMODE,TM_MULTILEVELUNDO,0);
TM_MULTILEVELUNDO 支持多取消(默認(rèn)值).可通過(guò)EM_SETUNDOLIMIT設(shè)置最大次數(shù)
SendMessage(EM_SETUNDOLIMIT,100,0);
i.響應(yīng)OnChange
EM_SETEVENTMASK 設(shè)置 ENM_CHANGE
long lMask = GetEventMask();
lMask |= ENM_CHANGE;
lMask &= ~ENM_PROTECTED;
SetEventMask(lMask);
j.設(shè)置只讀
CRichEditCtrl::SetReadOnly( BOOL bReadOnly = TRUE );
通過(guò)設(shè)置PROTECTED實(shí)現(xiàn)選中的文本只讀,參見(jiàn)
http://www.codeguru.com/Cpp/controls/richedit/article.php/c2401/
二.函數(shù)應(yīng)用
a.設(shè)置字體(主要是通過(guò)SetSelectionCharFormat)
CHARFORMAT cf;
ZeroMemory(&cf, sizeof(CHARFORMAT));
cf.cbSize = sizeof(CHARFORMAT);
cf.dwMask|=CFM_BOLD;
cf.dwEffects|=CFE_BOLD;//設(shè)置粗體,取消用cf.dwEffects&=~CFE_BOLD;
cf.dwMask|=CFM_ITALIC;
cf.dwEffects|=CFE_ITALIC;//設(shè)置斜體,取消用cf.dwEffects&=~CFE_ITALIC;
cf.dwMask|=CFM_UNDERLINE;
cf.dwEffects|=CFE_UNDERLINE;//設(shè)置斜體,取消用cf.dwEffects&=~CFE_UNDERLINE;
cf.dwMask|=CFM_COLOR;
cf.crTextColor = RGB(255,0,0);//設(shè)置顏色
cf.dwMask|=CFM_SIZE;
cf.yHeight =200;//設(shè)置高度
cf.dwMask|=CFM_FACE;
strcpy(cf.szFaceName ,_T("隸書(shū)"));//設(shè)置字體
rich.SetSelectionCharFormat(cf);
b.設(shè)置字體的行間距
要用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 才起作用,項(xiàng)目符號(hào),默認(rèn)用PFN_BULLET
2 使用阿拉伯?dāng)?shù)字 (1, 2, 3, ...).
3 使用小寫(xiě)字母 (a, b, c, ...).
4 使用大寫(xiě)字母 (A, B, C, ...).
5 使用小寫(xiě)羅馬數(shù)字 (i, ii, iii, ...).
6 使用大寫(xiě)羅馬數(shù)字 (I, II, III, ...).
7 自定義,字符見(jiàn)成員 wNumberingStart.
PFM_OFFSET 成員 dxOffset 才起作用,縮進(jìn),單位twips
PFM_STARTINDENT 成員 dxStartIndent 才起作用,首行縮進(jìn)
PFM_SPACEAFTER 成員 dySpaceAfter 才起作用,段間距
PFM_LINESPACING 成員 dyLineSpacing 才起作用,行間距
c.設(shè)置CRichEditCtrl(2.0)背景透明
long style = ::GetWindowLong(GetSafeHwnd(), GWL_EXSTYLE);
style &= WS_EX_TRANSPARENT;
::SetWindowLong(GetSafeHwnd(), GWL_EXSTYLE, style);
或 CreateEx,然后把WS_EX_TRANSPARENT樣式加上
e.得到內(nèi)容有三種
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;//設(shè)置用例參數(shù),以便回調(diào)函數(shù)調(diào)用
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);
如果要繼續(xù)查找,修改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格式保存
目前做法可先轉(zhuǎn)為RTF格式,再通過(guò)RTF-to-HTML Converter
http://www.codeguru.com/Cpp/controls/richedit/conversions/article.php/c5377/
h.重載OnProtected函數(shù)得到對(duì)應(yīng)的消息,如粘貼等
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. 創(chuàng)建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. 設(shè)定選中的文字為鏈接顯示
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.支持鏈接的點(diǎn)擊響應(yīng)
m_cRichEdit.SetEventMask(ENM_LINK);
5.響應(yīng)鏈接的點(diǎn)擊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);//這是鏈接文字
//后面是你的處理過(guò)程
......
}
}
b.插入位圖
http://www.codeguru.com/Cpp/controls/richedit/article.php/c2417/
http://www.codeguru.com/Cpp/controls/richedit/article.php/c5383/
自定義在RichEdit中插入對(duì)象的圖標(biāo)
http://www.blogcn.com/user3/jiangsheng/blog/1319738.html
方法基本同Knowledge Base文章Q220844 HOWTO: Insert a Bitmap Into an RTF Document Using the RichEdit Control
只是在最后插入之前調(diào)用一下IOleCache::SetData,用一個(gè)HGLOBAL作為參數(shù),HGLOBAL里面的數(shù)據(jù)是一個(gè)METAFILEPICT結(jié)構(gòu),包含自己提供的圖片
使用CRichEditView::InsertFileAsObject就可以插入圖像。VC++帶有一個(gè)例子WordPad。
另外可以參考“Insert any HBITMAP (Bitmap) in your RichEdit Control”(http://www.codeguru.com/richedit/richeditrc.html)。
c.顯示GIF動(dòng)畫(huà)
常用的是通過(guò)qq的imageole.dll(也有用Gif89.dll的)
http://www.xiaozhou.net/cooldog/blogview.asp?logID=82
http://www.codeproject.com/richedit/AnimatedEmoticon.asp
在richedit控件中插入動(dòng)態(tài)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 信息發(fā)送框的制作(上)
http://www.vckbase.com/document/viewdoc/?id=1087
內(nèi)容包含:實(shí)現(xiàn)右鍵菜單,圖片插入,讀取/寫(xiě)入RTF格式字符串
自定義 CRichEditCtrl 控件
http://www.vckbase.com/document/viewdoc/?id=328
內(nèi)容包含:鼠標(biāo)右鍵消息,消息映射,字體變換
PS.richedit控件升級(jí)到2.0后,先把字體設(shè)為楷體,輸入漢字沒(méi)有問(wèn)題,但輸入字母時(shí),字母自動(dòng)跳轉(zhuǎn)為Arial字體,而1.0卻沒(méi)有這個(gè)文題,仍然是用楷體顯示字母
是一個(gè)專門(mén)的設(shè)計(jì) Dual-font, Smart font apply, 參見(jiàn) http://61.186.252.131/Expert/topic/913/913807.xml?temp=.3753778