• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            鐵觀音

            C++編程寶典

               ::  ::  ::  ::  :: 管理 ::
              1 隨筆 :: 19 文章 :: 0 評論 :: 0 Trackbacks

            CRichEditCtrl 超文本編輯(MSN/QQ常用控件)

            owg 轉自-vcmute (2005-9-9 13:48:00)

            //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

            一.常見問題

            a.可以編譯,不能執行的

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

            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有

            1 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)&gt,(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
            ----------------------
            比我想象中還要花時間,所以最后潦草了點,見諒


            posted on 2006-08-20 11:20 鐵觀音 閱讀(327) 評論(0)  編輯 收藏 引用 所屬分類: VC界面控件類
            av色综合久久天堂av色综合在| 亚洲国产成人久久综合一| 国产成人久久激情91| 久久精品国产2020| 中文成人久久久久影院免费观看| 久久精品女人天堂AV麻| 四虎国产永久免费久久| 热99re久久国超精品首页| 久久综合久久综合九色| 国产亚洲精品自在久久| 久久er热视频在这里精品| 伊人久久大香线蕉精品| 99久久精品免费观看国产| 一本久久a久久精品综合夜夜| 色综合色天天久久婷婷基地| 成人精品一区二区久久| 午夜精品久久久久9999高清| 久久精品国产亚洲AV忘忧草18 | 久久香蕉一级毛片| 久久se精品一区二区| 精品久久国产一区二区三区香蕉| 亚洲&#228;v永久无码精品天堂久久 | 久久只这里是精品66| 久久久久青草线蕉综合超碰| 久久久久亚洲AV成人片| 成人午夜精品久久久久久久小说| 三级片免费观看久久| 久久亚洲日韩精品一区二区三区| 国产精品美女久久久| 久久久噜噜噜久久| 日产精品久久久一区二区| 国内精品久久久久久久涩爱| 欧美日韩精品久久久久| 久久精品九九亚洲精品天堂| 日韩久久久久中文字幕人妻| 99久久精品日本一区二区免费| 久久久精品人妻无码专区不卡| 久久亚洲私人国产精品vA| 久久亚洲2019中文字幕| 精品久久久久久国产91| 久久人人爽人人爽人人av东京热 |