Question

I am trying to BitBlt from an HBITMAP to a GDI+ bitmap. I tried this, but nothing happens:

Bitmap Buffer = New Bitmap(608, 392)
Graphics BufferGraphics = Graphics.FromImage(Buffer);
IntPtr hBufferDC = BufferGraphics.GetHdc();

...

BitBlt(hBufferDC, x, y, width, height, hInputDC, 0, 0, SRCCOPY);

EDIT: Apparently the hDC doesn't work if I acquire it and then much later use it with BitBlt. I needed to make sure the hDC was still valid. This is the solution:

Bitmap Buffer = New Bitmap(608, 392)
Graphics BufferGraphics = Graphics.FromImage(Buffer);

...

IntPtr hBufferDC = BufferGraphics.GetHdc();
BitBlt(hBufferDC, x, y, width, height, hInputDC, 0, 0, SRCCOPY);
BufferGraphics.ReleaseHdc(hBufferDC);

Does anyone know why this change is necessary? Why might it not work to use an hDC that was gotten earlier as in the first example?

Was it helpful?

Solution

Check the sample at the end of this page on pinvoke.net. The additional calls to CreateCompatibleDC and SelectObject might make your sample work.

Alternatively, you can consider using Graphics.DrawImageUnscalled which would allow you to implement your code only on the .Net side and would still offer a pretty good performance.

Update (Due to updated question)
I don't know exactly why the hDC becomes invalid after a while, but according to MSDN you call GetHdc and ReleaseHdc in pairs and group the calls to GDI+ code between them: "Calls to the GetHdc and ReleaseHdc methods must appear in pairs. During the scope of a GetHdc and ReleaseHdc method pair, you usually make only calls to GDI functions."

So according to the documentation, the way you did in your second sample is the way to go and you shouldn't cache and reuse values from the GetHdc method.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top