2016-04-04 70 views
1

私は、デバイスコンテキストにCRectのベクトルを描画します。オーバーラップするCRectsは、すべての交差点がより明るい緑に変わるようになるはずです。そこで、次のコードを考えました:TransparentBltをMFCで描画するために使用する

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

例では、メモリ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); 
} 
+0

ありがとうBarmak!そしてMarcinに感謝します!両方のアプローチを組み合わせることで、私はこの仕事を達成するのに役立ちました。 – Michen

1

blt中にカラーキーイングを行うTransparentBltの代わりに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); 
+0

コードを少し修正しましたが、上記と同じ結果が得られました。これは黒のままです。ここに私が書いたものがあります: [...] \t dcMemory.CreateCompatibleDC(pDC); \t HBITMAP hbmp = CreateCompatibleBitmap((HDC)dcMemory、frame.Width()、frame.Height()); \t dcMemory.SelectObject(hbmp); \t for(size_t i = 0; i AlphaBlend .Height()、&dcMemory、0、0、taglist [i] .Width()、taglist [i] .Height()、BlendFunction); – Michen

+0

@Michenあなたが提供しているコードを読むのは難しいです。 – marcinj

+0

それは申し訳ありませんが、Marcin。それは本当に奇妙ですが、私はそれを解決するように見えることはできません。画面は黒にかかわらず黒いままです。私がpDC-> FillRect(...)を直接使うと、うまくいきますが、もちろんブレンドはありません。論理的な観点から、間違っていなければならないのは、dcMemory.FillRect(...) FillRectが実際に成功するかどうかを確認する方法はありますか? – Michen

関連する問題