我想将CRect的矢量绘制到设备上下文中。重叠的CRects应该以所有交叉点变为更亮的绿色的方式相加。因此我想出了以下代码:
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。我究竟做错了什么?这是一个有效的方法吗?
答案 0 :(得分:1)
而不是TransparentBlt - 在blt期间进行颜色键控,您可以使用AlphaBlend,代码中还有其他问题。下面是一些修复,以及如何更正代码的想法(我没有测试过这是否编译)。
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);
答案 1 :(得分:0)
In your example you have to fill memory dc with a transparent color. This will initialize the background color, so to speak. Then draw on memory dc and use TransparentBlt
with that transparent color.
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);
}