Тем, для кого этот материал вновинку, сначала советую ознакомиться со статьями:
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. Обычно я использую еще более апгрейженную процедуру, в которую передаю, например, какой джаваскрипт выполнить после осуществления выбора.
Закрепляем материал. Пример применения:

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.
Маша а как вы боретесь с учтечками памяти при работе с ИЕ? каждый навигейт, каждая работа с хтмлелементами потихоньку течет...
ОтветитьУдалитьДля меня это больной вопрос :( Пока ответа не нашла.
ОтветитьУдалить