Delphi: TWebBrowser в фоновом режиме - PullRequest
3 голосов
/ 12 марта 2009

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

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

Есть предложения?

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

Я думаю, что в целом могу писать темы.

Ответы [ 3 ]

9 голосов
/ 12 марта 2009

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

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

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

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

3 голосов
/ 14 мая 2009

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

После некоторого исследования это сработало:

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/

Здесь были взяты постоянные дельфи-константы: http://www.cryer.co.uk/brian/delphi/twebbrowser/twebbrowser_properties.htm

1 голос
/ 12 марта 2009

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...