您的位置:首页 > 其它

透明按钮背景不刷新【不使用父窗口背景刷新】

2014-08-29 14:20 736 查看
随笔- 10  文章- 0  评论- 37 


用C++实现半透明按钮控件(PNG,GDI+)





使用MFC实现上面的按钮半透明效果能看到父窗口中的内容,上面是效果图(一个是带背景图片的、另一个是不带的)。
控件继承自CWnd类(彩色的部分是窗口的背景图片、按钮是PNG图片,第二个图标是鼠标指向时的效果)。

图标的绘制使用GDI+绘制PNG图片,在此不多说了(处理WM_PAINT消息):



 1 void PNGButton::OnPaint()
2 {
3 CPaintDC dc(this);
4 Graphics g(dc.m_hDC);
5 if(DrawBorder){
6     g.DrawImage(hoverBg,0,0);//画鼠标指向时的亮色背景
7  }
8 g.DrawImage(this->bg,0,0);//画按钮图标
9   g.ReleaseHDC(dc.m_hDC);
10 }



 
透明的关键:注意后面调用此方法的代码
关键在于InvalidateRect函数:通知父窗口重新绘制特定区域,执行此函数后按钮所在区域就被父窗口绘制的内容覆盖.在父窗口绘制完成后,

按钮也会收到WM_PAINT消息,执行上面的一段OnPaint代码.



1 void PNGButton::PaintParent()
2 {
3 CRect rect;
4 GetWindowRect(&rect);
5 GetParent()-> ScreenToClient(&rect);
6 GetParent()-> InvalidateRect(&rect);
7 }



捕获鼠标指向或移出事件(处理WM_MOUSEMOVE,WM_MOUSEOVER,WM_MOUSELEAVE消息):
 



 1 void PNGButton::OnMouseHover(UINT nFlags, CPoint point)
2 {
3 DrawBorder=true;
4 PaintParent();//通知父窗口重绘特定区域,会引发控件自身的重绘
5 }
6
7
8  void PNGButton::OnMouseLeave()
9 {
10 m_is_mouse_over = false;
11 m_is_tracked = false;
12 DrawBorder=false;
13 PaintParent(); //通知父窗口重绘特定区域,会引发控件自身的重绘
14 CWnd::OnMouseLeave();
15 }
16
17
18  void PNGButton::OnMouseMove(UINT nFlags, CPoint point)
19 {
20 m_is_mouse_over = true;
21 if(!m_is_tracked)
22 {
23 TRACKMOUSEEVENT tme;
24 tme.cbSize = sizeof(TRACKMOUSEEVENT);
25 tme.dwFlags = TME_LEAVE|TME_HOVER;
26 tme.hwndTrack = GetSafeHwnd();
27 tme.dwHoverTime = 80;
28 _TrackMouseEvent(&tme);
29 m_is_tracked = true;
30 }
31 CWnd::OnMouseMove(nFlags, point);
32 }



附:
从资源加载PNG图片


View
Code

平铺图片的代码



 1     CPaintDC dc(this);
2 CRect rect;
3 GetClientRect(rect);
4 CBrush bs(RGB(240,240,240));//窗口背景色
5   dc.FillRect(&rect,&bs); //窗口着色
6 //填充背景图片:平铺
7   Graphics g(dc.m_hDC);
8 if(has_bg) g.DrawImage(this->bg,0,0);
9 Gdiplus::TextureBrush bbs(this->img);
10 g.FillRectangle(&bbs,0,0,rect.Width(),this->img->GetHeight());
11 g.ReleaseHDC(dc.m_hDC);
12 //TRACE(L"CMainFrame::OnPaint\r\n");



附:PNGButton类代码下载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐