一般性問題
1.
代碼編譯通過了,運行后RichEdit控件不顯示,在InitInstance中添加
代碼編譯通過了,運行后RichEdit控件不顯示,在InitInstance中添加
BOOL CWinApp::InitInstance ()
{
…
AfxInitRichEdit(); - RichEdit 1.0
或 AfxInitRichEdit2(); - RichEdit 2.0
…
}
2.
升級默認的RichEdit版本,默認的版本有BUG,在InitInstance中添加
升級默認的RichEdit版本,默認的版本有BUG,在InitInstance中添加
BOOL CWinApp::InitInstance ()
{
…
LoadLibrary("RICHED20.DLL");
…
FreeLibrary();
}
如果是CRichEditView基類的話,可用如下消息機制:
BOOL CRichEditView::PreCreateWindow(CREATESTRUCT& cs)
{
if (LoadLibraryA("RICHED20.DLL") == NULL)
{
AfxMessageBox(_T("Fail to load /"riched20.dll/"."),MB_OK | MB_ICONERROR);
PostMessage(WM_QUIT,0,0);
return FALSE;
return FALSE;
}
m_strClass = RICHEDIT_CLASSA;
return CRichEditView::PreCreateWindow(cs);
}
}
3.
在RichEdit控件的輸入框中最后追加一行
在RichEdit控件的輸入框中最后追加一行
CRichEditCtrl.SetSel(-1, -1);
CRichEditCtrl.ReplaceSel((LPCTSTR)str);
CRichEditCtrl.ReplaceSel((LPCTSTR)str);
4.
限制RichEdit控件的字數
限制RichEdit控件的字數
CRichEditCtrl.LimitText(long nChars)
5.
設置RichEdit控件的換行切換
設置RichEdit控件的換行切換
如果是CRichEditView基類的話,可用如下消息機制:
BOOL CRichEditView::OnInitialUpdate()
{
…
m_nWordWrap = WrapNone;
WrapChanged();
…
}
如果是在Dialog,可使用SetTargetDevice,並在RichEdit的屬性里面加上want
return
return
CRichEditCtrl.SetTargetDevice(m_dcTarget, GetPrintWidth());
WrapChanged實際上也是調用
CRichEditCtrl.SetTargetDevice(NULL, 0); //m_nWordWrap == WrapToWindow
CRichEditCtrl.SetTargetDevice(NULL, 1); //m_nWordWrap == WrapNone
CRichEditCtrl.SetTargetDevice(NULL, 2);// m_nWordWrap == WrapToTargetDevice
6.
設置RichEdit控件不帶格式的數據粘貼
設置RichEdit控件不帶格式的數據粘貼
CRichEditCtrl.PasteSpecial(CF_TEXT);
7.
設置RichEdit控件的滾動條自動隨輸入滾動到最后一行
設置RichEdit控件的滾動條自動隨輸入滾動到最后一行
int nFirstVisible = CRichEditCtrl.GetFirstVisibleLine();
if (nFirstVisible > 0)
{
{
CRichEditCtrl.LineScroll(-nFirstVisible, 0);
}
或CRichEditCtrl.PostMessage(WM_VSCROLL, SB_BOTTOM, 0);
8.設置RichEdit控件的撤銷輸入次數(只能用在RICHED20以上)
SendMessage(EM_SETTEXTMODE, TM_MULTILEVELUNDO, 0);
SendMessage(EM_SETUNDOLIMIT, 100, 0);
TM_MULTILEVELUNDO 支持多取消(默認值),可通過EM_SETUNDOLIMIT設置最大次數
9.設置RichEdit控件的OnChange事件
EM_SETEVENTMASK 設置 ENM_CHANGE
long lMask = GetEventMask();
lMask |= ENM_CHANGE;
lMask &= ~ENM_PROTECTED;
SetEventMask(lMask);
10.設置RichEdit控件的只讀屬性
CRichEditCtrl::SetReadOnly(BOOL bReadOnly = TRUE );
通過設置PROTECTED實現選中的文本只讀,參見如下文章:
函數應用
1. 設置RichEdit控件的顯示字體
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.dwMask|=CFM_COLOR;
cf.crTextColor = RGB(255,0,0); //設置顏色
cf.dwMask|=CFM_SIZE;
cf.yHeight =200; //設置高度
cf.dwMask|=CFM_FACE;
strcpy(cf.szFaceName ,_T("隸書")); //設置字體
CRichEditCtrl.SetSelectionCharFormat(cf);
2.設置RichEdit控件的顯示字體的行間距(只能用在RICHED20以上)
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
才起作用
才起作用
1 項目符號,默認用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
才起作用,縮進,單位twips
PFM_STARTINDENT 成員 dxStartIndent
才起作用,首行縮進
才起作用,首行縮進
PFM_SPACEAFTER 成員 dySpaceAfter
才起作用,段間距
才起作用,段間距
PFM_LINESPACING 成員 dyLineSpacing
才起作用,行間距
才起作用,行間距
3.設置RichEdit控件的透明背景(只能用在RICHED20以上)
long style = ::GetWindowLong(GetSafeHwnd(), GWL_EXSTYLE);
style &= WS_EX_TRANSPARENT;
::SetWindowLong(GetSafeHwnd(), GWL_EXSTYLE, style);
或 CreateEx(),然后把WS_EX_TRANSPARENT樣式加上
4.獲取或者寫入RichEdit控件的內容
Ø
GetWindowText
GetWindowText
Ø
使用EM_GETTEXTEX
使用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);
Ø
StreamOut(主要用於RTF等格式輸出)
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
5.查找RichEdit控件中的字符串
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);
6. 以Html格式保存RichEdit控件中的內容
臨時做法可先轉為RTF格式,再通過RTF-to-HTML Converter,參考如下文章:
8.
重載OnProtected函數以得到RichEdit對應的消息,如粘貼等
重載OnProtected函數以得到RichEdit對應的消息,如粘貼等
void CRichEditorView::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;
}
聊天常用
1. 設置RichEdit控件的鏈接功能(只能用在RICHED20以上)
Ø
LoadLibrary(_T("Riched20.dll"));
LoadLibrary(_T("Riched20.dll"));
Ø
創建RichEdit2.0控件
創建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);
Ø
設置選中的文字為鏈接顯示
設置選中的文字為鏈接顯示
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);
Ø
支持鏈接的點擊響應
m_cRichEdit.SetEventMask(ENM_LINK);
支持鏈接的點擊響應
m_cRichEdit.SetEventMask(ENM_LINK);
Ø
響應鏈接的點擊EN_LINK
響應鏈接的點擊EN_LINK
BEGIN_MESSAGE_MAP(CMyRichEdit, CRichEditCtrl)
ON_NOTIFY_REFLECT(EN_LINK, OnURL)
END_MESSAGE_MAP()
......
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); //這是鏈接文字
…
}
}
Ø
自動識別鏈接
自動識別鏈接
UINT nMask = SendDlgItemMessage(IDC_RICHEDIT_MESSAGE, EM_GETEVENTMASK, 0, 0);
SendDlgItemMessage(IDC_RICHEDIT_MESSAGE, EM_SETEVENTMASK, 0, nMask | NM_LINK);
SendDlgItemMessage(IDC_RICHEDIT_MESSAGE, EM_AUTOURLDETECT, TRUE, 0);
BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
NMHDR* pNmHdr = (NMHDR *)lParam;
if(pNmHdr->idFrom == IDC_RICHEDIT_MESSAGE && pNmHdr->code == EN_LINK)
{
ENLINK *pLink = (ENLINK *)lParam;
if (pLink->msg == WM_LBUTTONDOWN)
{
SendDlgItemMessage(IDC_RICHEDIT_MESSAGE, EM_EXSETSEL, 0, (LPARAM)&(pLink->chrg));
ShellExecute(GetSafeHwnd(), "open", m_wndREMessage.GetSelText(), 0, 0, SW_SHOWNORMAL);
}
}
return CDialog::OnNotify(wParam, lParam, pResult);
}
}