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