Web浏览器疯狂 [英] WebBrowser Madness

查看:121
本文介绍了Web浏览器疯狂的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑:最初的问题很长,有很多疯狂的猜测.我已经把它减少到剩下的奥秘了.

The original question was a long one with many wild guesses. I have cut it back to the remaining mysteries..

我整天都在挣扎和困惑,我想我应该向社区提出我的问题.

I've been struggling and puzzling all day now and guess I ought to present my problem to the community.

它起源于 Screenshot方法生成黑色图像的帖子 .原始发布者希望每n秒连续即使用户注销,也要连续获取其程序的屏幕快照,其中包括WebBrowser.

It originated from the post called Screenshot method generates black images. The original poster wants to continuously take screenshots of his program, which includes a WebBrowser, every n seconds even when the user is logged off.

用户注销后,他不再显示任何屏幕.因此,任何尝试读取屏幕的操作都会失败.如果使用窗口句柄,则结果为黑框,使用CopyFromScreen时会出现GDI错误.

When the user is logged out he has no screen anymore. Therefore any attempt to read the screen will fail. If using a window handle the result is a black box, when using CopyFromScreen a GDI-error exception.

但是程序窗口仍然存在,并且即使用户注销也可以使用DrawToBitmap正常工作.

But the program window is still there and using DrawToBitmap works fine even when the user is logged out.

以下是条件和其余问题:

Here are the conditions and the remaining issues:

  • 用户不得以任何方式触摸/单击WebBrowser.如果他这样做,例如滚动,单击,导航子DrawToBitmap调用,则会产生一个空框.

  • The user must not touch/click the WebBrowser in any way. If he does by, say, Scrolling, Clicking, Navigating the subsqeuent DrawToBitmap calls result in an empty box.

虽然WebBrowser保持不变,但在下一个DrawToBitmap调用之前执行Refresh足以.

While the WebBrowser remains untouched, it is enough to do a Refresh before the next DrawToBitmap call.

触摸后,有必要通过执行webBrowser1.Url = new Uri(URLpath);

After touching it it is neccessary to load the URL again by doing a webBrowser1.Url = new Uri(URLpath);

在导航时,必须存储新的URL才能执行此操作.我是在导航"事件中这样做的.

When navigating the new URL must be stored to do this. I do that in the Navigated event.

无论如何,如果网页包含<input type="text" ..> fieldDrawToBitmap都会失败(带有空白框).

No matter what, DrawToBitmap fails (with the empty box) if the webpage contains a <input type="text" ..> field.

通过用Replace("<input", "<in_put");破坏DocumentText可以被治愈,但是如果没有其他技巧,这将丢失CSS工作表..

By vandalising the DocumentText with a Replace("<input", "<in_put"); this could be healed, but without further tricks this will lose the CSS sheets..

要进行测试,请抛出两个Buttons, a Label, a Timer, a Combobox and a WebBrowser on a Form并复制代码;将文件路径更改为适合您的设置和监视的文件夹..

To test it throw two Buttons, a Label, a Timer, a Combobox and a WebBrowser on a Form and copy the code; change the filepath to a folder that fits your setup and watch..:

public Form1()
{
    InitializeComponent();
    this.button1.Click += new System.EventHandler(this.button1_Click);
    this.button2.Click += new System.EventHandler(this.button2_Click);
    this.button1.Text = "Start";
    this.button2.Text = "Stop";
    this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
    this.comboBox1.Items.AddRange(new object[] {
        "https://stackoverflow.com/questions",
        "http://webcam.zirndorf.de/marktplatz/gross.jpg"});
    scapeRect = this.ClientRectangle;
    webBrowser1.Url = new Uri("https://stackoverflow.com/questions");
    this.comboBox1.SelectedIndexChanged += 
                   new System.EventHandler(this.comboBox1_SelectedIndexChanged);

}

Rectangle scapeRect = Rectangle.Empty;
int imgIndex = 0;
int urlIndex = 0;

private void button1_Click(object sender, EventArgs e)
{
    timer1.Interval = 10 * 1000;  // every 10 seconds
    timer1.Start();
}

private void button2_Click(object sender, EventArgs e)
{
    timer1.Stop();
}


private void timer1_Tick(object sender, EventArgs e)
{
    imgIndex ++;
    label1.Text = imgIndex .ToString();
    webBrowser1.Url = new Uri(comboBox1.Text); // this works almost always
    //webBrowser1.Refresh();                   // this works only if the WB is 'untouched'   
    string filename = "d:\\scrape\\AB_sos_Screen" + imgIndex .ToString("000") + ".png";
    Bitmap bmp = new Bitmap(scapeRect.Width, scapeRect.Height);
    this.DrawToBitmap(bmp, scapeRect);
    bmp.Save(filename, System.Drawing.Imaging.ImageFormat.Png);
    bmp.Dispose();
}

private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
    if (comboBox1.Text != "") webBrowser1.Url = new Uri(comboBox1.Text);
}




private void webBrowser1_Navigated(object sender, WebBrowserNavigatedEventArgs e)
{
    if (!comboBox1.Items.Contains(e.Url.ToString()))
        urlIndex = comboBox1.Items.Add(e.Url.ToString());
    else
        urlIndex = comboBox1.Items.IndexOf(e.Url.ToString());
    if (urlIndex >= 0) comboBox1.SelectedIndex = urlIndex;
    button1.Focus();
}

我现在几乎可以自由导航了,并且屏幕抓取功能仍然有效-带有文本输入字段(例如)的页面除外用户标签页面.

I can now navigate almost freely and the screen scraping keeps working - except for pages with textual input fields like e.g. the Users or the Tags pages.

我想知道是否有人可以繁殖..?

I wonder if anybdoy can reproduce ..?

还是解释?

还是我毕竟只是在寻鬼",而事情根本不可靠?

Or have I been just 'ghost hunting' after all and the thing is simply unreliable???

最终

虽然可能会得到很好的解释,但找到一个可行的解决方案可能必须足够好..OP已找到使用PrintWindow调用user32.dll的代码并解决了所有问题.它可以在注销时工作,即使在WebBrowser中单击也可以在Refreshing下工作,并刮擦所有页面,包括带有文本输入字段的页面.这是我的版本:

While it would have been nice to get an explanation, getting a working solution probably has to be good enough.. The OP has found code that uses a PrintWindow call to user32.dll and solves all problems. It works while being logged off, works with Refreshing even after clicking in the WebBrowser and scrapes all pages, including those with textual input fields. Here is my version of it:

using System.Runtime.InteropServices;
//...
[DllImport("user32.dll")]
public static extern bool PrintWindow(IntPtr hwnd, IntPtr hdcBlt, uint nFlags);

public Bitmap CaptureControl(Control ctl)
{
    //Bitmap bmp = new Bitmap(ctl.Width, ctl.Height);  // includes borders
    Bitmap bmp = new Bitmap(ctl.ClientRectangle.Width, ctl.ClientRectangle.Height);  // content only
    using (Graphics graphics = Graphics.FromImage(bmp))
    {
        IntPtr hDC = graphics.GetHdc();
        try      { PrintWindow(ctl.Handle, hDC, (uint)0);   }
        finally  { graphics.ReleaseHdc(hDC);                }
    }
    return bmp;
}

这可以捕获带有或不带有边框的表单或控件.

This can capture a Form or a Control with or without Borders.

推荐答案

经过一整天的努力之后,我只是想增加我的经验.

Just wanted to add my experience, after a long day of beating my head against this problem.

以上基于PrintWindow的方法只是在大多数WebBrowser控件上绘制了一个黑色矩形,尽管很奇怪,显示的文本的最后几行似乎通过了.因此,即使黑色矩形也不一致!但是我能够使DrawToBitmap()正常工作.

The above PrintWindow-based method just drew a black rectangle over most of the WebBrowser control, though oddly, the last few lines of displayed text seemed to come through. So even the black rectangle is inconsistent! But I was able to get DrawToBitmap() to work.

但是,有各种各样的隐藏要求.

However, there are all sorts of hidden requirements.

  • 首先,您的表单中只能有一个WebBrowser控件 —当我尝试添加第二个时,它会显示正常,但是 绘制到位图时它会变成空白.
  • 第二,WebBrowser必须是表单中最顶层的控件, 并且不能应用任何顶部/底部边距.违反 这往往导致我显示的HTML的底部被剪切 关闭,并且足够大的顶部/底部页边距往往会导致页面的 内容绘制到位图时会垂直拉伸.
  • 第三,要防止触摸WebBrowser,请创建一个 禁用Control来包装它,并将WebBrowser放在其中 该控件(DockFill).你要处理 显示整个HTML文档的内容,其中大部分是 在此处(即设置您的网络浏览器,并包含 控件的大小与Web浏览器的Document.Body.ScrollRectangleDocumentCompleted事件处理程序中).
  • First, you can only have one WebBrowser control in your form — when I tried to add a second one, it would display fine, but it would come out blank when drawn to a bitmap.
  • Second, the WebBrowser has to be the topmost control in your form, and it can't have any top/bottom margins applied to it. Violating this tended to lead to the bottom of my displayed HTML getting cut off, and large-enough top/bottom margins tended to lead to the page's content getting vertically stretched, when drawn to bitmap.
  • Third, to keep the WebBrowser from getting touched, create a disabled Control to wrap it, and put the WebBrowser inside of that control (with a Dock of Fill). You'll have to deal with displaying the contents of the entire HTML document, most of which is covered here (i.e. set your web-browser, and containing control's size to the web-browser's Document.Body.ScrollRectangle in a DocumentCompleted event-handler).

但是到目前为止,这种方法对我来说一直有效.

But so far, this method is working consistently for me.

这篇关于Web浏览器疯狂的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆