• MFC使用rich edit若干问题


    一般性问题
    1.   
    代码编译通过了,运行后RichEdit控件不显示,在InitInstance中添加
    BOOL CWinApp::InitInstance ()
    {
    AfxInitRichEdit(); - RichEdit 1.0
    或 AfxInitRichEdit2(); - RichEdit 2.0
    }
     
    2.   
    升级默认的RichEdit版本,默认的版本有BUG,在InitInstance中添加
    BOOL CWinApp::InitInstance ()
    {
    LoadLibrary("RICHED20.DLL");
    FreeLibrary();
    }
     
    如果是CRichEditView基类的话,可用如下消息机制:
    BOOL CRichEditView::PreCreateWindow(CREATESTRUCT& cs)
    {
    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;
    return CRichEditView::PreCreateWindow(cs);
    }
     
    3.   
    在RichEdit控件的输入框中最后追加一行
    CRichEditCtrl.SetSel(-1, -1);
    CRichEditCtrl.ReplaceSel((LPCTSTR)str);
     
    4.   
    限制RichEdit控件的字数
    CRichEditCtrl.LimitText(long nChars)
     
    5.   
    设置RichEdit控件的换行切换
    如果是CRichEditView基类的话,可用如下消息机制:
    BOOL CRichEditView::OnInitialUpdate()
    {
    m_nWordWrap = WrapNone;
    WrapChanged();
    }
     
    如果是在Dialog,可使用SetTargetDevice,并在RichEdit的属性里面加上want
    return
    CRichEditCtrl.SetTargetDevice(m_dcTarget, GetPrintWidth());
     
    WrapChanged实际上也是调用
    CRichEditCtrl.SetTargetDevice(NULL, 0); //m_nWordWrap == WrapToWindow
    CRichEditCtrl.SetTargetDevice(NULL, 1); //m_nWordWrap == WrapNone
    CRichEditCtrl.SetTargetDevice(NULL, 2);// m_nWordWrap == WrapToTargetDevice
     
    6.   
    设置RichEdit控件不带格式的数据粘贴
    CRichEditCtrl.PasteSpecial(CF_TEXT);
     
    7.   
    设置RichEdit控件的滚动条自动随输入滚动到最后一行
    int nFirstVisible = CRichEditCtrl.GetFirstVisibleLine();
    if (nFirstVisible > 0)
    {
    CRichEditCtrl.LineScroll(-nFirstVisible, 0);
    }
    或CRichEditCtrl.PostMessage(WM_VSCROLL, SB_BOTTOM, 0);

    8.设置RichEdit控件的撤销输入次数(只能用在RICHED20以上)
    SendMessage(EM_SETTEXTMODE, TM_MULTILEVELUNDO, 0);
    SendMessage(EM_SETUNDOLIMIT, 100, 0);
    TM_MULTILEVELUNDO 支持多取消(默认值),可通过EM_SETUNDOLIMIT设置最大次数
     
    9.设置RichEdit控件的OnChange事件
    EM_SETEVENTMASK 设置 ENM_CHANGE
    long lMask = GetEventMask();
    lMask |= ENM_CHANGE;
    lMask &= ~ENM_PROTECTED;
    SetEventMask(lMask);
     
    10.设置RichEdit控件的只读属性
    CRichEditCtrl::SetReadOnly(BOOL bReadOnly = TRUE );
    通过设置PROTECTED实现选中的文本只读,参见如下文章:
     
     
    函数应用
    1. 设置RichEdit控件的显示字体
    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 = RGB(255,0,0); //设置颜色
    cf.dwMask|=CFM_SIZE;
    cf.yHeight =200; //设置高度
    cf.dwMask|=CFM_FACE;
    strcpy(cf.szFaceName ,_T("隶书")); //设置字体
    CRichEditCtrl.SetSelectionCharFormat(cf);
     
    2.设置RichEdit控件的显示字体的行间距(只能用在RICHED20以上)
    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
    才起作用
    1 项目符号,默认用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
    才起作用,行间距
     
    3.设置RichEdit控件的透明背景(只能用在RICHED20以上)
    long style = ::GetWindowLong(GetSafeHwnd(), GWL_EXSTYLE);
    style &= WS_EX_TRANSPARENT;
    ::SetWindowLong(GetSafeHwnd(), GWL_EXSTYLE, style);
    或 CreateEx(),然后把WS_EX_TRANSPARENT样式加上
     
    4.获取或者写入RichEdit控件的内容
    Ø        
    GetWindowText
    Ø        
    使用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);
    Ø        
    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
     
    5.查找RichEdit控件中的字符串
    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);
     
    6. 以Html格式保存RichEdit控件中的内容
    临时做法可先转为RTF格式,再通过RTF-to-HTML Converter,参考如下文章:
     
    8.   
    重载OnProtected函数以得到RichEdit对应的消息,如粘贴等
     
    void CRichEditorView::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;
    }
     
     
    聊天常用
    1. 设置RichEdit控件的链接功能(只能用在RICHED20以上)
    Ø        
    LoadLibrary(_T("Riched20.dll"));
    Ø        
    创建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);
    Ø        
    设置选中的文字为链接显示
    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);
    Ø        
    支持链接的点击响应
    m_cRichEdit.SetEventMask(ENM_LINK);
    Ø        
    响应链接的点击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); //这是链接文字
    }
    }
    Ø        
    自动识别链接
    UINT nMask = SendDlgItemMessage(IDC_RICHEDIT_MESSAGE, EM_GETEVENTMASK, 0, 0);
    SendDlgItemMessage(IDC_RICHEDIT_MESSAGE, EM_SETEVENTMASK, 0, nMask | NM_LINK);
    SendDlgItemMessage(IDC_RICHEDIT_MESSAGE, EM_AUTOURLDETECT, TRUE, 0);
    BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
    {
    NMHDR* pNmHdr = (NMHDR *)lParam;
    if(pNmHdr->idFrom == IDC_RICHEDIT_MESSAGE && pNmHdr->code == EN_LINK)
    {
    ENLINK *pLink = (ENLINK *)lParam;
    if (pLink->msg == WM_LBUTTONDOWN)
    {
    SendDlgItemMessage(IDC_RICHEDIT_MESSAGE, EM_EXSETSEL, 0, (LPARAM)&(pLink->chrg));
    ShellExecute(GetSafeHwnd(), "open", m_wndREMessage.GetSelText(), 0, 0, SW_SHOWNORMAL);
    }
    }
    return CDialog::OnNotify(wParam, lParam, pResult);
    }
  • 相关阅读:
    【docker】关于docker中挂载的解释
    【linux】centos7安装使用rz/sz命令
    【docker】 docker容器内部安装vi命令
    【docker】centOS7上部署的mysql和spring boot服务,要求,mysql的时间、java程序服务的时间和宿主机的时间完全保持一致【修改mysql时区,临时和永久】【修改spring boot配置文件时区】【修改docker启动spring boot实例程序时区】
    【docker】docker部署spring boot项目在服务器上
    【spring boot】spring boot后台时间正确,返回给前台的时间不正确,和后台差8个小时
    html页面跳转传递参数
    SpringCloud服务如何在Eureka安全优雅的下线
    使用SpringBoot Admin监控SpringCloud微服务
    对actuator的管理端点进行ip白名单限制(springBoot添加filter)
  • 原文地址:https://www.cnblogs.com/saintdingspage/p/12448191.html
Copyright © 2020-2023  润新知