MFC学习之 背景贴图及控件透明

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

  1.   
  1. void C***Dialog::OnPaint()   
  2. {  
  3.  CPaintDC dc(this); // device context for painting  
  4.  // CPaintDC  dc(this);    
  5.  CRect  rect;    
  6.  GetClientRect(&rect);    
  7.  CDC  dcMem;   //定义一个工具箱(设备上下文)  
  8.  dcMem.CreateCompatibleDC(&dc);///建立关联DC   
  9.  CBitmap  bmpBackground;   //位图对象  
  10.  bmpBackground.LoadBitmap(IDB_BITMAP_BKK);   //IDB_BITMAP是你自己的图对应的ID    
  11.  BITMAP  bitmap;    
  12.  bmpBackground.GetBitmap(&bitmap);  //建立绑定关系  
  13.  CBitmap  *pbmpOld=dcMem.SelectObject(&bmpBackground);   //保存原有CDC对象,并选入新CDC对象入DC  
  14.  dc.SetStretchBltMode(COLORONCOLOR);//防止bmp图片失真  
  15.  dc.StretchBlt(0,0,rect.Width(),rect.Height(),&dcMem,0,0,  bitmap.bmWidth,bitmap.bmHeight,SRCCOPY);  
  16.   
  17. // (个人建议把,rect.Width(),rect.Height()这两个数据 换成你的图片的大小,前提是图片足够大,这样图片不容易失真。关于图片失真,参考:http://blog.csdn.net/abidepan/article/details/7963929 )  
  18. dcMem.SelectObject(pbmpOld);  
  19. bmpBackground.DeleteObject();  
  20. dcMem.DeleteDC();  
  21. }  

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

  1. HBRUSH C***Dialog::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)   
  2. {  
  3.  HBRUSH hbr = CGraphDialog::OnCtlColor(pDC, pWnd, nCtlColor);  
  4.   
  5.  if( nCtlColor == CTLCOLOR_STATIC)        
  6.  {      
  7.   pDC->SetBkMode(TRANSPARENT);   //设置背景透明   
  8.   return   HBRUSH(GetStockObject(HOLLOW_BRUSH));  
  9.  }   
  10.  return hbr;  
  11. }  

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

  1. .H文件中  
  2.  afx_msg void OnPaint();  
  3.  afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);  
  4. CBrush m_brush;  
  5. .CPP文件中  
  6.  ON_WM_PAINT()  
  7.  ON_WM_CTLCOLOR()  

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

  1. HBRUSH CAllMaterialDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)   
  2. {  
  3.  HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);  
  4.    
  5.  if( nCtlColor == CTLCOLOR_STATIC)        
  6.  {      
  7.   pDC->SetBkMode(TRANSPARENT);   //设置背景透明   
  8. //  return   HBRUSH(GetStockObject(HOLLOW_BRUSH));  
  9.   hbr=(HBRUSH)(m_brush.GetSafeHandle());     
  10.  }   
  11.  return hbr;  
  12. }  

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

 

  1.  1、//if (pWnd == GetDlgItem(IDC_EDIT_CAMERA_TIME))  
  2.  //{  
  3.  // UpdateWindow();  
  4.  //}  
  5. 2、// Invalidate(FALSE);  
  6. 3、 //GetDlgItem(IDC_EDIT_CAMERA_TIME)->UpdateWindow();  
  7.  4、//GetDlgItem(IDC_EDIT_CAMERA_TIME)->Invalidate(TRUE);  
  8.  //GetDlgItem(IDC_EDIT_COMPUTERTIME)->Invalidate(TRUE);  

都不管用!

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

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

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

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

现在 Dlg::OnInitDialog()里加:

// 贴张图

  1. CBitmap m_Bitmap;  
  2. if(m_Bitmap.LoadBitmap(IDB_BITMAP_BKK))  
  3. {  
  4. m_brush.CreatePatternBrush(&m_Bitmap);  
  5. }  

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

再然后在Dlg::OnCtlColor里加:

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

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

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也一样。

  1. 在OnInitDialog() 里:m_brush.CreateSolidBrush(RGB(199, 0, 0));  
  2. 在OnCtlColor()里:  
  3.  if (pWnd->GetDlgCtrlID() == IDC_RADIO_ADMIN)  
  4.  {  
  5.   return (HBRUSH)(m_brush.GetSafeHandle());  
  6.  }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值