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

вторник, 27 апреля 2010 г.

Работа с комбобоксами (SELECT) в TWebbrowser

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

1. TWebBrowser, OleObject и его свойства.
2. Работа с формами в TWebBrowser.

Обычно я делаю так: сначала ищу на форме нужный селект по имени (тип искомого объекта - IHTMLSelectElement (не забудьте подключить библиотеку MSHTML)). Селект можно находить по id или по name, в зависимости от требований. Вот пример функции, возращающей требуемый элемент (проверяется и по id, и по name):

function FindCBByName(CBName: String) : IHTMLSelectElement;

function TMainF.FindCBByName(CBName: String): IHTMLSelectElement;
var
i : integer;
DocSelect : IHTMLElementCollection;
DocElement : IHtmlElement;
Doc : IHTMLDocument2;
begin
Result := nil;
WB.Document.QueryInterface(IHTMLDocument2, Doc);
DocSelect := Doc.all.tags('SELECT') as IHTMLElementCollection;

for i := 0 to DocSelect.length-1 do
begin
DocElement := DocSelect.Item(i, 0) as IHtmlElement;
if (UpperCase(DocElement.id) = UpperCase( CBName )) or
(UpperCase(DocElement.getAttribute('name',0)) = UpperCase( CBName )) then
begin
Result := DocElement as IHTMLSelectElement;
exit;
end;
end;
end;


В случае, если объект не найден, возвращается nil. В данном примере у меня привязка к объекту TWebBrowser (WB) на форме. Можно избавиться от нее, добавив TWebBrowser в качестве параметра функции (я так обычно и делаю).

Когда элемент найден, в нем надо будет выбрать значение. В зависимости от задачи, требуется обычно выбрать option по тексту или по value.

В качестве примера привожу процедурку, которая уже "светилась" в статьях на этом блоге.

procedure SelectItemByTextFromSelectEl (TextStr : string;
SelectEl : IHTMLSelectElement; var vSelected : boolean); // выбор оптионза по тексту из селекта


Код:
procedure TEmailF.SelectItemByTextFromSelectEl(TextStr: string;
SelectEl: IHTMLSelectElement; var vSelected : boolean);
var
i, t : integer;
iDisp : IDispatch;
iColl : IHTMLElementCollection;
iOption : IHTMLOptionElement;
begin
iDisp := SelectEl.tags('OPTION');
iDisp.QueryInterface(IHTMLElementCollection, iColl);
if not Assigned(iColl) then
begin
// sLog('log.txt','Not assigned!');
exit;
end;

i := 0;
while i <= iColl.length-1 do
begin
iDisp := iColl.item(i,0);
iDisp.QueryInterface(IHTMLOptionElement, iOption);
if Assigned(iOption) then
begin
if iOption.text = TextStr then
begin
iOption.selected := true;
vSelected := true;
break;
end;
end;
inc(i);
end;
end;


Переменная vSelected становится равной true, если выбор сделан успешно. Если нужен выбор по value, процедура будет аналогичной, изменится лишь одна строка

if iOption.text = TextStr then

на
if iOption.value = ValueStr then

Можно сделать и универсальную процедуру, в которую в качестве параметра передавать, по чему искать - по тексту или по value. Обычно я использую еще более апгрейженную процедуру, в которую передаю, например, какой джаваскрипт выполнить после осуществления выбора.

Закрепляем материал. Пример применения:

option select twebbrowser
var
SelectQuest : IHTMLSelectElement;
vQSelected, vQSelected2 : boolean;

...

SelectQuest := FindCBByName('hintq');
if (Assigned(SelectQuest)) then
begin
vQSelected := false;
// пытаемся выбрать вопрос по умолчанию
SelectItemByTextFromSelectEl( teQUEST.Text, SelectQuest, vQSelected);
// если вопрос удачно выбран, то вводим ответ
if (vQSelected) then
begin
// ShowMessage('Вопрос был в стандартных');
// разные действия
end
else // если вопроса нет в стандартных, выбираем свой вопрос
begin
// ShowMessage('Вопроса не было в стандартных');
vQSelected2 := false;
SelectItemByValueFromSelectEl('99', SelectQuest, vQSelected2);
// разные действия
end;
end;

...

___

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

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



2 комментария:

  1. Маша а как вы боретесь с учтечками памяти при работе с ИЕ? каждый навигейт, каждая работа с хтмлелементами потихоньку течет...

    ОтветитьУдалить
  2. Для меня это больной вопрос :( Пока ответа не нашла.

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

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

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

Поделиться