2009-03-12 3 views
3

Можно ли загрузить веб-страницу в TWebBrowser в фоновом потоке?Delphi: TWebBrowser в фоновом режиме

Когда приложение загружается, я хочу загрузить страницу из Интернета в TWebBrowser, но я не хочу блокировать gui-thread.

Любые предложения?

Некоторые пояснения:
веб-браузера-компонент живет на форме, и я хочу, чтобы отобразить страницу из Интернета. Но я хочу сделать всю загрузку этой страницы в фоновом потоке, так что загрузка тяжелой страницы не будет блокировать gui-thread.

Я думаю, что я способен писать темы вообще.

ответ

9

TWebBrowser загружает материал в отдельной теме. Ваша программа должна оставаться отзывчивой во время ее загрузки. Вы можете увидеть это, потому что часто картина установить URL, а затем ждать завершения загрузки:

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

Это использует ProcessMessages, поэтому я не могу добросовестно рекомендовать его. Чтобы получить уведомление о завершении загрузки, вместо опроса, подобного этому коду, обработайте событие управления OnNavigateComplete2. Помните, что событие может быть запущено как для фреймов, так и для главной страницы.

Если вы хотите дисплей страницы, а затем ваш TWebBrowser контроль не должен быть в отдельном потоке в любом случае, потому что она подпадает под те же правила, как и любой другой элемент управления, используемого с VCL. Если вы просто используете элемент управления до , загрузите a, тогда TWebBrowser может быть излишним. Вы можете использовать Indy или встроенные функции загрузки файлов операционной системы. Они могут использоваться в отдельных потоках легко.

+0

Это имеет смысл. Мое приложение останавливается на несколько секунд, но, я думаю, я должен найти для этого еще одну причину. – Vegar

+1

Общая идея хорошая. Вам просто нужно использовать ReadyState вместо Busy. См. Мой комментарий для получения дополнительной информации .. –

1

Должен сказать, что я никогда не пробовал что-то подобное, но предполагаю, что у вас возникнут проблемы.

Вы можете иметь несколько потоков в одном процессе, все реализующие петли сообщений и обработку сообщений для окон этого потока, но все окна привязаны к потоку, который их создал. Сообщения Windows всегда будут обрабатываться в потоке, в котором было создано окно. Таким образом, вы можете вызвать метод из встроенного элемента управления TWebBrowser из другого потока, но поскольку это будет связано с отправкой сообщения в окно веб-браузера, они все равно будут обрабатываться в потоке графического интерфейса пользователя.

Для получения дополнительной информации ознакомьтесь с статьей Википедии о Threading in COM и сообщениями блога Раймондом Ченом о STA, например this one.

3

Мне было нужно то же самое (сделать автоматические скриншоты страниц), и я начал с кода Роба. Он не работал на страницах, которые я загружал. В половине случаев флаг занятости не был установлен, а страница еще не была выполнена.

После некоторых исследований, это, казалось, работали:

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/

Константы delphi readystate были взяты fr om здесь: http://www.cryer.co.uk/brian/delphi/twebbrowser/twebbrowser_properties.htm

Смежные вопросы