[英]Using TransparentBlt for drawing in MFC
我想将 CRect 的向量绘制到设备上下文中。 重叠的 CRect 相加应该使所有的交集变成更亮的绿色。 因此,我想出了以下代码:
void Grid::tag(CDC* pDC){
CBrush brushGreen;
brushGreen.CreateSolidBrush(RGB(0, 100, 0));
CDC dcMemory;
dcMemory.SelectObject(&brushGreen);
dcMemory.CreateCompatibleDC(pDC);
for (size_t i = 0; i < taglist.size(); i++){
dcMemory.FillRect(taglist[i], &brushGreen);
pDC->TransparentBlt(frame.left, frame.top, frame.Width(), frame.Height(), &dcMemory, taglist[i].left, taglist[i].top, taglist[i].Width(), taglist[i].Height(),RGB(0,100,0));
}
DeleteObject(brushGreen);
}
不幸的是,结果是黑色的。 似乎没有任何东西被吸引到 pDC 中。 我究竟做错了什么? 这是一种有效的方法吗?
您可以使用AlphaBlend代替TransparentBlt - 在 blt 期间进行颜色键控,您的代码中还有其他问题。 下面是一些修复程序,以及如何更正代码的想法(我还没有测试过它是否可以编译)。
CBrush brushGreen;
brushGreen.CreateSolidBrush(RGB(0, 100, 0));
CDC dcMemory;
//SO: what is the use of this? Also before creating DC
//dcMemory.SelectObject(&brushGreen);
dcMemory.CreateCompatibleDC(pDC);
//SO: for memory DC you need also a bitmap to be selected (dont forget to release it):
HBITMAP hbmp = CreateCompatibleBitmap((HDC)dc, 500, 500);
auto oldDcMemoryBmp = dcMemory.SelectObject(hbmp);
for (size_t i = 0; i < taglist.size(); i++){
dcMemory.FillRect(taglist[i], &brushGreen);
// SO: this is not needed
//pDC->TransparentBlt(frame.left, frame.top, frame.Width(), frame.Height(), &dcMemory, taglist[i].left, taglist[i].top, taglist[i].Width(), taglist[i].Height(),RGB(0,100,0));
// SO: Instead use albhaBlt
BLENDFUNCTION BlendFunction;
BlendFunction.AlphaFormat = AC_SRC_ALPHA;
BlendFunction.BlendFlags = 0;
BlendFunction.BlendOp = AC_SRC_OVER;
BlendFunction.SourceConstantAlpha = 15; // value 0 (transparent) to 255 (opaque)
dc.AlphaBlend(taglist[i].left, taglist[i].top, taglist[i].Width(), taglist[i].Height(), &dcMemory, 0, 0, taglist[i].Width(), taglist[i].Height(), BlendFunction);
}
//DeleteObject(brushGreen);
在您的示例中,您必须用透明颜色填充内存 dc。 这将初始化背景颜色,可以这么说。 然后在内存 dc 上绘制并使用具有该透明颜色的TransparentBlt
。
void CMyWnd::OnPaint()
{
CWnd::OnPaint();
CClientDC dc(this);
CRect rc;
GetClientRect(&rc);
//paint any custom background
dc.FillSolidRect(&rc, RGB(200,200,255));
//choose a color which you don't otherwise need, use it for transparency
COLORREF transparent_color = RGB(1, 1, 1);
//create memory dc and initialize with transparent_color:
CDC memdc;
memdc.CreateCompatibleDC(&dc);
CBitmap bitmap;
bitmap.CreateCompatibleBitmap(&dc, rc.right, rc.bottom);
memdc.SelectObject(bitmap);
memdc.FillSolidRect(&rc, transparent_color);
//start custom drawing on memeory dc:
CBrush brushGreen;
brushGreen.CreateSolidBrush(RGB(0, 100, 0));
CRect small_rc(10, 10, rc.right - 10, 20);
memdc.FillRect(small_rc, &brushGreen);
//end custom drawing
//Finish by copying memeory dc to destination dc:
dc.TransparentBlt(0, 0, rc.Width(), rc.Height(),
&memdc, 0, 0, rc.Width(), rc.Height(), transparent_color);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.