CRichEditView或CRichEditCtrl设置自定义背景图片的方法

科南 2008-07-18 11:59:07
CRichEditView或CRichEditCtrl设置自定义背景图片的方法

由于CRichEditView封装了CRichEditCtrl控件,并且重载OnPaint()来绘制背景图片,就会花脸。在OnSize和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,cl); // 用指定透明色刷一下背景,否则会把程序后面的统统看见,一团乱麻。此处可以将cl替换成窗口默认背景或自定义的颜色,如白色RGB(255,255,255)
CPaintDC* pdc=(CPaintDC*)m_pCtrlREdit->GetDC(); // 获取CRichEditCtrl控件的DC
if (m_ImageLogo)
{
m_ImageLogo.TransparentBlt(pdc->m_hDC,0,0,rect.Width(),rect.Height(),0,0,widthPic,heightPic,cl); // 帖图到CRichEditCtrl控件中
}
return FALSE; // 通知窗口不用重绘背景了,我们已经填充过了。
//return CRichEditView::OnEraseBkgnd(pDC); // 把默认的重绘背景注释掉
}


此方法比CodeProject的方法要简单多了,我看他的代码觉得好复杂啊。不过大家可以参考一下他们的高招
http://www.codeproject.com/KB/edit/SemiRichEdit.aspx
http://www.codeproject.com/KB/edit/COleRichEditCtrl.aspx
...全文
712 点赞 收藏 1
写回复
1 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
科南 2008-07-21
原帖方法会产生贴图遮挡文字的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::SetBackgroundColor(BOOL bSysColor, COLORREF cr );函数可设置控件的背景色,
2. BOOL CWnd::SetLayeredWindowAttributes(COLORREF crKey, BYTE bAlpha, DWORD dwFlags);函数可设置层叠窗口属性。
3. 有的朋友为了加快速度,喜欢用内存兼容DC来绘图,此时可以调用CRichEditCtrl::SetTargetDevice()指定文本输出到你的内存DC中,这样速度快多了
回复
相关推荐
发帖
界面
创建于2007-09-28

1.5w+

社区成员

VC/MFC 界面
申请成为版主
帖子事件
创建了帖子
2008-07-18 11:59
社区公告
暂无公告