MFC背景贴图及控件透明

在CDialog类中进行贴图,一般放在OnPaint()函数中,因为窗口更新时,使用它来进行重绘。在OnPain()中贴图的源码如下:

void C***Dialog::OnPaint()
{
CPaintDC dc(this); // device context for painting
//CPaintDC dc(this);
CRect rect;
GetClientRect(&rect);
CDC dcMem; //定义一个工具箱(设备上下文)
dcMem.CreateCompatibleDC(&dc);///建立关联DC
CBitmap bmpBackground; //位图对象
bmpBackground.LoadBitmap(IDB_BITMAP_BKK);//IDB_BITMAP是你自己的图对应的ID
BITMAP bitmap;
bmpBackground.GetBitmap(&bitmap);//建立绑定关系
CBitmap *pbmpOld=dcMem.SelectObject(&bmpBackground);//保存原有CDC对象,并选入新CDC对象入DC

dc.SetStretchBltMode(COLORONCOLOR);//防止bmp图片失真
dc.StretchBlt(0,0,rect.Width(),rect.Height(),&dcMem,0,0,bitmap.bmWidth,bitmap.bmHeight,SRCCOPY);

// (个人建议把,rect.Width(),rect.Height()这两个数据 换成你的图片的大小,前提是图片足够大,这样图片不容易失真。关于图片失真,参考:http://blog.csdn.net/abidepan/article/details/7963929

dcMem.SelectObject(pbmpOld);
bmpBackground.DeleteObject();
dcMem.DeleteDC();
}

当你贴图完毕后,会发现很多地方出现了原来的底色,这是因为这是你的其他东东即控件,的画刷没有设置透明背景色。所有下一步就是设置透明背景色,代码如下:

HBRUSH C***Dialog::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CGraphDialog::OnCtlColor(pDC, pWnd, nCtlColor);

if( nCtlColor == CTLCOLOR_STATIC)
{
pDC->SetBkMode(TRANSPARENT); //设置背景透明
return HBRUSH(GetStockObject(HOLLOW_BRUSH));
}
return hbr;
}

这两个函数均为消息响应函数,所以还需要添加消息响应

.H文件中

afx_msg void OnPaint();
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);

CBrush m_brush;

.CPP文件中

ON_WM_PAINT()
ON_WM_CTLCOLOR()

这个时候贴图的效果就非常好了,但是你如果动态的修改静态文本框控件内容时候,又发现了新的问题,发现字符可能重叠。这个原因是你在OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 函数中,将画刷设置为透明引起的。那怎么解决内,你就需要,在OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 函数中返回一个具有背景的画刷了。具体的办法可以自己去琢磨,我这里有个比较笨的办法,给大家提供一个借鉴:

HBRUSH CAllMaterialDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

if( nCtlColor == CTLCOLOR_STATIC)
{
pDC->SetBkMode(TRANSPARENT); //设置背景透明
//return HBRUSH(GetStockObject(HOLLOW_BRUSH));
hbr=(HBRUSH)(m_brush.GetSafeHandle());
}
return hbr;

}

有可能用到 Edit 控件时,而且用到时钟控件在编辑框中显示时间,这个时候又会出现文本重叠的问题。

1、//if (pWnd == GetDlgItem(IDC_EDIT_CAMERA_TIME))
//{
//UpdateWindow();
//}

2、//Invalidate(FALSE);
3、//GetDlgItem(IDC_EDIT_CAMERA_TIME)->UpdateWindow();

4、//GetDlgItem(IDC_EDIT_CAMERA_TIME)->Invalidate(TRUE);
//GetDlgItem(IDC_EDIT_COMPUTERTIME)->Invalidate(TRUE);

都不管用!

------------------------------------------------------------------------------------------------------------------------

最令人纠结的应该是滑动条了!如果不做处理,就是这个样子滴!

最后做出的效果是这样滴:

也不怎么好看,先把方法写上来,以后再改好了。我自己也不知道怎么就搞成这样了 = =、

现在Dlg::OnInitDialog()里加:

// 贴张图
CBitmap m_Bitmap;
if(m_Bitmap.LoadBitmap(IDB_BITMAP_BKK))
{
m_brush.CreatePatternBrush(&m_Bitmap);
}

然后::OnPaint() 跟上面的一样代码

再然后在Dlg::OnCtlColor里加:

if (pWnd == GetDlgItem(IDC_SLIDER_SPEED)) //IDC_SLIDER_SPEED是滑动条的ID
{
return (HBRUSH)m_brush.GetSafeHandle();
}

.....//这里是各种控件的透明

pDC->SetBkMode(TRANSPARENT); //背景透明模式
return (HBRUSH)GetStockObject(NULL_BRUSH);

然后就成上面那样了~

=======================================================================================================================

今天做另一个项目的UI,用到了 TabCtrl 这个控件,遇到了跟Slider类似的背景透明问题,然后分析了以前做Slider时的代码,知道了为什么上面的控件背景颜色是那样的了。

图1

图2

TabCtrl 这个控件跟 Slider 一样 ,背景很难搞,在整个对话框贴了背景图片之后的样子 如 图一

如果按Slider那样做,也行

这次是把Dlg::OnInitDialog():里的代码改成 m_brush.CreateSolidBrush(RGB(199, 199, 199));

其中 RGB(199, 199, 199) 其实就是 黑色区域附近的灰色 的颜色,然后在Dlg::OnCtlColor 返回画刷的时候,返回这个颜色就行了。

对于一张颜色不太细致的背景图片来说,这样做 如果不仔细看的话,是没什么问题的。

(后面的灰色是一张渐变的bmp图片)


==============================================================================================================================

radiobutton的透明:checkbox也一样。

在OnInitDialog() 里:m_brush.CreateSolidBrush(RGB(199, 0, 0));

在OnCtlColor()里:

if (pWnd->GetDlgCtrlID() == IDC_RADIO_ADMIN)
{
return (HBRUSH)(m_brush.GetSafeHandle());
}



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值