2012-12-03 112 views
1

我想創建一個基於CWnd的類,它將引入具有透明背景的控件。CWnd與透明背景

只要內容是靜態的,創建控件並使用透明背景繪製其內容沒有什麼大不了的。

問題是當我想通過更改內容創建控件時。這是因爲我不知道如何通過父母的背景來清除控件的內容(在一般情況下,這可能不僅僅是純色)。

所以我想要實現的目標是在繪製控件之前刪除控件,因爲控件永遠不會存在(父類,也許其他控件可能會出現),而不是在此處繪製控件。

回答

2

如果你想創建一個頂層窗口,Roel answer是好的。如果你需要創建一個子窗口(如果你正在創建一個控件,必須是這種情況),你不能使用WS_EX_LAYERED(我認爲這已經從Windows 8開始改變)。

簡單的技巧是將父母作爲控件背景。所以在OnEraseBkgnd您可以添加以下代碼:如果afxGlobalData全局變量只是MFC 2008功能包

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

    return afxGlobalData.DrawParentBackground(this, pDC, rect); 
} 

不知道。如果您使用的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; 
0

我用下面的代碼爲我的自定義靜態控制:

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