MFC 半透明按钮

效果展示
在这里插入图片描述
实现方法

  1. 给按钮加上BS_OWNERDRAW样式
  2. 重载DrawItem函数,在这里绘制按钮
  3. 关键之处就是把父窗口的背景复制到按钮上,实现视觉上的透明
  4. 最后通过AlphaBlend实现半透明.

源码下载:
http://blog.csdn.net/cometnet/article/details/8464693

实现源码

// MyButton.h 

#pragma once 

  
  
// CMyButton 

  
class CMyButton : public CButton

{ 
    DECLARE_DYNAMIC(CMyButton)

  
public:

    CMyButton();

    virtual ~CMyButton();

public:

    void SetBkColor(COLORREF color);

    void SetTextColor(COLORREF color);

private:

    bool m_bOver;

    bool m_bDown;

    bool m_bDisable;

    bool m_bTracking;

    COLORREF m_bkColor;

    COLORREF m_textColor;

protected:

    DECLARE_MESSAGE_MAP()

    virtual BOOL PreCreateWindow(CREATESTRUCT& cs);

    virtual void PreSubclassWindow();

public:

    virtual void DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/);

    afx_msg void OnMouseMove(UINT nFlags, CPoint point);

    afx_msg void OnLButtonDown(UINT nFlags, CPoint point);

    afx_msg void OnLButtonUp(UINT nFlags, CPoint point);

    afx_msg LRESULT OnMouseLeave(WPARAM wParam, LPARAM lParam);

    afx_msg LRESULT OnMouseHover(WPARAM wParam, LPARAM lParam);

    afx_msg void OnEnable(BOOL bEnable);

private:

    void ButtonInit();

    void DrawButton();

    void DrawButton(HDC hDestDC);

};
// MyButton.cpp : 实现文件

// 
  
#include "stdafx.h"

#include "AlphaButton.h"

#include "MyButton.h"

#include "MainDlg.h"

  
// CMyButton 

  
IMPLEMENT_DYNAMIC(CMyButton, CButton)

  
CMyButton::CMyButton()

{ 
    m_bkColor=0xFFFFFF;

    m_textColor=0x000000;

} 
  
CMyButton::~CMyButton()

{ 
} 
  
  
BEGIN_MESSAGE_MAP(CMyButton, CButton)

    ON_WM_MOUSEMOVE()

    ON_WM_LBUTTONDOWN()

    ON_WM_LBUTTONUP()

    ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)

    ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover)

    ON_WM_ENABLE()

END_MESSAGE_MAP() 

  
  
  
// CMyButton 消息处理程序

  
void CMyButton::SetBkColor(COLORREF color)

{ 
    m_bkColor=color;

} 
void CMyButton::SetTextColor(COLORREF color)

{ 
    m_textColor=color;

} 
  
BOOL CMyButton::PreCreateWindow(CREATESTRUCT& cs)

{ 
    BOOL bRet=CButton::PreCreateWindow(cs);

    ButtonInit();

    return bRet;

} 
  
void CMyButton::PreSubclassWindow()

{ 
    CButton::PreSubclassWindow();

    ButtonInit();

} 
void CMyButton::ButtonInit()

{ 
    m_bTracking=false;

    m_bOver=m_bDown=m_bDisable=false;

    m_bDisable=IsWindowEnabled()?FALSE:TRUE;

    ModifyStyle(NULL,BS_OWNERDRAW);

} 
  
void CMyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)

{ 
  
    DrawButton(lpDrawItemStruct->hDC);

} 
  
void CMyButton::OnMouseMove(UINT nFlags, CPoint point)

{ 
    if (!m_bTracking)

    {

        m_bOver = TRUE;

        TRACKMOUSEEVENT tme;

        tme.cbSize = sizeof(tme);

        tme.hwndTrack = m_hWnd;

        tme.dwFlags = TME_LEAVE | TME_HOVER;

        tme.dwHoverTime = 50;

        m_bTracking = (bool)_TrackMouseEvent(&tme);

    }

  
    CButton::OnMouseMove(nFlags, point);

} 
  
void CMyButton::OnLButtonDown(UINT nFlags, CPoint point)

{ 
    m_bDown=TRUE;

  
    CButton::OnLButtonDown(nFlags, point);

} 
  
void CMyButton::OnLButtonUp(UINT nFlags, CPoint point)

{ 
    m_bDown=FALSE;

    CButton::OnLButtonUp(nFlags, point);

} 
LRESULT CMyButton::OnMouseLeave(WPARAM wParam, LPARAM lParam)

{ 
    m_bOver = FALSE;

    m_bTracking = FALSE;

    m_bDown=FALSE;

    InvalidateRect(NULL, FALSE);

    return 0;

} 
  
LRESULT CMyButton::OnMouseHover(WPARAM wParam, LPARAM lParam)

{ 
    m_bOver = TRUE;

    InvalidateRect(NULL);

    return 0;

} 
void CMyButton::DrawButton()

{ 
    HDC hDC=::GetDC(m_hWnd);

    DrawButton(hDC);

    ::ReleaseDC(m_hWnd,hDC);

} 
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--255

    int 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; // 透明度 最大255

  
    HRGN 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);

  
} 
void CMyButton::OnEnable(BOOL bEnable)

{ 
    CButton::OnEnable(bEnable);

    m_bDisable=IsWindowEnabled()?FALSE:TRUE;

    DrawButton();

}
  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
要设置MFC对话框为半透明,可以使用以下步骤: 1. 打开对话框资源文件(例如MyDialog.rc)。 2. 选择对话框并打开其属性窗口。 3. 在属性窗口中,找到“Style”属性,并将其设置为“Popup”。 4. 找到“ExStyle”属性,并将其设置为“Transparent”。 5. 保存并关闭资源文件。 6. 打开对话框的头文件(例如MyDialog.h)。 7. 在头文件中添加以下代码: ``` BOOL OnInitDialog(); afx_msg void OnPaint(); afx_msg BOOL OnEraseBkgnd(CDC* pDC); ``` 8. 在对话框的源文件(例如MyDialog.cpp)中实现这些函数: ``` BOOL CMyDialog::OnInitDialog() { CDialogEx::OnInitDialog(); // 设置背景透明 SetWindowLong(GetSafeHwnd(), GWL_EXSTYLE, GetWindowLong(GetSafeHwnd(), GWL_EXSTYLE) | WS_EX_LAYERED); SetLayeredWindowAttributes(RGB(255, 255, 255), 200, LWA_ALPHA); return TRUE; } void CMyDialog::OnPaint() { CPaintDC dc(this); // 绘制对话框内容 // ... // 绘制背景透明 dc.FillSolidRect(0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), RGB(255, 255, 255)); } BOOL CMyDialog::OnEraseBkgnd(CDC* pDC) { // 防止擦除背景 return TRUE; } ``` 在这些函数中,我们使用SetWindowLong和SetLayeredWindowAttributes函数将对话框设置为半透明。在OnPaint函数中,我们绘制对话框内容,并使用FillSolidRect函数绘制背景透明。在OnEraseBkgnd函数中,我们返回TRUE以防止擦除背景。 现在,您的MFC对话框应该显示为半透明了!
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值