Поиск по блогу

понедельник, 6 апреля 2009 г.

Как установить фокус на TWebBrowser (SetFocus не работает)

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

Как правило, при написании приложений всплывают какие-нибудь специфические вопросы. Эти вопросы легко решить с помощью интернета :) Вот, например, недавно, при отладке очередной программы обратила внимание, что не работает SetFocus применительно к объекту WebBrowser. Погуглила, нашла решение (даже 2).


{1}

uses
ActiveX;

begin
WebBrowser1.Navigate('irgendeinedatei.html');
with WebBrowser1 do
if Document <> nil then
with Application as IOleobject do
DoVerb(OLEIVERB_UIACTIVATE, nil, WebBrowser1, 0, Handle,
GetClientRect);
end;

{2}

uses
MSHTML;

begin
WebBrowser1.Navigate('irgendeinedatei.html');
repeat
Application.ProcessMessages;
until WebBrowser1.ReadyState >= READYSTATE_COMPLETE;
if WebBrowser1.Document <> nil then
(Webbrowser1.Document as IHTMLDocument2).ParentWindow.Focus;
end;


Выбрала второе, так как оно показалось мне более простым :) Однако, в нем обнаружился недостаток, который, видимо, не на всех формах можно обнаружить. У меня на форме в верхней части расположен грид, а в нижней - WebBrowser.

TWebBrowser setfocus

После установления фокуса на WebBrowser начинаю скроллить мышь над ним. Все идет гладко до тех пор, пока не достигается конец (или начало — в зависимости от того, в какую сторону скроллить) документа. После этого начинает скроллиться грид, который расположен над документом. Использование варианта под номером {1} устранило этот недочет.

Чтобы быть в курсе обновлений блога, можно подписаться на RSS.

Статьи схожей тематики:



12 комментариев:

  1. Хм...интересное решение, надо попробовать. Сорри за оффтоп, но раз пошла речь об этом компоненте, то может подскажете решение такой проблемы: у WebBrowser никак не хочет работать свойство Visible - компонент всегда остается видимым. Можно было бы использовать рекомендации в вашей статье про DOM, но c WebBrowser как-то роднее :) Может подскажете как спрятать компонент с глаз долой?

    ОтветитьУдалить
  2. Visible у WebBrowser-а не работает. У него есть только методы Hide и Show. Но когда он спрятан хайдом — с ним нельзя работать, так что эта ситуация не подходит.

    Если надо поработать с HTML — лучше все-таки использовать DOM. Как вариант, можно динамически создавать WebBrowser и сразу его уничтожать.

    Или еще, первое, что приходит в голову, — на OnCreate формы повесить:

    WebBrowser.Height := 0;
    WebBrowser.Width := 0;

    Но все это, конечно, будет финтом ушами :)

    ОтветитьУдалить
  3. Хы-хы)) Последний вариант улыбнул не по-деццки :) А вот про вариант с динамическим созданием я что-то как-то и не подумал сразу. Спасибо большое за совет. Буду пробовать

    ОтветитьУдалить
  4. А можно вопрос по поводу вот этого куска кода:
    repeat
    Application.ProcessMessages;
    until WebBrowser1.ReadyState >= READYSTATE_COMPLETE;

    С ним проблем не бывает? У меня при обработке списка урлов переодически IE клинит и в этом цикле всё зависает, всмысле никакой сетевой активности уже нет, загрузить он ничего не пытается, но READYSTATE_COMPLETE не наступает. Я пока лечу это вызовом руками Refresh в компоненте. Может есть какой-то цивилизованный способ борьбы с этим? Или это какая-то частная проблема у меня?

    ОтветитьУдалить
  5. Ziavra, этот код я скопировала из инета "как есть", я из него брала для себя только установление фокуса :) А идентификация окончания загрузки в TWebBrowser-е уже как-то обсуждалась на блоге. Почитай http://www.blogok.ru/2009/01/09/readystate-in-twebbrowser/ - может, поможет :)
    Голый until использовать тут неправильно, надо, хотя бы, предусмотреть, что загрузка может не произойти, и ограничить время ожидания.

    ОтветитьУдалить
  6. Я помню, что видел где-то эту ссылку, искал в постах и с первого раза найти не смог. Спасибо. Насчет таймаута-то понятно, просто я думал может пропустил чего про этот ReadyState и IE сам умеет всё обрабатывать, а оказалось всё как обычно. :-)

    ОтветитьУдалить
  7. У меня в почти точно таком же приложении, как Ваше (TwebBrowser и два DevExpress грида) другая проблема - наоборот :) Если вручную (мышкой) "сфокусироваться" на WebBrowser, то грид потом перестает реагировать на клавиатуру. Мышкой щелкать - сколько угодно, а стрелками - фиг. НО!, если кликнуть мышкой на один грид, потом на другой, все становится нормально... до тех пор, пока не кликнуть на WebBrowser.

    ОтветитьУдалить
  8. Насчет READYSTATE_COMPLETE, конечно способ правильный, но WB порой с ним глючит, причем это касается не только ваших сохраненных страниц, но и страниц в инете. Очень часто попадаются страницы в которых полная загрузка не наступает НИКОГДА! (это касается java скриптов в реальном времени). Обход этому - другое состояние WB. Например:
    while WebBrowser1.ReadyState = 1 do
    begin
    Sleep(100);
    Application.ProcessMessages;
    end;

    При этом изменения ReadyState легко отследить ShowMessage'м.

    Да, и насколько я помню WebBrowser.SetFocus работает. По крайней мере доступ к OLE при фокусе осуществляется даже при переключении между двух WB)))

    ОтветитьУдалить
  9. Просто хочу поблагодарить за то что собрали полезную информацию в одном месте и перевели :) Сейчас занимался вопросами связанными с TWebBrowser, INDY и всё что нужно нашёл в вашем блоге.
    Алексей.

    ОтветитьУдалить
  10. ваш блог, очень удачное учебное пособие часто предлагаю своим сотрудникам, чтобы они там изучали грабли (к сожелению я сам не могу похвастаться ясностью изложения),
    Я понимаю, что ползу немного не туда, точнее совсем не туда.

    Вопрос ТWebBrowser (точнее активекомпанент) это, самое быстрое в Windows для освоения решение для отображении HTML содержимого?

    ОтветитьУдалить
  11. Анонимный, ну просто он стандартный, поэтому им и пользуются. Я вообще TWebBrowser-ом пользуюсь крайне редко, альтернативы не искала :)

    Спасибо за внимание к блогу ;)

    ОтветитьУдалить
  12. Понравился первый способ активации WebBrowser-а. Вот ещё вопрос: как выделить весь текст и удалить его? Браузер при этом находится в режиме правки

    ОтветитьУдалить

Комментарии модерируются, вопросы не по теме удаляются, троллинг тоже.

К сожалению, у меня нет столько свободного времени, чтобы отвечать на все частные вопросы, так что, может, свой вопрос лучше задать на каком-нибудь форуме?

Поделиться