自定义 CRichEditCtrl 控件


在VC中提供了两种很方便的编辑控件(CEdit 和CRichEditCtrl),一般来说这两种控件已经满足了我们大部分的需要,不过只有CEdit控件能响应我们鼠标右键消息,通过右键我们很容易的操作我们的编辑,而在CRichEditCtrl控件中我们不能得到这样的操作,同时CRichEditCtrl是能够包含各种格式的内容,就好像Word一样能够写入各种不同的字体,不过CRichEditCtrl没有给我们提供这样的要求,今天我的目的也就是给他添加这样的扩展操作。

本代码运行效果图

一. 首先我们要从CRichEditCtrl类派生一个我们自己的类CMyRichEdit,我们的操作也是在其中完成的。

二. 然后我们添加鼠标右键消息,在其中添加代码如下:

view source
print?
01.//设置为焦点
02.SetFocus();
03.
04.//创建一个弹出式菜单
05.CMenu popmenu;
06.popmenu.CreatePopupMenu();
07.
08.//添加菜单项目
09.
10.popmenu.AppendMenu(0, ID_RICH_UNDO, "&Undo");
11.popmenu.AppendMenu(0, MF_SEPARATOR);
12.popmenu.AppendMenu(0, ID_RICH_CUT, "&Cut");
13.popmenu.AppendMenu(0, ID_RICH_COPY, "C&opy");
14.popmenu.AppendMenu(0, ID_RICH_PASTE, "&Paste");
15.popmenu.AppendMenu(0, ID_RICH_CLEAR, "C&lear");
16.popmenu.AppendMenu(0, MF_SEPARATOR);
17.popmenu.AppendMenu(0, ID_RICH_SELECTALL, "Select &All");
18.popmenu.AppendMenu(0, MF_SEPARATOR);
19.popmenu.AppendMenu(0, ID_RICH_SETFONT, "Select &Font");
20.
21.//初始化菜单项
22.UINT nUndo=(CanUndo() ? 0 : MF_GRAYED );
23.popmenu.EnableMenuItem(ID_RICH_UNDO, MF_BYCOMMAND|nUndo);
24.UINT nSel=((GetSelectionType()!=SEL_EMPTY) ? 0 : MF_GRAYED) ;
25.popmenu.EnableMenuItem(ID_RICH_CUT, MF_BYCOMMAND|nSel);
26.popmenu.EnableMenuItem(ID_RICH_COPY, MF_BYCOMMAND|nSel);
27.popmenu.EnableMenuItem(ID_RICH_CLEAR, MF_BYCOMMAND|nSel);
28.UINT nPaste=(CanPaste() ? 0 : MF_GRAYED) ;
29.popmenu.EnableMenuItem(ID_RICH_PASTE, MF_BYCOMMAND|nPaste);
30.
31.//显示菜单
32.CPoint pt;
33.GetCursorPos(&pt);
34.popmenu.TrackPopupMenu(TPM_RIGHTBUTTON, pt.x, pt.y, this);
35.popmenu.DestroyMenu();

三. 然后在.h文件中加入如下的ID定义:

view source
print?
1.#define ID_RICH_UNDO 101
2.#define ID_RICH_CUT 102
3.#define ID_RICH_COPY 103
4.#define ID_RICH_PASTE 104
5.#define ID_RICH_CLEAR 105
6.#define ID_RICH_SELECTALL 106
7.#define ID_RICH_SETFONT 107

不过这些值还可以通过VC++编译器中的菜单View->Resource Symbols进行添加。 四. 添加消息相应操作,由于这些ID是我们自己定义的,所以我们只能手动添加:

1.在头文件中添加:

view source
print?
1.afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
2.afx_msg void OnCopy() { Copy(); }
3.afx_msg void OnCut() { Cut(); }
4.afx_msg void OnPaste() { Paste(); }
5.afx_msg void OnSelectall() { SetSel(0, -1); }
6.afx_msg void OnUndo() { Undo(); }
7.afx_msg void OnClear() { Clear(); }
8.afx_msg void OnSelectfont();//改变字体

2.在实现文件的消息映射宏中添加如下:

view source
print?
1.ON_COMMAND(ID_RICH_COPY, OnCopy)
2.ON_COMMAND(ID_RICH_CUT, OnCut)
3.ON_COMMAND(ID_RICH_PASTE, OnPaste)
4.ON_COMMAND(ID_RICH_SELECTALL, OnSelectall)
5.ON_COMMAND(ID_RICH_UNDO, OnUndo)
6.ON_COMMAND(ID_RICH_CLEAR, OnClear)
7.ON_COMMAND(ID_RICH_SETFONT, OnSelectfont)

3.最后添加字体变换函数:

view source
print?
01.CHARFORMAT cf;
02.LOGFONT lf;
03.memset(&cf, 0, sizeof(CHARFORMAT));
04.memset(&lf, 0, sizeof(LOGFONT));
05.
06.//判断是否选择了内容
07.BOOL bSelect = (GetSelectionType() != SEL_EMPTY) ? TRUE : FALSE;
08.if (bSelect)
09.{
10.GetSelectionCharFormat(cf);
11.}
12.else
13.{
14.GetDefaultCharFormat(cf);
15.}
16.
17.//得到相关字体属性
18.BOOL bIsBold = cf.dwEffects & CFE_BOLD;
19.BOOL bIsItalic = cf.dwEffects & CFE_ITALIC;
20.BOOL bIsUnderline = cf.dwEffects & CFE_UNDERLINE;
21.BOOL bIsStrickout = cf.dwEffects & CFE_STRIKEOUT;
22.
23.//设置属性
24.lf.lfCharSet = cf.bCharSet;
25.lf.lfHeight = cf.yHeight/15;
26.lf.lfPitchAndFamily = cf.bPitchAndFamily;
27.lf.lfItalic = bIsItalic;
28.lf.lfWeight = (bIsBold ? FW_BOLD : FW_NORMAL);
29.lf.lfUnderline = bIsUnderline;
30.lf.lfStrikeOut = bIsStrickout;
31.sprintf(lf.lfFaceName, cf.szFaceName);
32.
33.
34.CFontDialog dlg(&lf);
35.dlg.m_cf.rgbColors = cf.crTextColor;
36.if (dlg.DoModal() == IDOK)
37.{
38.dlg.GetCharFormat(cf);//获得所选字体的属性
39.if (bSelect)
40.SetSelectionCharFormat(cf); //为选定的内容设定所选字体
41.else
42.SetWordCharFormat(cf); //为将要输入的内容设定字体
43.}

然后在我们需要的地方添加头文件和实现文件,将定义的CRichEditCtrl对象改为用CMyRichEdit来定义,就可以了。

还有提醒的就是不要忘记在InitInstance()中调用AfxInitRichEdit()

在VC中提供了两种很方便的编辑控件(CEdit 和CRichEditCtrl),一般来说这两种控件已经满足了我们大部分的需要,不过只有CEdit控件能响应我们鼠标右键消息,通过右键我们很容易的操作我们的编辑,而在CRichEditCtrl控件中我们不能得到这样的操作,同时CRichEditCtrl是能够包含各种格式的内容,就好像Word一样能够写入各种不同的字体,不过CRichEditCtrl没有给我们提供这样的要求,今天我的目的也就是给他添加这样的扩展操作。

本代码运行效果图

一. 首先我们要从CRichEditCtrl类派生一个我们自己的类CMyRichEdit,我们的操作也是在其中完成的。

二. 然后我们添加鼠标右键消息,在其中添加代码如下:

view source
print?
01.//设置为焦点
02.SetFocus();
03.
04.//创建一个弹出式菜单
05.CMenu popmenu;
06.popmenu.CreatePopupMenu();
07.
08.//添加菜单项目
09.
10.popmenu.AppendMenu(0, ID_RICH_UNDO, "&Undo");
11.popmenu.AppendMenu(0, MF_SEPARATOR);
12.popmenu.AppendMenu(0, ID_RICH_CUT, "&Cut");
13.popmenu.AppendMenu(0, ID_RICH_COPY, "C&opy");
14.popmenu.AppendMenu(0, ID_RICH_PASTE, "&Paste");
15.popmenu.AppendMenu(0, ID_RICH_CLEAR, "C&lear");
16.popmenu.AppendMenu(0, MF_SEPARATOR);
17.popmenu.AppendMenu(0, ID_RICH_SELECTALL, "Select &All");
18.popmenu.AppendMenu(0, MF_SEPARATOR);
19.popmenu.AppendMenu(0, ID_RICH_SETFONT, "Select &Font");
20.
21.//初始化菜单项
22.UINT nUndo=(CanUndo() ? 0 : MF_GRAYED );
23.popmenu.EnableMenuItem(ID_RICH_UNDO, MF_BYCOMMAND|nUndo);
24.UINT nSel=((GetSelectionType()!=SEL_EMPTY) ? 0 : MF_GRAYED) ;
25.popmenu.EnableMenuItem(ID_RICH_CUT, MF_BYCOMMAND|nSel);
26.popmenu.EnableMenuItem(ID_RICH_COPY, MF_BYCOMMAND|nSel);
27.popmenu.EnableMenuItem(ID_RICH_CLEAR, MF_BYCOMMAND|nSel);
28.UINT nPaste=(CanPaste() ? 0 : MF_GRAYED) ;
29.popmenu.EnableMenuItem(ID_RICH_PASTE, MF_BYCOMMAND|nPaste);
30.
31.//显示菜单
32.CPoint pt;
33.GetCursorPos(&pt);
34.popmenu.TrackPopupMenu(TPM_RIGHTBUTTON, pt.x, pt.y, this);
35.popmenu.DestroyMenu();

三. 然后在.h文件中加入如下的ID定义:

view source
print?
1.#define ID_RICH_UNDO 101
2.#define ID_RICH_CUT 102
3.#define ID_RICH_COPY 103
4.#define ID_RICH_PASTE 104
5.#define ID_RICH_CLEAR 105
6.#define ID_RICH_SELECTALL 106
7.#define ID_RICH_SETFONT 107

不过这些值还可以通过VC++编译器中的菜单View->Resource Symbols进行添加。 四. 添加消息相应操作,由于这些ID是我们自己定义的,所以我们只能手动添加:

1.在头文件中添加:

view source
print?
1.afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
2.afx_msg void OnCopy() { Copy(); }
3.afx_msg void OnCut() { Cut(); }
4.afx_msg void OnPaste() { Paste(); }
5.afx_msg void OnSelectall() { SetSel(0, -1); }
6.afx_msg void OnUndo() { Undo(); }
7.afx_msg void OnClear() { Clear(); }
8.afx_msg void OnSelectfont();//改变字体

2.在实现文件的消息映射宏中添加如下:

view source
print?
1.ON_COMMAND(ID_RICH_COPY, OnCopy)
2.ON_COMMAND(ID_RICH_CUT, OnCut)
3.ON_COMMAND(ID_RICH_PASTE, OnPaste)
4.ON_COMMAND(ID_RICH_SELECTALL, OnSelectall)
5.ON_COMMAND(ID_RICH_UNDO, OnUndo)
6.ON_COMMAND(ID_RICH_CLEAR, OnClear)
7.ON_COMMAND(ID_RICH_SETFONT, OnSelectfont)

3.最后添加字体变换函数:

view source
print?
01.CHARFORMAT cf;
02.LOGFONT lf;
03.memset(&cf, 0, sizeof(CHARFORMAT));
04.memset(&lf, 0, sizeof(LOGFONT));
05.
06.//判断是否选择了内容
07.BOOL bSelect = (GetSelectionType() != SEL_EMPTY) ? TRUE : FALSE;
08.if (bSelect)
09.{
10.GetSelectionCharFormat(cf);
11.}
12.else
13.{
14.GetDefaultCharFormat(cf);
15.}
16.
17.//得到相关字体属性
18.BOOL bIsBold = cf.dwEffects & CFE_BOLD;
19.BOOL bIsItalic = cf.dwEffects & CFE_ITALIC;
20.BOOL bIsUnderline = cf.dwEffects & CFE_UNDERLINE;
21.BOOL bIsStrickout = cf.dwEffects & CFE_STRIKEOUT;
22.
23.//设置属性
24.lf.lfCharSet = cf.bCharSet;
25.lf.lfHeight = cf.yHeight/15;
26.lf.lfPitchAndFamily = cf.bPitchAndFamily;
27.lf.lfItalic = bIsItalic;
28.lf.lfWeight = (bIsBold ? FW_BOLD : FW_NORMAL);
29.lf.lfUnderline = bIsUnderline;
30.lf.lfStrikeOut = bIsStrickout;
31.sprintf(lf.lfFaceName, cf.szFaceName);
32.
33.
34.CFontDialog dlg(&lf);
35.dlg.m_cf.rgbColors = cf.crTextColor;
36.if (dlg.DoModal() == IDOK)
37.{
38.dlg.GetCharFormat(cf);//获得所选字体的属性
39.if (bSelect)
40.SetSelectionCharFormat(cf); //为选定的内容设定所选字体
41.else
42.SetWordCharFormat(cf); //为将要输入的内容设定字体
43.}

然后在我们需要的地方添加头文件和实现文件,将定义的CRichEditCtrl对象改为用CMyRichEdit来定义,就可以了。

还有提醒的就是不要忘记在InitInstance()中调用AfxInitRichEdit()

优质内容筛选与推荐>>
1、dos 批量ren 无后缀名的文件
2、web前端(1)——了解什么是前端,以及与后端的关系
3、Oracle 四种列转行的方法
4、查看Linux进程状态
5、常见电脑故障维修-硬盘篇


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号