2

我有一个 .NET 控件,它通过非托管代码输出视频。

我想捕获控制客户区(视频帧)。

Control.DrawToBitmap方法不起作用,它输出控件背景 - 灰色。

然后我尝试使用 GDI 的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 destination 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);
    }

它可以工作,但问题是它捕获了所有 - 甚至是捕获控件之上的控件。

我想捕获控制客户区,即使它重叠。如何实现?

4

1 回答 1

1

应该可以工作,但是自从我用winforms编写代码来执行此操作以来已经有一段时间了……如果没有,我也许可以重新创建它。

而不是

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

[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);

另请注意,如果这为您提供了灰色背景,则可能意味着非托管代码未呈现到您的窗口中,而是在其顶部创建的另一个窗口。您可以通过 spy++ 查看是否属于这种情况。

于 2011-05-28T22:15:31.163 回答