帖子收藏:http://bbs.csdn.net/topics/250014374
原帖方法会产生贴图遮挡文字的Bug,现修订贴图DC为CRichEditView的DC,圆满解决此问题。修正帖全文如下:
由于CRichEditView内置了一个CRichEditCtrl控件,并且重载OnPaint()来绘制背景图片,就会花脸。在OnSize和OnEraseBkgnd中贴图效果都不理想。
偶然经网上关于透明窗口绘制方法的启发,对窗口风格进行重设,顺利解决了CRichEditView 加入背景图片的问题。
基本原理为:
1. 设置CRichEditCtrl控件的窗口属性为透明;
2. 重载CRichEditView::OnEraseBkgnd(),手动填充客户区,并贴图到CRichEditView中。
以加载透明背景的PNG图片为例,详述如下:
加入头文件引用,如果不用CImage类,可以不用此句
#include "atlimage.h"
// 自己派生一个CRichEditView子类。
class CViewMsg : public CRichEditView
声明几个变量
CRichEditCtrl* m_pCtrlREdit;// 内嵌的CRichEditCtrl控件指针
CImage m_ImageLogo; // 图片
UINT widthPic,heightPic; // 图片的长宽
COLORREF cl; // 指定图片的透明色
在OnInitialUpdate()中加入以下语句
void CViewMsg::OnInitialUpdate()
{
// ...
m_pCtrlREdit=&GetRichEditCtrl();
ASSERT_VALID(m_pCtrlREdit);
LONG lStyle=GetWindowLong(m_pCtrlREdit->m_hWnd,GWL_EXSTYLE); // 保存CRichEditCtrl的窗口风格
lStyle|=WS_EX_TRANSPARENT; // CRichEditCtrl的窗口风格加入透明背景
SetWindowLong(m_pCtrlREdit->m_hWnd,GWL_EXSTYLE,lStyle); // 重设CRichEditCtrl的新窗口风格
TCHAR g_szAppPath[260]; // 程序运行路径
::GetModuleFileName(NULL,g_szAppPath,260); // 获取当前程序路径
SetCurrentDirectory(g_szAppPath); //设置当前路径为程序模块(生成的exe文件)路径
PTSTR strImage=_T("Logo.png"); // 加载当前路径下的Logo.png图片
m_ImageLogo.Load(strImage);
if (m_ImageLogo.IsNull())
{
CString szTemp;
szTemp.Format(_T("错误!找不到%s!"),strImage);
MessageBox(szTemp);
}
else
{
widthPic=m_ImageLogo.GetWidth(); // 获取图片宽度
heightPic=m_ImageLogo.GetHeight(); // 获取图片高度
cl=m_ImageLogo.GetPixel(1,1); // 指定图片第一个像素作为透明色
}
重载OnEraseBkgnd函数
BOOL CViewMsg::OnEraseBkgnd(CDC* pDC)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CRect rect;
GetClientRect(&rect);
pDC->FillSolidRect(&rect,pDC->GetBkColor()); // 用原背景色刷一下背景,否则会把程序后面的统统看见,一团乱麻。此处可以pDC->GetBkColor()将替换自定义的颜色,如白色RGB(255,255,255)
if (m_ImageLogo)
{
m_ImageLogo.TransparentBlt(pDC->m_hDC,0,0,rect.Width(),rect.Height(),0,0,widthPic,heightPic,cl); // 帖图到CRichEditView中作为背景
}
return FALSE; // 通知窗口不用重绘背景了,我们已经填充过了。
//return CRichEditView::OnEraseBkgnd(pDC); // 把默认的重绘背景注释掉
}
此方法比CodeProject的方法要简单多了,我看他的代码觉得好复杂啊。不过大家可以参考一下他们的高招
http://www.codeproject.com/KB/edit/SemiRichEdit.aspx
http://www.codeproject.com/KB/edit/COleRichEditCtrl.aspx
补充:
1. COLORREF CRichEditCtrl http://bbs.csdn.net/topics/250014374 ::SetBackgroundColor(BOOL bSysColor, COLORREF cr );函数可设置控件的背景色,
2. BOOL CWnd::SetLayeredWindowAttributes(COLORREF crKey, BYTE bAlpha, DWORD dwFlags);函数可设置层叠窗口属性。
3. 有的朋友为了加快速度,喜欢用内存兼容DC来绘图,此时可以调用CRichEditCtrl::SetTargetDevice()指定文本输出到你的内存DC中,这样速度快多了