richedit 常見使用問題 一.常見問題 a.能夠編譯,不能執行的php
在須要在相應的對話框中加上InitInstance(void)函數中添加html
AfxInitRichEdit();windows
b.升級默認的Riched版本(默認的有一些bug),如 可在InitInstance中添加 LoadLibrary("RICHED20.DLL") 最後注意 FreeLibraryapp
若是是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; }ide
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)this
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.net
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)>,(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); };
-----------------------------------------------------------------------
注: m_edit1表明ID爲IDC_EDIT1的CEdit控件的control類型的變量 m_richedit1表明ID爲IDC_RICHEDIT1的CRichEditCtrl控件的control類型的變量
-------------------------------------------------------------------------------- 1.設置edit只讀屬性
方法一: m_edit1.SetReadOnly(TRUE); 方法二: ::SendMessage(m_edit1.m_hWnd, EM_SETREADONLY, TRUE, 0);
-------------------------------------------------------------------------------- 2.判斷edit中光標狀態並獲得選中內容(richedit一樣適用)
int nStart, nEnd; CString strTemp;
m_edit1.GetSel(nStart, nEnd); if(nStart == nEnd) { strTemp.Format(_T("光標在%d"), nStart); AfxMessageBox(strTemp); } else { //獲得edit選中的內容 m_edit1.GetWindowText(strTemp); strTemp = strTemp.Mid(nStart) - strTemp.Mid(nEnd); AfxMessageBox(strTemp); } 注:GetSel後,若是nStart和nEnd,代表光標處於某個位置(直觀來看就是光標在閃動); 若是nStart和nEnd不相等,代表用戶在edit中選中了一段內容。
-------------------------------------------------------------------------------- 3.在edit最後添加字符串
CString str; m_edit1.SetSel(-1, -1); m_edit1.ReplaceSel(str);
-------------------------------------------------------------------------------- 4.隨輸入自動滾動到最後一行(richedit一樣適用)
方法一:(摘自msdn) // The pointer to my edit. extern CEdit* pmyEdit; int nFirstVisible = pmyEdit->GetFirstVisibleLine();
// Scroll the edit control so that the first visible line // is the first line of text. if (nFirstVisible > 0) { pmyEdit->LineScroll(-nFirstVisible, 0); } 方法二: m_richedit.PostMessage(WM_VSCROLL, SB_BOTTOM, 0);
-------------------------------------------------------------------------------- 5.如何限制edit輸入指定字符
能夠從CEdit派生一個類,添加WM_CHAR消息映射。下面一個例子實現了限定輸入16進制字符的功能。
void CMyHexEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) { if ( (nChar >= '0' && nChar <= '9') || (nChar >= 'a' && nChar <= 'f') || (nChar >= 'A' && nChar <= 'F') || nChar == VK_BACK || nChar == VK_DELETE) //msdn的virtual key { CEdit::OnChar(nChar, nRepCnt, nFlags); } }
-------------------------------------------------------------------------------- 6.如何使用richedit
添加AfxInitRichEdit(); CxxxApp::InitInstance() { AfxInitRichEdit(); ............. }
AfxInitRichEdit()功能:裝載 RichEdit 1.0 Control (RICHED32.DLL).
-------------------------------------------------------------------------------- 7.如何使用richedit2.0 or richedit3.0
使用緣由:因爲RichEdit2.0A自動爲寬字符(WideChar),因此它能夠解決中文亂碼以及一些漢字問題
方法一:(msdn上的作法,適用於用VC.NET及之後版本建立的工程) To update rich edit controls in existing Visual C++ applications to version 2.0, open the .RC file as text, change the class name of each rich edit control from "RICHEDIT" to "RichEdit20a". Then replace the call to AfxInitRichEdit with AfxInitRichEdit2. 方法二:以對話框爲例: (1) 增長一全局變量 HMODULE hMod; (2) 在CxxxApp::InitInstance()中添加一句hMod = LoadLibrary(_T("riched20.dll")); 在CxxxApp::ExitInstance()中添加一句FreeLibrary(hMod); (3) 在對話框上放一個richedit,文本方式打開.rc文件修改該richedit控件的類名"RICHEDIT" to "RichEdit20a". (4) 在對話框頭文件添加 CRichEditCtrl m_richedit; 在OnInitDialog中添加 m_richedit.SubclassDlgItem(IDC_RICHEDIT1, this);
-------------------------------------------------------------------------------- 8.改變richedit指定區域的顏色及字體
CHARFORMAT cf; ZeroMemory(&cf, sizeof(CHARFORMAT)); cf.cbSize = sizeof(CHARFORMAT); cf.dwMask = CFM_BOLD | CFM_COLOR | CFM_FACE | CFM_ITALIC | CFM_SIZE | CFM_UNDERLINE; cf.dwEffects = 0; cf.yHeight = 12*12;//文字高度 cf.crTextColor = RGB(200, 100, 255); //文字顏色 strcpy(cf.szFaceName ,_T("隸書"));//設置字體 m_richedit1.SetSel(1, 5); //設置處理區域 m_richedit1.SetSelectionCharFormat(cf);
-------------------------------------------------------------------------------- 9.設置行間距(只適用於richedit2.0)
PARAFORMAT2 pf; pf2.cbSize = sizeof(PARAFORMAT2); pf2.dwMask = PFM_LINESPACING | PFM_SPACEAFTER; pf2.dyLineSpacing = 200; pf2.bLineSpacingRule = 4; m_richedit.SetParaFormat(pf2);
-------------------------------------------------------------------------------- 10.richedit插入位圖
Q220844:How to insert a bitmap into an RTF document using the RichEdit control in Visual C++ 6.0 http://support.microsoft.com/default.aspx?scid=kb;en-us;220844 http://www.codeguru.com/Cpp/controls/richedit/article.php/c2417/ http://www.codeguru.com/Cpp/controls/richedit/article.php/c5383/
-------------------------------------------------------------------------------- 11.richedit插入gif動畫
http://www.codeproject.com/richedit/AnimatedEmoticon.asp
-------------------------------------------------------------------------------- 12.richedit嵌入ole對象
http://support.microsoft.com/kb/141549/en-us
-------------------------------------------------------------------------------- 13.使richedit選中內容只讀
http://www.codeguru.com/cpp/controls/richedit/article.php/c2401/
-------------------------------------------------------------------------------- 14.打印richedit
http://www.protext.com/MFC/RichEdit3.htm
-------------------------------------------------------------------------------- 15.richeidt用於聊天消息窗口
http://www.vckbase.com/document/viewdoc/?id=1087 http://www.codeproject.com/richedit/chatrichedit.asp http://www.codeguru.com/Cpp/controls/richedit/article.php/c2395/
-------------------------------------------------------------------------------- 16.解決richedit的EN_SETFOCUS和EN_KILLFOCUS無響應的問題
http://support.microsoft.com/kb/181664/en-us
-------------------------------------------------------------------------------- 17.richedit拼寫檢查
http://www.codeproject.com/com/AutoSpellCheck.asp
-------------------------------------------------------------------------------- 18.改變edit背景色
Q117778:How to change the background color of an MFC edit control http://support.microsoft.com/kb/117778/en-us
-------------------------------------------------------------------------------- 19.當edit控件的父窗口屬性是帶標題欄WS_CAPTION和子窗口WS_CHILD時,不能設置焦點SetFocus
Q230587:PRB: Can't Set Focus to an Edit Control When its Parent Is an Inactive Captioned Child Window
http://support.microsoft.com/kb/230587/en-us
-------------------------------------------------------------------------------- 20. 在Edit中回車時,會退出對話框
選中Edit的風格Want Return。
MSDN的解釋以下: ES_WANTRETURN Specifies that a carriage return be inserted when the user presses the ENTER key while entering text into a multiple-line edit control in a dialog box. Without this style, pressing the ENTER key has the same effect as pressing the dialog box's default pushbutton. This style has no effect on a single-line edit control.
-------------------------------------------------------------------------------- 21. 動態建立的edit沒有邊框的問題
m_edit.Create(....); m_edit.ModifyStyleEx(0, WS_EX_CLIENTEDGE, SWP_DRAWFRAME);
-------------------------------------------------------------------------------- 22. 一個能顯示RTF,ole(包括gif, wmv,excel ,ppt)的例子
http://www.codeproject.com/richedit/COleRichEditCtrl.asp
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/qsycn/archive/2009/11/10/4793461.aspx
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/abcpanpeng/archive/2010/04/21/5509680.aspx