当应用程序加载时,我想从Web下载一个页面到TWebBrowser中,但我不想阻塞GUI线程。
有什么建议吗?
一些澄清:
WebBrowser组件存在于一个表单中,并且我想显示来自Web的页面。但我希望将所有下载该页面的工作都放在后台线程中,以便加载重型页面不会阻塞GUI线程。
我认为我能够编写一般的线程。
TWebBrowser
已经在一个单独的线程中下载内容。在下载期间,您的程序应该保持响应。您可以通过设置URL并等待下载完成来验证此操作:
WebBrowser1.Navigate(...);
while WebBrowser1.Busy do
Application.ProcessMessages;
这段代码使用了ProcessMessages
,因此我不能良心推荐它。如果您想在下载完成时收到通知,而不是像该代码一样轮询,请处理控件的OnNavigateComplete2
事件。请注意,该事件可能会为框架以及主页面触发。
如果您要显示页面,那么您的TWebBrowser
控件无论如何都不应该在单独的线程中,因为它遵循与VCL中使用的任何其他控件相同的规则。如果您只是使用该控件来下载页面,则TWebBrowser
可能过于复杂。您可以使用Indy或操作系统内置的文件下载功能。这些功能可以轻松地在单独的线程中使用。
我需要相同的功能(自动截取页面屏幕截图),然后我开始使用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