RichEdit的⽤法总结(转载)richedit 常见使⽤问题
⼀.常见问题
a.可以编译,不能执⾏的
在需要在相应的对话框中加上InitInstance(void)函数中添加
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);
⼆.函数应⽤
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.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;
dw滚动文字代码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.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("f"), 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
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, p, 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);//这是链接⽂字
//后⾯是你的处理过程
......
}
}
不能显⽰图⽚等其他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);
};
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论