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

来源:互联网 发布:橙名网络 编辑:程序博客网 时间:2024/06/05 14:29

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



            

原创粉丝点击