1
votes

Using C++ and GDI+, I am drawing a rectangle on top of a image and Moving/Resizing the rectangle along with my MouseMovements, It was causing lots of flickering , so I decided to create a a transprent HDC on top on my Control. At the time of click I create that HDC and Draw on that HDC.

Here is my code...

HDC mSourceHDC; // Handle to the display device context 
HDC mMemoryDC;
HBITMAP mBitmap;
HBITMAP mOverlayBitmap;

in my Mouse Click CallBack

mSourceHDC = GetDC(hWnd); // Hwnd is the HWND of my control

RECT rc;
GetClientRect(hWnd, &rc);
int32 clientheight = rc.bottom - rc.top;
int32 clientWidth = rc.right - rc.left;

mMemoryDC = CreateCompatibleDC(mSourceHDC);
mBitmap = CreateCompatibleBitmap(mSourceHDC, clientWidth, clientheight);
mOverlayBitmap = (HBITMAP)SelectObject(mMemoryDC, mBitmap);

//SetBkMode(mMemoryDC,TRANSPARENT); // Line 1

// In my Mouse Move CallBack

if(mMemoryDC != NULL) {
  Gdiplus::Graphics gdiGraphics(mMemoryDC);
  gdiGraphics.Clear(Gdiplus::Color.LightGray);  // Line 2

  Gdiplus::Pen* myPen = new Gdiplus::Pen(Gdiplus::Color::White);
  myPen->SetWidth(2);

  Gdiplus::GraphicsPath *cropRectPath = new Gdiplus::GraphicsPath();
  cropRectPath->AddRectangle(cropRectF); // This cropRectF is my rectangle 
  gdiGraphics.DrawPath(myPen, cropRectPath); 

  BitBlt(mSourceHDC, 0, 0,  clntWdth, clntheight, mMemoryDC, 0, 0, SRCCOPY);
}

// In Mouse Leave Callback

if(mMemoryDC != NULL) {
  SelectObject(mMemoryDC, mOverlayBitmap);
  DeleteObject(mBitmap);
  DeleteDC(mMemoryDC);

  ReleaseDC(hWnd, mSourceHDC);
}

However, My rectangle is drawing correctly but during MouseMovement, my whole Window Becomes Gray and the Image is not shown, If I remove Line 2, then whole area becomes Black , Even I tried

gdiGraphics.Clear(Gdiplus::Color.Transparent);  in Line 2, still it turns Black.

I wanted to become this memory HDC transparent so that my Image is shown during the Mouse Move.

Any Idea where I am going wrong. Thanks

-Pankaj

1

1 Answers

1
votes

You're copying from the memory DC using Bitblt with SRCCOPY. That's going to overwrite everything. The SetBkMode call is just for drawing text with GDI--that's not relevant to blitting bitmaps.

The way to eliminate the flicker is to render everything to an offscreen bitmap, and then blit the final result back to the window DC. That's called double-buffering.

Create the bitmap and the memory DC as before. Instead of trying to clear the memory DC, copy whatever is supposed to appear in the client area to the memory DC. Then draw the selection rectangle on top of that. Finally, blit the memory DC back to the window DC (as you're already doing).