我动态创建了一个CRichEditCtrl编辑框,请问高手一下,如何才能让动态创建的这个边际框背景色透明呢?
 Help!!!

解决方案 »

  1.   

    刚做完这个功能。
    从CRichEditCtrl派生一个类
    在其OnCreate中
    SetWindowLong(m_hWnd, GWL_EXSTYLE, GetWindowLong(m_hWnd,GWL_EXSTYLE)|WS_EX_TRANSPARENT); 
    边框自绘
    void CMYRichEditCtrl::OnNcPaint()
    {
    // TODO: 在此处添加消息处理程序代码
    // 不为绘图消息调用 CRichEditCtrl::OnNcPaint()
    CDC* pDC = GetDC();
    CRect rtWindow;
    GetWindowRect(rtWindow);
    int xBorder = GetSystemMetrics(SM_CXSIZEFRAME);
    int yBorder = GetSystemMetrics(SM_CYSIZEFRAME);
    ScreenToClient(rtWindow);
    CPen pen(PS_DASH, 0, RGB(0,116,255));
    CPen* pOldpen = pDC->SelectObject(&pen);
    CGdiObject* pOld = pDC->SelectStockObject(NULL_BRUSH);
    pDC->Rectangle(rtWindow);
    rtWindow.DeflateRect(xBorder-2, yBorder-2);
    pDC->Rectangle(rtWindow);
    pDC->SelectObject(pOld);
    pDC->SelectObject(pOldpen);
    ReleaseDC(pDC);
    }
      

  2.   

    或者你不派生也可以在控件Create以后
    调用其SetWindowLong也可以
    比如CRichEditCtrl wndRich;wndRich.Create(...);::SetWindowLong(wndRich.GetSafeHwnd(),GWL_EXSTYLE, ::GetWindowLong(wndRich.GetSafeHwnd(),GWL_EXSTYLE)|WS_EX_TRANSPARENT); 
      

  3.   

    感谢 jcily!
    不过我用了你的那个边框自绘,在视图窗口中只是闪烁了一下就没有了,请问这是为什么?
      

  4.   


    #if !defined(AFX_AUTORICHEDITCTRL_H__C26D1E0E_DD32_11D2_B39F_000092914562__INCLUDED_)
    #define AFX_AUTORICHEDITCTRL_H__C26D1E0E_DD32_11D2_B39F_000092914562__INCLUDED_#if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    // AutoRichEditCtrl.h : header file
    ///////////////////////////////////////////////////////////////////////////////
    // CAutoRichEditCtrl windowclass CAutoRichEditCtrl : public CRichEditCtrl
    {
    // Construction
    public:
    CAutoRichEditCtrl();// Attributes
    public:// Operations
    public:// Overrides
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CAutoRichEditCtrl)
    //}}AFX_VIRTUAL// Implementation
    public:
    long GetSelectionFontSize();
    CString GetSelectionFontName();
    CStringArray m_saFontList;
    void GetSystemFonts(CStringArray &saFontList);
    void SetFontSize(int nPointSize);
    void SetFontName(CString sFontName);
    void SelectColor();
    bool ParagraphIsBulleted();
    void SetParagraphBulleted();

    PARAFORMAT GetParagraphFormat();

    bool ParagraphIsRight();
    bool ParagraphIsLeft();
    bool ParagraphIsCentered();

    void SetParagraphRight();
    void SetParagraphLeft();
    void SetParagraphCenter();

    CHARFORMAT GetCharFormat(DWORD dwMask = CFM_COLOR | CFM_FACE | CFM_SIZE | CFM_BOLD | CFM_ITALIC | CFM_UNDERLINE);

    bool SelectionIsBold();
    bool SelectionIsItalic();
    bool SelectionIsUnderlined(); void SetSelectionBold();
    void SetSelectionItalic();
    void SetSelectionUnderlined(); void SetRTF(CString sRTF);
    CString GetRTF();
    virtual ~CAutoRichEditCtrl(); // Generated message map functions
    protected:
    afx_msg void OnRButtonDown(UINT nFlags, CPoint point); DECLARE_MESSAGE_MAP()
    private:
    void SetCharStyle(int MASK, int STYLE, int nStart, int nEnd);
    static DWORD CALLBACK CBStreamIn(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb);
    static DWORD CALLBACK CBStreamOut(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG* pcb);
    static BOOL CALLBACK CBEnumFonts(LPLOGFONT lplf, LPTEXTMETRIC lptm, DWORD dwType, LPARAM lpData);
    public:
    afx_msg void OnCopy() { Copy(); }
    afx_msg void OnCut() { Cut(); }
    afx_msg void OnPaste() { Paste(); }
    afx_msg void OnSelectall() { SetSel(0, -1); }
    afx_msg void OnUndo() { Undo(); }
    afx_msg void OnClear() { Clear(); }
    afx_msg void OnEnRequestresize(NMHDR *pNMHDR, LRESULT *pResult);
    afx_msg HBRUSH CtlColor(CDC* /*pDC*/, UINT /*nCtlColor*/);
    afx_msg BOOL OnEraseBkgnd(CDC* pDC);
    afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
    afx_msg void OnNcPaint();
    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
    afx_msg void OnEnUpdate();
    };///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}}
    // Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_AUTORICHEDITCTRL_H__C26D1E0E_DD32_11D2_B39F_000092914562__INCLUDED_)
      

  5.   


    // AutoRichEditCtrl.cpp : implementation file
    //#include "stdafx.h"
    //#include "RichEd.h"
    #include "AutoRichEditCtrl.h"
    #include ".\autoricheditctrl.h"#ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif#define ID_RICH_UNDO                    101
    #define ID_RICH_CUT                     102
    #define ID_RICH_COPY                    103
    #define ID_RICH_PASTE                   104
    #define ID_RICH_CLEAR                   105
    #define ID_RICH_SELECTALL               106
    //#define ID_RICH_SETFONT                 107/////////////////////////////////////////////////////////////////////////////
    // CAutoRichEditCtrlCAutoRichEditCtrl::CAutoRichEditCtrl()
    {
    }CAutoRichEditCtrl::~CAutoRichEditCtrl()
    {
    }
    BEGIN_MESSAGE_MAP(CAutoRichEditCtrl, CRichEditCtrl)
    //{{AFX_MSG_MAP(CAutoRichEditCtrl)
    ON_WM_RBUTTONDOWN()
    ON_COMMAND(ID_RICH_COPY, OnCopy)
    ON_COMMAND(ID_RICH_CUT, OnCut)
    ON_COMMAND(ID_RICH_PASTE, OnPaste)
    ON_COMMAND(ID_RICH_SELECTALL, OnSelectall)
    ON_COMMAND(ID_RICH_UNDO, OnUndo)
    ON_COMMAND(ID_RICH_CLEAR, OnClear)
    //}}AFX_MSG_MAP
    ON_NOTIFY_REFLECT(EN_REQUESTRESIZE, OnEnRequestresize)
    ON_WM_CTLCOLOR_REFLECT()
    ON_WM_ERASEBKGND()
    ON_WM_CTLCOLOR()
    ON_WM_NCPAINT()
    ON_WM_CREATE()
    ON_CONTROL_REFLECT(EN_UPDATE, OnEnUpdate)
    END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////
    // CAutoRichEditCtrl message handlersCString CAutoRichEditCtrl::GetRTF()
    {
    // Return the RTF string of the text in the control.

    // Stream out here.
    EDITSTREAM es;
    es.dwError = 0;
    es.pfnCallback = CBStreamOut; // Set the callback CString sRTF = ""; es.dwCookie = (DWORD) &sRTF; // so sRTF receives the string

    StreamOut(SF_RTF, es); // Call CRichEditCtrl::StreamOut to get the string.
    /// return sRTF;}void CAutoRichEditCtrl::SetRTF(CString sRTF)
    {
    // Put the RTF string sRTF into the rich edit control. // Read the text in
    EDITSTREAM es;
    es.dwError = 0;
    es.pfnCallback = CBStreamIn;
    es.dwCookie = (DWORD) &sRTF;
    StreamIn(SF_RTF, es); // Do it.

    }/*
    Callback function to stream an RTF string into the rich edit control.
    */
    DWORD CALLBACK CAutoRichEditCtrl::CBStreamIn(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
    {
    // We insert the rich text here./*
    This function taken from CodeGuru.com
    http://www.codeguru.com/richedit/rtf_string_streamin.shtml
    Zafir Anjum
    */ CString *pstr = (CString *) dwCookie; if (pstr->GetLength() < cb)
    {
    *pcb = pstr->GetLength();
    memcpy(pbBuff, (LPCSTR) *pstr, *pcb);
    pstr->Empty();
    }
    else
    {
    *pcb = cb;
    memcpy(pbBuff, (LPCSTR) *pstr, *pcb);
    *pstr = pstr->Right(pstr->GetLength() - cb);
    }
    /// return 0;
    }/*
    Callback function to stream the RTF string out of the rich edit control.
    */
    DWORD CALLBACK CAutoRichEditCtrl::CBStreamOut(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
    {
    // Address of our string var is in psEntry
    CString *psEntry = (CString*) dwCookie;
    CString tmpEntry = "";
    tmpEntry = (CString) pbBuff; // And write it!!!
    *psEntry += tmpEntry.Left(cb); return 0;
    }bool CAutoRichEditCtrl::SelectionIsBold()
    {
    CHARFORMAT cf = GetCharFormat();

    if (cf.dwEffects & CFM_BOLD)
    return true;
    else
    return false;
    }bool CAutoRichEditCtrl::SelectionIsItalic()
    {
    CHARFORMAT cf = GetCharFormat();

    if (cf.dwEffects & CFM_ITALIC)
    return true;
    else
    return false;
    }bool CAutoRichEditCtrl::SelectionIsUnderlined()
    {
    CHARFORMAT cf = GetCharFormat();

    if (cf.dwEffects & CFM_UNDERLINE)
    return true;
    else
    return false;
    }CHARFORMAT CAutoRichEditCtrl::GetCharFormat(DWORD dwMask)
    {
    CHARFORMAT cf;
    cf.cbSize = sizeof(CHARFORMAT); cf.dwMask = dwMask; GetSelectionCharFormat(cf); return cf;
    }void CAutoRichEditCtrl::SetCharStyle(int MASK, int STYLE, int nStart, int nEnd)
    {
    CHARFORMAT cf;
    cf.cbSize = sizeof(CHARFORMAT);
    //cf.dwMask = MASK;

    GetSelectionCharFormat(cf);

    if (cf.dwMask & MASK) // selection is all the same
    {
    cf.dwEffects ^= STYLE; 
    }
    else
    {
    cf.dwEffects |= STYLE;
    }

    cf.dwMask = MASK; SetSelectionCharFormat(cf);}void CAutoRichEditCtrl::SetSelectionBold()
    {
    long start=0, end=0;
    GetSel(start, end); // Get the current selection SetCharStyle(CFM_BOLD, CFE_BOLD, start, end); // Make it bold
    }void CAutoRichEditCtrl::SetSelectionItalic()
    {
    long start=0, end=0;
    GetSel(start, end); SetCharStyle(CFM_ITALIC, CFE_ITALIC, start, end);
    }void CAutoRichEditCtrl::SetSelectionUnderlined()
    {
    long start=0, end=0;
    GetSel(start, end); SetCharStyle(CFM_UNDERLINE, CFE_UNDERLINE, start, end);
    }void CAutoRichEditCtrl::SetParagraphCenter()
    {
    PARAFORMAT paraFormat;    
    paraFormat.cbSize = sizeof(PARAFORMAT);
    paraFormat.dwMask = PFM_ALIGNMENT;    
    paraFormat.wAlignment = PFA_CENTER;

    SetParaFormat(paraFormat); // Set the paragraph.
    }void CAutoRichEditCtrl::SetParagraphLeft()
    {
    PARAFORMAT paraFormat;
    paraFormat.cbSize = sizeof(PARAFORMAT);
    paraFormat.dwMask = PFM_ALIGNMENT;    
    paraFormat.wAlignment = PFA_LEFT;

    SetParaFormat(paraFormat);
    }void CAutoRichEditCtrl::SetParagraphRight()
    {
    PARAFORMAT paraFormat;
    paraFormat.cbSize = sizeof(PARAFORMAT);
    paraFormat.dwMask = PFM_ALIGNMENT;    
    paraFormat.wAlignment = PFA_RIGHT;

    SetParaFormat(paraFormat);
    }bool CAutoRichEditCtrl::ParagraphIsCentered()
    {
    PARAFORMAT pf = GetParagraphFormat(); if (pf.wAlignment == PFA_CENTER)
    return true;
    else
    return false;
    }bool CAutoRichEditCtrl::ParagraphIsLeft()
    {
    PARAFORMAT pf = GetParagraphFormat(); if (pf.wAlignment == PFA_LEFT)
    return true;
    else
    return false;
    }bool CAutoRichEditCtrl::ParagraphIsRight()
    {
    PARAFORMAT pf = GetParagraphFormat(); if (pf.wAlignment == PFA_RIGHT)
    return true;
    else
    return false;
    }PARAFORMAT CAutoRichEditCtrl::GetParagraphFormat()
    {
    PARAFORMAT pf;
    pf.cbSize = sizeof(PARAFORMAT); pf.dwMask = PFM_ALIGNMENT | PFM_NUMBERING;     GetParaFormat(pf); return pf;
    }void CAutoRichEditCtrl::SetParagraphBulleted()
    {
    PARAFORMAT paraformat = GetParagraphFormat(); if ( (paraformat.dwMask & PFM_NUMBERING) && (paraformat.wNumbering == PFN_BULLET) )
    {
    paraformat.wNumbering = 0;
    paraformat.dxOffset = 0;
    paraformat.dxStartIndent = 0;
    paraformat.dwMask = PFM_NUMBERING | PFM_STARTINDENT | PFM_OFFSET;
    }
    else
    {
    paraformat.wNumbering = PFN_BULLET;
    paraformat.dwMask = PFM_NUMBERING;
    if (paraformat.dxOffset == 0)
    {
    paraformat.dxOffset = 4;
    paraformat.dwMask = PFM_NUMBERING | PFM_STARTINDENT | PFM_OFFSET;
    }
    }

    SetParaFormat(paraformat);}bool CAutoRichEditCtrl::ParagraphIsBulleted()
    {
    PARAFORMAT pf = GetParagraphFormat(); if (pf.wNumbering == PFN_BULLET)
    return true;
    else
    return false;
    }void CAutoRichEditCtrl::SelectColor()
    {
    CColorDialog dlg; CHARFORMAT cf = GetCharFormat(); if (cf.dwEffects & CFE_AUTOCOLOR) cf.dwEffects -= CFE_AUTOCOLOR; // Get a color from the common color dialog.
    if( dlg.DoModal() == IDOK )
    {
    cf.crTextColor = dlg.GetColor();
    } cf.dwMask = CFM_COLOR; SetSelectionCharFormat(cf);
    }
      

  6.   

    void CAutoRichEditCtrl::SetFontName(CString sFontName)
    {
    CHARFORMAT cf = GetCharFormat(); // Set the font name.
    for (int i = 0; i <= sFontName.GetLength()-1; i++)
    cf.szFaceName[i] = sFontName[i];
    cf.dwMask = CFM_FACE; SetSelectionCharFormat(cf);
    }void CAutoRichEditCtrl::SetFontSize(int nPointSize)
    {
    CHARFORMAT cf = GetCharFormat(); nPointSize *= 20; // convert from to twips
    cf.yHeight = nPointSize;

    cf.dwMask = CFM_SIZE; SetSelectionCharFormat(cf);
    }void CAutoRichEditCtrl::GetSystemFonts(CStringArray &saFontList)
    {
    CDC *pDC = GetDC (); EnumFonts (pDC->GetSafeHdc(),NULL,(FONTENUMPROC) CBEnumFonts,(LPARAM)&saFontList);//Enumerate}BOOL CALLBACK CAutoRichEditCtrl::CBEnumFonts(LPLOGFONT lplf, LPTEXTMETRIC lptm, DWORD dwType, LPARAM lpData)
    {
    // This function was written with the help of CCustComboBox, by Girish Bharadwaj.
    // Available from Codeguru. if (dwType == TRUETYPE_FONTTYPE) 
    {
    ((CStringArray *) lpData)->Add( lplf->lfFaceName );
    } return true;
    }CString CAutoRichEditCtrl::GetSelectionFontName()
    {
    CHARFORMAT cf = GetCharFormat(); CString sName = cf.szFaceName; return sName;
    }long CAutoRichEditCtrl::GetSelectionFontSize()
    {
    CHARFORMAT cf = GetCharFormat();
    double fScaleTP = 1440.0/GetDeviceCaps(GetDC()->GetSafeHdc(), LOGPIXELSY);
    long nSize = cf.yHeight/fScaleTP; return nSize;
    }void CAutoRichEditCtrl::OnRButtonDown( UINT nFlags, CPoint point )
    {
    //设置为焦点
    SetFocus();
    //创建一个弹出式菜单
    CMenu popmenu;
    popmenu.CreatePopupMenu();
    //添加菜单项目
    popmenu.AppendMenu(0, ID_RICH_UNDO, _T("撤销(&U)"));
    popmenu.AppendMenu(0, MF_SEPARATOR);
    popmenu.AppendMenu(0, ID_RICH_CUT, _T("剪切(&T)"));
    popmenu.AppendMenu(0, ID_RICH_COPY, _T("复制(&C)"));
    popmenu.AppendMenu(0, ID_RICH_PASTE, _T("粘贴(&P)"));
    popmenu.AppendMenu(0, ID_RICH_CLEAR, _T("删除(&L)"));
    popmenu.AppendMenu(0, MF_SEPARATOR);
    popmenu.AppendMenu(0, ID_RICH_SELECTALL, _T("全选(&A)"));
    //popmenu.AppendMenu(0, MF_SEPARATOR);
    //popmenu.AppendMenu(0, ID_RICH_SETFONT, "Select &Font"); //初始化菜单项
    UINT nUndo=(CanUndo() ? 0 : MF_GRAYED );
    popmenu.EnableMenuItem(ID_RICH_UNDO, MF_BYCOMMAND|nUndo); UINT nSel=((GetSelectionType()!=SEL_EMPTY) ? 0 : MF_GRAYED) ;
    popmenu.EnableMenuItem(ID_RICH_CUT, MF_BYCOMMAND|nSel);
    popmenu.EnableMenuItem(ID_RICH_COPY, MF_BYCOMMAND|nSel);
    popmenu.EnableMenuItem(ID_RICH_CLEAR, MF_BYCOMMAND|nSel); UINT nPaste=(CanPaste() ? 0 : MF_GRAYED) ;
    popmenu.EnableMenuItem(ID_RICH_PASTE, MF_BYCOMMAND|nPaste); //显示菜单
    CPoint pt;
    GetCursorPos(&pt);
    popmenu.TrackPopupMenu(TPM_RIGHTBUTTON, pt.x, pt.y, this);
    popmenu.DestroyMenu();
    CRichEditCtrl::OnRButtonDown(nFlags, point);
    }
    HBRUSH CAutoRichEditCtrl::CtlColor(CDC* pDC, UINT /*nCtlColor*/)
    {
    // TODO:  在此更改 DC 的任何属性 pDC->SetBkMode(TRANSPARENT);
    return NULL;
    }BOOL CAutoRichEditCtrl::OnEraseBkgnd(CDC* pDC)
    {
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    //CRect rt;
    //GetClientRect(rt);
    //pDC->FillSolidRect(rt,RGB(0,255,0));
    //pDC->MoveTo(rt.TopLeft());
    //pDC->LineTo(rt.BottomRight());
    return CRichEditCtrl::OnEraseBkgnd(pDC);
    return FALSE;
    }HBRUSH CAutoRichEditCtrl::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
    {
    HBRUSH hbr = CRichEditCtrl::OnCtlColor(pDC, pWnd, nCtlColor); // TODO:  在此更改 DC 的任何属性 // TODO:  如果默认的不是所需画笔,则返回另一个画笔
    return hbr;
    }void CAutoRichEditCtrl::OnNcPaint()
    {
    // TODO: 在此处添加消息处理程序代码
    // 不为绘图消息调用 CRichEditCtrl::OnNcPaint()
    CDC* pDC = GetDC();
    CRect rtWindow;
    GetWindowRect(rtWindow);
    int xBorder = GetSystemMetrics(SM_CXSIZEFRAME);
    int yBorder = GetSystemMetrics(SM_CYSIZEFRAME);
    ScreenToClient(rtWindow);
    CPen pen(PS_DASH, 0, RGB(0,116,255));
    CPen* pOldpen = pDC->SelectObject(&pen);
    CGdiObject* pOld = pDC->SelectStockObject(NULL_BRUSH);
    pDC->Rectangle(rtWindow);
    rtWindow.DeflateRect(xBorder-2, yBorder-2);
    pDC->Rectangle(rtWindow);
    pDC->SelectObject(pOld);
    pDC->SelectObject(pOldpen);
    ReleaseDC(pDC);
    }int CAutoRichEditCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
    if (CRichEditCtrl::OnCreate(lpCreateStruct) == -1)
    return -1; SetWindowLong(m_hWnd, GWL_EXSTYLE, GetWindowLong(m_hWnd,GWL_EXSTYLE)|WS_EX_TRANSPARENT);  return 0;
    }void CAutoRichEditCtrl::OnEnUpdate()
    {
    // TODO:  如果该控件是 RICHEDIT 控件,则它将不会
    // 发送该通知,除非重写 CRichEditCtrl::OnInitDialog()
    // 函数,将 EM_SETEVENTMASK 消息发送到控件,
    // 同时将 ENM_UPDATE 标志“或”运算到 lParam 掩码中。 // TODO:  在此添加控件通知处理程序代码
    }// 根据文本改变编辑框大小
    void CAutoRichEditCtrl::OnEnRequestresize(NMHDR *pNMHDR, LRESULT *pResult)
    {
    REQRESIZE *pReqResize = reinterpret_cast<REQRESIZE *>(pNMHDR);
    // TODO:  控件将不发送该通知,除非您重写
    // CRichEditCtrl::OnInitDialog() 函数以发送 EM_SETEVENTMASK 消息
    // 到具有 ENM_REQUESTRESIZE 标志“或”运算到 lParam 掩码中的控件。 // 根据文本改变编辑框大小
    CRect rtEditBox;
    GetWindowRect(rtEditBox);
    rtEditBox.NormalizeRect();
    RECT rtNew = pReqResize->rc;
    GetParent()->ScreenToClient( rtEditBox );
    rtEditBox.NormalizeRect();
    if (rtEditBox.Height() < (rtNew.bottom +2*GetSystemMetrics(SM_CYSIZEFRAME) - rtNew.top) )
    rtEditBox.bottom = rtNew.bottom + 2*GetSystemMetrics(SM_CYSIZEFRAME);
    MoveWindow(rtEditBox); *pResult = 1;
    }