Delphi :TWebBrowser在后台线程中

qv7cva1a  于 12个月前  发布在  其他
关注(0)|答案(3)|浏览(126)

是否可以在后台线程中加载TWebBrowser中的网页?
当应用程序加载时,我想从Web下载一个页面到TWebBrowser中,但我不想阻塞gui线程。
有什么建议吗?

一些说明:

webbrowser-component是生活在一个形式,我想显示一个网页从web.但我想做所有下载的网页在一个后台线程,这样加载一个沉重的页面不会阻塞gui线程.
我想我一般都能写好帖子。

ippsafx7

ippsafx71#

TWebBrowseralready在一个单独的线程中下载东西。你的程序在下载时应该已经保持响应。你可以看到这一点,因为一个常见的模式是设置URL,然后等待下载完成:

WebBrowser1.Navigate(...);
while WebBrowser1.Busy do
  Application.ProcessMessages;

字符串
它使用ProcessMessages,所以我不能真诚地推荐它。要在下载完成时得到通知,而不是像代码那样轮询,处理控件的OnNavigateComplete2事件。注意,该事件可能会在框架和主页上触发。
如果你想 * 显示 * 页面,那么你的TWebBrowser控件无论如何都不应该在一个单独的线程中,因为它与VCL使用的任何其他控件都福尔斯相同的规则。如果你只是使用控件来 * 下载 * 页面,那么TWebBrowser可能会大材小用。你可以使用Indy,或者操作系统内置的文件下载功能。这些可以很容易地在单独的线程中使用。

wixjitnu

wixjitnu2#

我也需要同样的功能(自动截图页面),我开始使用Rob的代码。它不适用于我正在加载的页面.有一半的时间忙碌标志没有设置,而显然页面还没有完成。
经过一番研究,这似乎起作用了:

while (webBrowser1.ReadyState <>  READYSTATE_COMPLETE) do
  Application.ProcessMessages;

字符串
其中readystate是以下之一:

const READYSTATE_UNINITIALIZED = 0; // Default initialisation state.
const READYSTATE_LOADING = 1; // Object is currently loading data.
const READYSTATE_LOADED = 2; // Object has been initialised.
const READYSTATE_INTERACTIVE = 3; // User can interact with the object but loading has not yet finished.
const READYSTATE_COMPLETE = 4; // All of the object's data has been loaded.


使用readystate的想法来自这里:http://gaskell.org/making-the-webbrowser-control-synchronous/
readystate Delphi 常量取自此处:http://www.cryer.co.uk/brian/delphi/twebbrowser/twebbrowser_properties.htm

0yg35tkg

0yg35tkg3#

我不得不说,我从来没有尝试过类似的东西,但我认为你会遇到问题。
一个进程中可以有多个线程,所有线程都实现消息循环并处理该线程的窗口的消息,但所有窗口都绑定到创建它们的线程。Windows消息将始终在创建窗口的线程中处理。因此,您可以从另一个线程调用嵌入式TWebBrowser控件的方法,但由于这将涉及发送消息到Web浏览器窗口,因此它们仍将在GUI线程中处理。
有关更多信息,请查看Wikipedia关于COM中线程的文章以及Raymond Chen关于STA(如this one)的博客文章。

相关问题