qq_38610144
2017-12-29 08:12
采纳率: 0%
浏览 1.6k

MFC中继承CStatic的对话框怎么设置透明度

1.该基类没有OnInitDialog可以重载。
2.在onCreate中调用以下函数在win10中可以,但是win7中失效
::SetWindowLong(m_hWnd, GWL_EXSTYLE, GetWindowLong(m_hWnd, GWL_EXSTYLE) | WS_EX_LAYERED);
::SetLayeredWindowAttributes(m_hWnd, 0, 1, LWA_ALPHA);

  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

7条回答 默认 最新

  • Owen_le 2017-12-29 08:35

    在有背景图片的对话框中,static控件的透明显示是一个非常普通的问题。
    常用的解决办法可以通过重载OnCtlColor函数设置背景透明,再返回一个空画刷来解决。

    if(nCtlColor == CTLCOLOR_STATIC )  
    {  
        pDC->SetBkMode(TRANSPARENT);//设置背景透明  
        pDC->SetTextColor(RGB(255,255,0));//设置字体为黄色  
        return (HBRUSH)::GetStockObject(NULL_BRUSH);  
    }   
    

    但这种方法有一个弊端:不能动态更新static控件内容,否则输出的文字会重叠。
    对于动态更新问题的解决办法就是将控件背后的对话框图片贴到控件上来,这样就可以实现static控件的动态更新了。
    下面将详叙通过CTransparentStatic类来实现static控件动态的透明显示的解决方案,其中在CTransparentStatic类的OnPaint函数中实现了动态更新控件背景图片(即将将控件背后的对话框图片贴到控件上来)。
    1、在头文件中为static控件增加一个变量(ID为IDC_STATIC_ELAPSETIME ),并使此变量类型为CTransparentStatic,而不是默认的CStatic

     CTransparentStatic m_staEelapseTime; 
    

    2、在对话框的OnInitDialog函数中设置此控件的字体大小和颜色

     m_staEelapseTime.SetFont(&m_font1);  
    m_staEelapseTime.SetTextColor(RGB(255,255,0));     //黄色  
    

    3、在OnCtlColor函数中设置此控件透明和颜色,并返回一个空画刷。

     if( pWnd ->GetDlgCtrlID() == IDC_STATIC_ELAPSETIME )  
            {  
                pDC->SetBkMode(TRANSPARENT);//设置背景透明  
                pDC->SetTextColor(RGB(255,255,0));//设置字体为黄色  
                return (HBRUSH)::GetStockObject(NULL_BRUSH);  
    
            } 
    

    注意,第三步必须有,否则动态显示staEelapseTime控件内容时,会先绘制windows默认的static控件,造成控件闪烁,自己试一下就知道了。

    通过以上步骤,就可以实现static控件的动态透明显示了,并且连续采样时也不会出现闪烁。

    下面是CTransparentStaticl类的源文件和头文件
    //CTransparentStatic.h

     #pragma once  
    
    
    // CTransparentStatic  
    
    class CTransparentStatic : public CStatic  
    {  
        DECLARE_DYNAMIC(CTransparentStatic)  
    public:  
        CDC         m_dcBk;  
        CBitmap     m_bmpBk;  
        CBitmap*    m_pbmpOldBk;  
    int m_nFontsize ;   
        void SetTextColor(COLORREF TextColor);  
        //void SetFont(int nSize) ;  
    
    
        COLORREF m_TextColor;  
    public:  
        CTransparentStatic();  
        virtual ~CTransparentStatic();  
    
    protected:  
        DECLARE_MESSAGE_MAP()  
    public:  
        afx_msg void OnPaint();  
        DWORD SetBk(CDC* pDC);  
    
    };  
    

    // CTransparentStatic.cpp

     // TransparentStatic.cpp : implementation file  
    //  
    
    #include "stdafx.h"  
    #include "TransparentStatic.h"  
    
    
    // CTransparentStatic  
    
    IMPLEMENT_DYNAMIC(CTransparentStatic, CStatic)  
    CTransparentStatic::CTransparentStatic()  
    {  
        //TRACE("CTransparentStatic::CTransparentStatic()\n");  
    }  
    
    CTransparentStatic::~CTransparentStatic()  
    {  
        //TRACE("CTransparentStatic::~CTransparentStatic()\n");  
    }  
    
    
    BEGIN_MESSAGE_MAP(CTransparentStatic, CStatic)  
        ON_WM_PAINT()  
    END_MESSAGE_MAP()  
    
    
    
    // CTransparentStatic message handlers  
    
    void CTransparentStatic::OnPaint()  
    {  
        //TRACE("CTransparentStatic::OnPaint()\n");  
        CPaintDC dc(this); // device context for painting  
    
        // Where to draw text  
        CRect client_rect;  
        GetClientRect(client_rect);  
    
        // Get the caption  
        CString szText;  
        GetWindowText(szText);  
    
        // Get the font  
        CFont *pFont, *pOldFont;  
        pFont = GetFont();  
        pOldFont = dc.SelectObject(pFont);  
    
    
        // Map "Static Styles" to "Text Styles"  
    #define MAP_STYLE(src, dest) if(dwStyle & (src)) dwText |= (dest)  
    #define NMAP_STYLE(src, dest) if(!(dwStyle & (src))) dwText |= (dest)  
    
        DWORD dwStyle = GetStyle(), dwText = 0;  
    
        MAP_STYLE(  SS_RIGHT,           DT_RIGHT                    );  
        MAP_STYLE(  SS_CENTER,          DT_CENTER                   );  
        MAP_STYLE(  SS_CENTERIMAGE,     DT_VCENTER | DT_SINGLELINE  );  
        MAP_STYLE(  SS_NOPREFIX,        DT_NOPREFIX                 );  
        MAP_STYLE(  SS_WORDELLIPSIS,    DT_WORD_ELLIPSIS            );  
        MAP_STYLE(  SS_ENDELLIPSIS,     DT_END_ELLIPSIS             );  
        MAP_STYLE(  SS_PATHELLIPSIS,    DT_PATH_ELLIPSIS            );  
    
        NMAP_STYLE( SS_LEFTNOWORDWRAP |  
                    SS_CENTERIMAGE |  
                    SS_WORDELLIPSIS |  
                    SS_ENDELLIPSIS |  
                    SS_PATHELLIPSIS,    DT_WORDBREAK                );  
    
        // Set transparent background  
        dc.SetBkMode(TRANSPARENT);  
    
        //解决重影(将对话框的背景图片贴到控件上)  
        CClientDC clDC(GetParent()); //创建其父窗口的客户区DC。由于此处控件的父窗口是对话框,因此就是获取对话框的DC。  
                                     //相当于GetDC  
        CRect rect;  
        CRect rect1;  
    
        GetClientRect(rect);//获取本static控件的客户区大小  
        //this->GetClientRect(rect); //省去一个this,this就代表触发wm_paint消息的控件,以下同  
        GetWindowRect(rect1);//获取本static控件在窗口的位置和大小  
        GetParent()->ScreenToClient(rect1);//将本static控件的屏幕座标转换为客户区座标  
    
        dc.SetTextColor(m_TextColor);//设置字体颜色  
    
    
        if (m_dcBk.m_hDC == NULL)  
        {  
            m_dcBk.CreateCompatibleDC(&clDC);  
            m_bmpBk.CreateCompatibleBitmap(&clDC, rect.Width(), rect.Height());  
    
            m_pbmpOldBk = m_dcBk.SelectObject(&m_bmpBk);  
            m_dcBk.BitBlt(0, 0, rect.Width(), rect.Height(), &clDC, rect1.left, rect1.top, SRCCOPY);//将clDC的图片copy至m_dcBk  
            //m_dcBk.BitBlt(0, 0, rect.Width(), rect.Height(), &clDC, 100, 100, SRCCOPY);  
        }  
    
        dc.BitBlt(0, 0, rect.Width(), rect.Height(), &m_dcBk, 0, 0, SRCCOPY);//将m_dcBk的图片copy至当前dc  
        //解决重影  
    
    
        // Draw the text  
        dc.DrawText(szText, client_rect, dwText);  
    
        // Select old font  
        dc.SelectObject(pOldFont);  
    
    }  
    void CTransparentStatic::SetTextColor(COLORREF TextColor)  
    {  
        //TRACE("CTransparentStatic::SetTextColor(COLORREF TextColor)\n");  
        m_TextColor=TextColor;  
    }  
    
    
    //void CTransparentStatic::SetFont(int nSize)   
    //{  
    //  TRACE("CTransparentStatic::SetFont(int nSize)\n");  
    //  m_nFontsize = nSize ;  
    //  
    //}  
    DWORD CTransparentStatic::SetBk(CDC* pDC)  
    {  
        TRACE("CTransparentStatic::SetBk(CDC* pDC)\n");  
    
        CClientDC clDC(GetParent());  
        CRect rect;  
        CRect rect1;  
    
        GetClientRect(rect);  
    
        GetWindowRect(rect1);  
        GetParent()->ScreenToClient(rect1);  
    
        if (m_dcBk.m_hDC == NULL)  
        {  
            m_dcBk.CreateCompatibleDC(&clDC);  
            m_bmpBk.CreateCompatibleBitmap(&clDC, rect.Width(), rect.Height());  
            m_pbmpOldBk = m_dcBk.SelectObject(&m_bmpBk);  
            m_dcBk.BitBlt(0, 0, rect.Width(), rect.Height(), &clDC, rect1.left, rect1.top, SRCCOPY);  
        } // if  
    
        m_dcBk.BitBlt(0, 0, rect.Width(), rect.Height(), pDC, rect1.left, rect1.top, SRCCOPY);  
    
            return 0;  
        } // if  
    
    打赏 评论
  • 星梦wqx 2017-12-29 08:58
    打赏 评论
  • 久违开发者 2017-12-29 09:02
    打赏 评论
  • qq_37411634 2017-12-29 09:06

    HBRUSH CNoticeView::OnCtlColor(CDC* pDC, CWnd* pWnd, UINTnCtlColor)
    {
    HBRUSH hbr = CFormView::OnCtlColor(pDC, pWnd, nCtlColor);
    if (CTLCOLOR_STATIC == nCtlColor)
    {
    pDC->SetBkMode(TRANSPARENT);
    return (HBRUSH)::GetStockObject(NULL_BRUSH);
    } //设置控件背景透明
    // TODO: 如果默认的不是所需画笔,则返回另一个画笔
    return hbr;
    }

    打赏 评论
  • zy5756 2017-12-29 12:17
    打赏 评论
  • qiaochuanbiao 2017-12-29 12:22

    MFC无法对单个控件设置透明,可以尝试再放一个对话框(看上去像是个控件),然后给这个对话框设置透明。

    打赏 评论
  • qq_38610144 2018-01-02 08:47

    我目前的情况是,在父对话框中有个子对话框,用于播放视频,但是播放时无法双击,所以又创建了一个同级的对话框覆盖了他,并给这个对话框设置透明,现在的问题是win10中这样没有问题,但是win7中透明效果失效了

    打赏 评论

相关推荐 更多相似问题