【问题标题】:CWnd with transparent background具有透明背景的 CWnd
【发布时间】:2012-12-03 13:38:21
【问题描述】:

我想创建一个基于 CWnd 的类,该类将引入一个具有透明背景的控件。

只要内容是静态的,创建一个控件并用透明背景绘制其内容对我来说没什么大不了的。

问题是当我想创建一个内容不断变化的控件时。这是因为我不知道如何使用父背景(通常情况下可能不仅仅是纯色)擦除控件内容。

所以我想要实现的目标是在绘制其内容之前擦除控件,因为该控件从未存在(父控件,并且可能会出现其他控件),而不是在此位置绘制控件。

【问题讨论】:

    标签: mfc transparency cwnd


    【解决方案1】:

    如果你想创建一个顶级窗口,Roel 的回答很好。如果您需要创建一个子窗口(如果您正在创建一个控件,则必须是这种情况),您不能使用 WS_EX_LAYERED(我认为这已经从 Windows 8 开始改变了)。

    简单的技巧是绘制父控件作为背景。所以在 OnEraseBkgnd 你可以添加这个代码:

    BOOL uiBarcodeButton::OnEraseBkgnd(CDC* pDC)
    {
        CRect rect;
        GetClientRect(rect);
    
        return afxGlobalData.DrawParentBackground( this, pDC, rect);
    }
    

    不确定 afxGlobalData 全局变量是否仅适用于 MFC 2008 Feature Pack。如果您使用的是以前版本的 MFC,那么您可以使用 DrawParentBackground 中的代码:

    ASSERT_VALID(pDC);
    ASSERT_VALID(pWnd);
    
    BOOL bRes = FALSE;
    
    CRgn rgn;
    if (rectClip != NULL)
    {
        rgn.CreateRectRgnIndirect(rectClip);
        pDC->SelectClipRgn(&rgn);
    }
    
    CWnd* pParent = pWnd->GetParent();
    ASSERT_VALID(pParent);
    
    // In Windows XP, we need to call DrawThemeParentBackground function to implement
    // transparent controls
    if (m_pfDrawThemeBackground != NULL)
    {
        bRes = (*m_pfDrawThemeBackground)(pWnd->GetSafeHwnd(), pDC->GetSafeHdc(), rectClip) == S_OK;
    }
    
    if (!bRes)
    {
        CPoint pt(0, 0);
        pWnd->MapWindowPoints(pParent, &pt, 1);
        pt = pDC->OffsetWindowOrg(pt.x, pt.y);
    
        bRes = (BOOL) pParent->SendMessage(WM_ERASEBKGND, (WPARAM)pDC->m_hDC);
    
        pDC->SetWindowOrg(pt.x, pt.y);
    }
    
    pDC->SelectClipRgn(NULL);
    
    return bRes;
    

    【讨论】:

      【解决方案2】:

      您使用 WS_EX_LAYERED 和 UpdateLayeredWindow() API 来绘制您的窗口。见http://msdn.microsoft.com/en-us/library/ms997507.aspx

      【讨论】:

        【解决方案3】:

        我为我的自定义静态控件使用了以下代码:

        BOOL MyStaticText::OnEraseBkgnd(CDC* pDC)
        {
            CRect rect;
            GetClientRect(&rect);
            pDC->SelectObject((HBRUSH)GetStockObject(NULL_BRUSH));
            return pDC->PatBlt(0, 0, rect.Width(), rect.Height(), PATCOPY); 
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-05-31
          • 2011-07-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-10-29
          相关资源
          最近更新 更多