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