zoukankan      html  css  js  c++  java
  • 自定义 CRichEditCtrl 控件

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

    本代码运行效果图

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

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

    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定义:

    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.在头文件中添加:

    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.在实现文件的消息映射宏中添加如下:

    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.最后添加字体变换函数:

    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,我们的操作也是在其中完成的。

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

    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定义:

    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.在头文件中添加:

    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.在实现文件的消息映射宏中添加如下:

    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.最后添加字体变换函数:

    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()

  • 相关阅读:
    单向链表的创建、输出、插入、删除
    linux文件管理指令
    二叉树的创建与遍历(递归)
    小工具
    排序
    Project Euler Problem (1~10)
    福大软工 · 最终作业
    福大软工 · 第十二次作业
    Beta冲刺 7
    Beta冲刺 6
  • 原文地址:https://www.cnblogs.com/jinsedemaitian/p/5589164.html
Copyright © 2011-2022 走看看