一.常見問題 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 = #ff0000;//設置顏色 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)>,(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 |