Mfc 透明背景的CWnd

Mfc 透明背景的CWnd,mfc,transparency,cwnd,Mfc,Transparency,Cwnd,我想创建一个基于CWnd的类,它将引入一个具有透明背景的控件 只要内容是静态的,创建控件并用透明背景绘制其内容对我来说没什么大不了的 问题是当我想创建一个内容不断变化的控件时。这是因为我不知道如何用父控件的背景擦除控件的内容(通常情况下,背景可能不仅仅是纯色) 因此,我想要实现的目标是在绘制控件的内容之前擦除控件,因为控件从未出现过(父控件,可能还会出现其他控件),而不是在此处绘制控件。您使用WS_EX_LAYERED和UpdateLayeredWindow()API绘制窗口。请参阅。您可以使用

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

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

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


因此,我想要实现的目标是在绘制控件的内容之前擦除控件,因为控件从未出现过(父控件,可能还会出现其他控件),而不是在此处绘制控件。

您使用WS_EX_LAYERED和UpdateLayeredWindow()API绘制窗口。请参阅。

您可以使用WS_EX_LAYERED和UpdateLayeredWindow()API来绘制窗口。请参阅。

如果要创建顶级窗口,则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功能包。如果您使用的是早期版本的MFCs,则可以使用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;

如果您想创建一个顶级窗口,Roel answer很好。如果需要装箱子窗口(如果要创建控件,则必须如此),则不能使用WS_EX_LAYERED(我认为这已从Windows 8开始改变)

简单的技巧是将父对象作为控制背景。因此,在OnEraseBkgnd中,您可以添加以下代码:

BOOL uiBarcodeButton::OnEraseBkgnd(CDC* pDC)
{
    CRect rect;
    GetClientRect(rect);

    return afxGlobalData.DrawParentBackground( this, pDC, rect);
}
不确定afxGlobalData全局变量是否仅适用于MFC 2008功能包。如果您使用的是早期版本的MFCs,则可以使用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;

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

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

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

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