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



            

  • 15
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值