开发者

Capture without overlap

I have a .NET control which outputs a video via unmanaged code.

I'd like to capture the control client area (a video frame).

The method Control.DrawToBitmap does not work, it outputs the control background - gray color.

Then I tried to use the GDI's BitBlt:

    [DllImport("gdi32.dll")]
    private static extern bool BitBlt(
    IntPtr hdcDest, // handle to destination DC
    int nXDest, // x-coord of destination upper-left corner
    int nYDest, // y-coord of destination upper-left corner
    int nWidth, // width of destin开发者_StackOverflowation rectangle
    int nHeight, // height of destination rectangle
    IntPtr hdcSrc, // handle to source DC
    int nXSrc, // x-coordinate of source upper-left corner
    int nYSrc, // y-coordinate of source upper-left corner
    int dwRop // raster operation code
    );

    private const int SRCCOPY = 0xCC0020;

    private void btnSave_Click(object sender, EventArgs e)
    {
        Graphics graphic = captureBox.CreateGraphics();
        Bitmap memImage = new Bitmap(captureBox.Width, captureBox.Height, graphic);
        Graphics memGraphic = Graphics.FromImage(memImage);
        IntPtr dc1 = graphic.GetHdc();
        IntPtr dc2 = memGraphic.GetHdc();

        BitBlt(dc2, 0, 0, this.captureBox.ClientRectangle.Width,
        this.captureBox.ClientRectangle.Height, dc1, 0, 0, SRCCOPY);

        graphic.ReleaseHdc(dc1);
        memGraphic.ReleaseHdc(dc2);

        memImage.Save("capture.bmp", ImageFormat.Bmp);
    }

It works, but the problem is that it captures all - even controls that are over the captured control.

I want to capture the control client area even when it is overlapped. How can it be achieved?


this should work but its been a while since I've written code to do this with winforms... if it doesn't I may be able to recreate it.

Rather than

Graphics graphic = captureBox.CreateGraphics();
IntPtr dc1 = graphic.GetHdc();

do

[DllImport("gdi32.dll")]
private static extern IntPtr GetDC(IntPtr hWnd)
[DllImport("gdi32.dll")]
private static extern int ReleaseDc(IntPtr hWnd, IntPtr hDc)
// ...

IntPtr dc1 = GetDc(captureBox.Handle);
// ...
ReleaseDc(captureBox.Handle,dc1);

also note that if this gives you the grey background it may mean that the unmanaged code isn't rendering into your window, but another window that was created on top of it. You can find out if this is the case with spy++.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜