当前位置: 首页 > 面试题库 >

WebBrowser.DrawToBitmap()还是其他方法?

耿玄裳
2023-03-14
问题内容

我正在尝试捕获WebBrowser控件的内容。DrawToBitmap()可以完美地工作,但是WebBrowser控件的文档中不支持它。我一直在尝试寻找另一种捕获WebBrowser控件的内容并将其保存到本地图像文件的方法。

是否有人有任何变通办法或其他方法将WebBrowser控件的内容保存到本地图像文件?


问题答案:

Control.DrawToBitmap并不总是能正常工作,因此我诉诸于以下提供更一致结果的本机API调用:

实用程序类。调用Utilities.CaptureWindow(Control.Handle)捕获特定的控件:

public static class Utilities
{
    public static Image CaptureScreen()
    {
        return CaptureWindow(User32.GetDesktopWindow());
    }

    public static Image CaptureWindow(IntPtr handle)
    {

        IntPtr hdcSrc = User32.GetWindowDC(handle);

        RECT windowRect = new RECT();
        User32.GetWindowRect(handle, ref windowRect);

        int width = windowRect.right - windowRect.left;
        int height = windowRect.bottom - windowRect.top;

        IntPtr hdcDest = Gdi32.CreateCompatibleDC(hdcSrc);
        IntPtr hBitmap = Gdi32.CreateCompatibleBitmap(hdcSrc, width, height);

        IntPtr hOld = Gdi32.SelectObject(hdcDest, hBitmap);
        Gdi32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, ApiConstants.SRCCOPY);
        Gdi32.SelectObject(hdcDest, hOld);
        Gdi32.DeleteDC(hdcDest);
        User32.ReleaseDC(handle, hdcSrc);

        Image image = Image.FromHbitmap(hBitmap);
        Gdi32.DeleteObject(hBitmap);

        return image;
    }
}

Gdi32类:

public class Gdi32
{
    [DllImport("gdi32.dll")]
    public static extern bool BitBlt(IntPtr hObject, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hObjectSource, int nXSrc, int nYSrc, int dwRop);
    [DllImport("gdi32.dll")]
    public static extern IntPtr CreateCompatibleBitmap(IntPtr hDC, int nWidth, int nHeight);
    [DllImport("gdi32.dll")]
    public static extern IntPtr CreateCompatibleDC(IntPtr hDC);
    [DllImport("gdi32.dll")]
    public static extern bool DeleteDC(IntPtr hDC);
    [DllImport("gdi32.dll")]
    public static extern bool DeleteObject(IntPtr hObject);
    [DllImport("gdi32.dll")]
    public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);
}

User32类:

public static class User32
{
    [DllImport("user32.dll")]
    public static extern IntPtr GetDesktopWindow();
    [DllImport("user32.dll")]
    public static extern IntPtr GetWindowDC(IntPtr hWnd);
    [DllImport("user32.dll")]
    public static extern IntPtr GetWindowRect(IntPtr hWnd, ref RECT rect);
    [DllImport("user32.dll")]
    public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);
}

使用的常量

    public const int SRCCOPY = 13369376;

使用的结构:

[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
    public int left;
    public int top;
    public int right;
    public int bottom;
}

友好的Control扩展方法:

public static class ControlExtensions
{
    public static Image DrawToImage(this Control control)
    {
        return Utilities.CaptureWindow(control.Handle);
    }
}

这是我CC.Utilities项目的代码段,我专门编写了该代码段以从WebBrowser控件中截取屏幕截图。



 类似资料:
  • 问题内容: 在我的项目中,我需要在运行时在数据库之间切换。我尝试使用Hibernate,但是卡在一个地方,我需要在数据库中映射对象和表。问题是,我有几个带前缀的表:documents2001,documents2002 …据我了解,我在运行时无法将类与表进行映射。我尝试使用iBatis,但问题出在运行时更改数据库。在iBatis中,这很难做到。 也许一些建议,我应该使用什么? 我的要求: 能够在运

  • 我今天读了这篇关于lambdas的文章: http://www.infoq.com/articles/Java-8-Lambdas-A-Peek-Under-the-Hood 本文建议,lambda不是作为一个非内部类实现的(由于性能原因)。它给出了一个示例,可以将lambda表达式编译为类的(静态)方法。 我尝试了一个非常简单的片段: 输出是: 所以这不是同一个实例。它也不是一些中央的“Lamb

  • 如果ArrayList中还没有,我希望将添加到ArrayList中,但由于某些原因,它无法工作。在本例中,arrlist是,arr是。此代码位于for循环中,其中arr在循环中定义,因此arr中的值会更改。即使我打印出arrlist并且它有arr,代码总是说arrlist不包含arr。是否有其他方法可以检查ArrayList是否包含?

  • 其他认证方法 还有两种其他身份验证方法值得一提。它们是一次性密码和证书。 一次性密码 FreeRADIUS包含一个名为rlm_otp的模块,可用于处理OTP(一次性密码)令牌。该模块应与其他程序一起使用。 不幸的是,为其他程序提供代码的公司Tri-D Systems已经不存在了。但是,代码是分叉的,现在可以从Google Code(http://code.google.com/p/otpd/)获得

  • 我的理解是,在Tomcat中,每个请求将占用一个Java/(因此也是OS)线程。 想象一下,我有一个应用程序,有很多长时间运行的请求(例如一个有多个玩家的扑克游戏),涉及游戏内聊天和AJAX长轮询等。 有没有办法更改我的webapp的tomcat配置/体系结构,这样我就不会对每个请求使用线程,而是“截获”请求和响应,这样它们就可以作为队列的一部分进行处理?