2011-10-04 156 views
1

我有以下的代码,那种只要你屏蔽掉粉像素不过是我真正想要的作品就像一个PNG文件,这样就可以避开Alpha混合的问题和需要透明位屏蔽掉特定的颜色处处将位图使用。如何在CBitmap上使用具有透明背景的CDC绘制文本?

CClientDC dc(pWnd); 
CDC memDC; 

if(!memDC.CreateCompatibleDC(&dc)) 
    return NULL; 

CRect bitmapRect; 
bitmapRect.SetRectEmpty(); 

CFont* pOldFont = memDC.SelectObject(pWnd->GetFont()); 
CSize fontSize = memDC.GetTextExtent(imageText); 

bitmapRect.right = fontSize.cx; 
bitmapRect.bottom = fontSize.cy; 

CBitmap bitmap; 
if(!bitmap.CreateCompatibleBitmap(&dc, bitmapRect.Width(), bitmapRect.Height())) 
    return NULL; 

CBitmap* pOldMemDCBitmap = memDC.SelectObject(&bitmap); 

memDC.FillSolidRect(&bitmapRect, RGB(255,0,255)); 
//memDC.SetBkMode(TRANSPARENT); // doesn't work 
//memDC.SetBkColor(TRANSPARENT); // doesn't work 
memDC.SetTextColor(GetSysColor(COLOR_WINDOWTEXT)); 

//memDC.DrawText(imageText, bitmapRect, DT_TOP|DT_LEFT|DT_NOCLIP); // same difference 
memDC.TextOut(0, 0, imageText); 

memDC.SelectObject(pOldMemDCBitmap); 
memDC.SelectObject(pOldFont); 
memDC.DeleteDC(); 

CImageList bmImage; 
bmImage.Create(bitmapRect.Width(), bitmapRect.Height(), ILC_COLOR32|ILC_MASK, 0, 1); 
// this masks out the pink but for some windows blends edges of text causing pink text instead of black! 
bmImage.Add(&bitmap, RGB(255,0,255)); 

只是错误填充的野兽,是MFC行为不当或我错过了什么?问这个

+1

IIRC'SetBkMode(透明)'应该做的伎俩。你没有任何机会只尝试将该行结合随后对'SetBkColor(TRANSPARENT)'的调用(它可能会将常数TRANSPARENT解释为某个颜色值,并且可能会覆盖透明模式)......? – HostileFork

+0

没有那些相互排斥只是我试过的东西的残余......我想我只是想出了我的问题,但在我更新或发布答案之前进行测试。 – AJG85

回答

1

约10分钟后,我读我自己的意见,并意识到“某些窗口”是指它关系到传递的窗口。特别是从使用的字体说窗口。具有默认属性的字体显示出奇怪的混合。

在这一天结束时,我决定,我需要修改字体关闭事情搞乱了我的绘制代码。我最终把范围缩小到一个罪魁祸首导致了问题:

CClientDC dc(pWnd); 
CDC memDC; 

if(!memDC.CreateCompatibleDC(&dc)) 
    return NULL; 

LOGFONT tempFont; 
CFont* winFont = pWnd->GetFont(); 
if (winFont) 
    winFont->GetLogFont(&tempFont); 
else 
{ 
    // generate a likely font 
    SecureZeroMemory(&tempFont, sizeof(LOGFONT)); 
    //TEXTMETRIC txt; 
    //GetTextMetrics(memDC, &txt); 
    //tempFont.lfHeight = txt.tmHeight * -1; // 16 is too big looking 
    tempFont.lfHeight = -12; 
    tempFont.lfWeight = FW_NORMAL; 
    tempFont.lfCharSet = DEFAULT_CHARSET; 
    wcscpy_s(tempFont.lfFaceName, L"Segoe UI"); // Win7 control default 
} 

tempFont.lfQuality = NONANTIALIASED_QUALITY; // this is the fix!!! 

CFont newFont; 
newFont.CreateFontIndirect(&tempFont); 

CFont* pOldFont = memDC.SelectObject(&newFont); 
// ... other stuff same as before ... 

所以我还是FillSolidRect粉色再画我的图标,文字,我想做的事情,等等。然后屏蔽掉粉红色的像素。随着字体质量的调整,它不再将粉红色混合到字体文本中,并且看起来不错。上面的其他情况创建了一个默认字体,以防CWnd*传入时没有指定有效的字体。

2

简单DrawText的()与透明背景无MFC:

// in my case a user drawn button: 
_windowHandle = CreateWindowEx(...); 
SendMessage(_windowHandle, WM_SETFONT, (WPARAM)font, (LPARAM)NULL); 

...

// WM_DRAWITEM 
SetTextColor(hDC, RGB(216, 27, 27)); 
SetBkMode(hDC, TRANSPARENT); 
RECT rect = { 0, 0, backgroundBitmap.bmWidth, backgroundBitmap.bmHeight }; 
DrawText(hDC, _text.c_str(), -1, &rect, DT_CENTER | DT_WORDBREAK); 

--hfrmobile