背景透明总结

来源:互联网 发布:ubuntu 14.04 lamp 编辑:程序博客网 时间:2024/06/16 15:53

        最近在做客户端程序,遇到了各种透明的问题,下面就自己学到的一点东西写出来,同时希望有更好的方法的可以提出来,大家一起学习!!

 

    一、按钮透明(CButton)

    方法一、可以利用首先CImage来保存窗口的背景,再将它绘制到button上,这样可以实现背景透明。不过CImage是ATL里面的类,所以使用CImage就要编译器有ATL并且要会用ATL。下面具体讲解下使用的方法:

     1、在窗口中定义CImage对象m_bkImage,并将位图加载到里面,然后设置成窗口背景;

主窗口.h文件中定义

public:CImage m_bkImage;

主窗口.cpp文件中加载和设置窗口背景

BOOL CMainDlg::OnInitDialog(){CDialog::OnInitDialog();// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动//  执行此操作SetIcon(m_hIcon, TRUE);// 设置大图标SetIcon(m_hIcon, FALSE);// 设置小图标m_bkImage.LoadFromResource(AfxGetInstanceHandle(),IDB_BITMAP1);return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE}BOOL CMainDlg::OnEraseBkgnd(CDC* pDC){CRect rc;GetClientRect(&rc);m_bkImage.BitBlt(pDC->GetSafeHdc(),rc,CPoint(0,0),SRCCOPY);return TRUE;}

    2、在绘制(DrawItem)button时,把窗口对应的图像BitBlt到button上

void CMyButton::DrawButton(HDC hDestDC){        CRect rc;GetClientRect(rc);int nWindth=rc.Width();int nHeight=rc.Height(); HDC hDC=CreateCompatibleDC(hDestDC);//创建兼容DC,采用双缓冲画出 HDC hMaskDC=CreateCompatibleDC(hDestDC); HBITMAP hBitmap=CreateCompatibleBitmap(hDestDC,nWindth,nHeight); HBITMAP hMaskBitmap=CreateCompatibleBitmap(hDestDC,nWindth,nHeight); HBITMAP hOldBitmap=(HBITMAP)SelectObject(hDC,hBitmap); HBITMAP hOldMaskBitmap=(HBITMAP)SelectObject(hMaskDC,hMaskBitmap); SetBkMode(hDC,TRANSPARENT);//把父窗口的背景图复制到按钮的DC上,实现视觉透明----------------CMainDlg* pParent=(CMainDlg*)GetParent();CPoint pt(0,0);MapWindowPoints(pParent,&pt,1);pParent->m_bkImage.BitBlt(hDC,rc,pt,SRCCOPY);//-------------------------------------------------------------int nAlpha=100;//0--255int nOffset=0;HBRUSH hbr=CreateSolidBrush(m_bkColor);FillRect(hMaskDC,&rc,hbr);DeleteObject(hbr);if(m_bDisable){nAlpha=100;}else if(m_bDown){nAlpha=180;nOffset=1;}else if(m_bOver){nAlpha=150;}else{nAlpha=100;}BLENDFUNCTION blend;memset( &blend, 0, sizeof( blend) );blend.BlendOp= AC_SRC_OVER;blend.SourceConstantAlpha= nAlpha; // 透明度 最大255HRGN hRgn=CreateRoundRectRgn(0,0,nWindth,nHeight,3,3);SelectClipRgn (hDC,hRgn);AlphaBlend (hDC,0,0,nWindth,nHeight,hMaskDC, 0,0,nWindth,nHeight,blend);CString strText;GetWindowText(strText); if(strText!=_T("")){rc.InflateRect(-2,-2);rc.OffsetRect(nOffset,nOffset);HFONT hFont=(HFONT)SendMessage(WM_GETFONT);if(!hFont)hFont=(HFONT)GetStockObject(DEFAULT_GUI_FONT);HFONT hOldFont=(HFONT)SelectObject(hDC,hFont);::SetTextColor(hDC,m_textColor);::DrawText(hDC,strText,-1,&rc,DT_SINGLELINE|DT_CENTER|DT_VCENTER|DT_WORD_ELLIPSIS);::SelectObject(hDC,hOldFont); }SelectClipRgn (hDC,NULL);DeleteObject(hRgn);//复制到控件的DC上------------------------BitBlt(hDestDC,0,0,nWindth,nHeight,hDC,0,0,SRCCOPY);//删除资源,释放内存-----------------------SelectObject(hDC,hOldBitmap);DeleteObject(hBitmap);DeleteDC(hDC);SelectObject(hMaskDC,hOldMaskBitmap);DeleteObject(hMaskBitmap);DeleteDC(hMaskDC);}

上面的代码其实是制作水晶按钮的代码,不过大家可以看到其中有一段代码是专门用来赋值背景的;
这种方法的实例大家可以看看这个:http://blog.csdn.net/cometnet/article/details/8464693

    方法二、在OnEraseBkgnd把系统的绘制去掉,然后他就变成透明的了

     1、这种方法很简单,要实现最直接的办法就是把这个函数体内的所用代码去掉,然后返回真就可以了

BOOL CBmpButton::OnEraseBkgnd(CDC* pDC) {//去掉系统自绘背景,是背景透明return true;}

这种方法虽然直接,但他只是是背景透明如果你在背景上画了东西,下次也不会擦除。所以我们应该在绘制前,把主窗口按钮对应位置的图像拷贝到这里来:

BOOL CMyBuuton::OnEraseBkgnd(CDC* pDC) {    CWnd *pParent = GetParent();       CRect rc;    GetWindowRect(rc);    pParent->ScreenToClient(rc);    pParent->InvalidateRect(rc,false);    pParent->UpdateWindow();    CDC *dcParent = pParent->GetDC();       pDC->BitBlt(0,0,rc.Width(),rc.Height(),dcParent,rc.left,rc.top,SRCCOPY);    pParent->ReleaseDC(dcParent);    return true;}

这种方法的画感觉有点闪烁,我自己还没有找到方法,大家有解决的可以分享呀



 

 

原创粉丝点击