Мастера DELPHI, Delphi programming community Рейтинг@Mail.ru Титульная страница Поиск, карта сайта Написать письмо 
| Новости |
Новости сайта
Поиск |
Поиск по лучшим сайтам о Delphi
FAQ |
Огромная база часто задаваемых вопросов и, конечно же, ответы к ним ;)
Статьи |
Подборка статей на самые разные темы. Все о DELPHI
Книги |
Новинки книжного рынка
Новости VCL
Обзор свежих компонент со всего мира, по-русски!
|
| Форумы
Здесь вы можете задать свой вопрос и наверняка получите ответ
| ЧАТ |
Место для общения :)
Орешник |
Коллекция курьезных вопросов из форумов
KOL и MCK |
KOL и MCK - Компактные программы на Delphi
Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / rsdn.org

 
Чтобы не потерять эту дискуссию, сделайте закладку « предыдущая ветвь | форум | следующая ветвь »

TWebBrowser -> OleObject - проверить является ли элемент NULL [Delphi, Windows]


Edgar_Wine   (24.09.12 08:43

Здравствуйте. Подскажите как проверить, делаю так вот:

Var Element: OleVariant;
.....
Element:=WebBrowser1.OleObject.document.all.tags('div').namedItem('my_id');
// работа с Element
.....


Когда в странице есть хотя бы один тег [div] у которого id="my_id" или name="my_id" - то всё работает как нужно.
Но если таковых нет - функция вылетает в небеса. =(

Руководствуясь этим: http://msdn.microsoft.com/en-us/library/ms536634(v=vs.85).aspx
метод namedItem() должен: либо вернуть первый из подходящих элементов, либо вернуть NULL.

Пытался проверить на NULL этими функциями: VarIsEmpty(), VarIsNull() - без результатов. =(


sniknik ©   (24.09.12 13:50[1]

> Пытался проверить на NULL этими функциями: VarIsEmpty(), VarIsNull() - без результатов. =(
значит не то проверял. VarIsNull при том что возвращается именно он, то что надо...


sniknik ©   (24.09.12 13:51[2]

> метод namedItem() должен:
a tags('div') не должен?


Edgar_Wine   (24.09.12 14:34[3]

оой.. Куда-то я кажется в не тот раздел вообще написал.. 2 суток без сна.. Тока теперь подремав понял, простите.. =((

ну... В том конкретном случае у меня там были ещё div, так что вылетало точно не там. хмм. Надо проверить что будет если вообще нет div, спасибо. =)

Msg:='|';
Element:=WebBrowser1.OleObject.document.all.tags('DIV').namedItem('test');
if VarIsNull(Element) then Msg:=Msg+'true|' else Msg:=Msg+'false|';
if VarIsEmpty(Element) then Msg:=Msg+'true|' else Msg:=Msg+'false|';
if VarIsError(Element) then Msg:=Msg+'true|' else Msg:=Msg+'false|';
ShowMessage(Msg); // Все 3 пишут "false" (в обоих случаях), а если попытаться что-то делать дальше с Element - вылетает в трубу. =(
ShowMessage(Element.InnerText); // Например вот это: AV at 0045DE47 ... Read of address 00000000


Может в Делфи заголовочник как-то не так что-то? А что тогда делать? =(


sniknik ©   (24.09.12 16:21[4]

// Все 3 пишут "false" (в обоих случаях), а если попытаться что-то делать дальше с Element - вылетает в трубу. =(
а та проверь что пишут после каждого... кашу маслом можно испортить.

// ... Например вот это: AV at 0045DE47 ... Read of address 00000000
+ VarToStr

> Может в Делфи заголовочник как-то не так что-то?
начинаешь задаваться такими вопросами, значит нужен ответ на другой "а программирование это мое? не пойти ли в дворники...".
глюки у тебя! в 99,98% случаев, точка. по другому не думай.


Edgar_Wine   (24.09.12 17:08[5]

Ну отчего же? Просто заголовочники у моей D7 древние, много раз приходилось что-то вручную объявлять, некоторое объявлено не так как в оригинальном MSDN, например GradientFill() в D7 слегка через одно место... Ну это другая история уже. =))

Не очень понял что сделать после чего. VarToStr() в первом случае говорит [object], а во втором вылетает на ней с "EVariantTypeCastError -> Could not convert variant of type (Dispatch) into type (String)".

Брутфорс спасёт Мир! © =))
Перепробовал всё что начинается с VarIs - кажется мне нужно проверять по VarIsClear() - во всяком случае тока оно дало "true" на втором случае.


sniknik ©   (24.09.12 17:19[6]

> "EVariantTypeCastError -> Could not convert variant of type (Dispatch) into type (String)".
означает что
> метод namedItem() должен: либо вернуть первый из подходящих элементов, либо вернуть NULL.
не правда... иначе хватило бы VarIsNull.


Edgar_Wine   (24.09.12 20:24[7]

А я тут причём? =)
Это в MSDN так написано, я же давал ссыль: «Returns an object or a collection of objects if successful, or null otherwise.»

Ну ладно, сейчас ещё поподробнее потестю, с пристрастием... >:3
Но конструктивные идеи или ссылки приветствуются! =)


sniknik ©   (25.09.12 00:44[8]

> я же давал ссыль:
а я говорил
> значит не то проверял.

> Но конструктивные идеи или ссылки приветствуются! =)
ошибка в программе. это самая что ни на есть конструктивная правда жизни. на 99.98%.


sniknik ©   (25.09.12 08:03[9]

хм. все методы namedItem любых объектов в MSHTML_TLB возвращают интерфейс. в описанном случае не найдености это нулевой интерфейс, а не null. почему в мсдн написано null... не знаю, может справка не та, для net, или с++ где либо авто приведение типа либо игнорирование, в дельфи есть разница.

сорри, ошибался, дело не в твоей программе. 0,02% тоже бывают.


Плохиш ©   (26.09.12 00:06[10]


> Edgar_Wine   (24.09.12 14:34) [3]

null в Delphi называется nil.


sniknik ©   (26.09.12 07:45[11]

> null в Delphi называется nil.
> "EVariantTypeCastError -> Could not convert variant of type (Dispatch) into type (String)".


cobalt ©   (28.09.12 14:31[12]


> Msg:='|';
> Element:=WebBrowser1.OleObject.document.all.tags('DIV').
> namedItem('test');
> if VarIsNull(Element) then Msg:=Msg+'true|' else Msg:=Msg+'false|';
>
> if VarIsEmpty(Element) then Msg:=Msg+'true|' else Msg:=Msg+'false|';
>
> if VarIsError(Element) then Msg:=Msg+'true|' else Msg:=Msg+'false|';
>
> ShowMessage(Msg); // Все 3 пишут "false" (в обоих случаях),
>  а если попытаться что-то делать дальше с Element - вылетает
> в трубу. =(
> ShowMessage(Element.InnerText); // Например вот это: AV
> at 0045DE47 ... Read of address 00000000

>
> Может в Делфи заголовочник как-то не так что-то? А что тогда
> делать? =(

А что показывает отладчик на Element?

ЗЫ. У коллекции есть InnerText?


Edgar_Wine   (29.09.12 02:17[13]

namedItem() возвращает не коллекцию, а один элемент. Вроде как. =)
У коллекции нету innerText. А нужно ли? =)))

Показывает $00000000, а толку?

хм... VarIsNull() даёт false даже когда переменная вообще не инициализирована. Ну то есть не использовалась ни разу, тока в var написана - видимо компилятор или-кто-там расстарались. =)
Зато VarIsClear() даёт true и когда не инициализирована и когда не найдено ничего в namedItem(). :3


sniknik ©   (29.09.12 11:54[14]

> Зато VarIsClear() даёт true
там проверяется как раз на пустой интерфейс.

varEmpty    = $0000; { vt_empty        0 }
varNull     = $0001; { vt_null         1 }

function VarIsNull(const V: Variant): Boolean;
begin
 Result := FindVarData(V)^.VType = varNull;
end;

function VarIsClear(const V: Variant): Boolean;
var
 LHandler: TCustomVariantType;
 LVarData: TVarData;
begin
 LVarData := FindVarData(V)^;
 with LVarData do
   if VType < CFirstUserType then
     Result := (VType = varEmpty) or
               (((VType = varDispatch) or (VType = varUnknown)) and
                 (VDispatch = nil))
   else if FindCustomVariantType(VType, LHandler) then
     Result := LHandler.IsClear(LVarData)
   else
     Result := False;
end;


Плохиш ©   (29.09.12 16:01[15]


> Показывает $00000000, а толку?

Это и есть nil. А "толк" программист знать должен.


Edgar_Wine   (30.09.12 02:09[16]

Говорю же - VarIsNull() даёт false.

>> null в Delphi называется nil.
>> Это и есть nil.

Я знаю! Только попробуйте сделайте проверку на него в if чтоб оно работало. У меня не вышло. =(
Видимо компилятор как-то особо обрабатывает тип OleVariant.


Плохиш ©   (30.09.12 04:37[17]

If <какаятофигня> <> nil then делаем чë-то с <какаятофигня>


Edgar_Wine   (30.09.12 05:17[18]

Именно так я прежде всего и пробовал:

>> [Error] Incompatible types


Плохиш ©   (30.09.12 11:33[19]


> Edgar_Wine   (30.09.12 05:17) [18]
> Именно так я прежде всего и пробовал:
>
> >> [Error] Incompatible types
>
>

nil соместим с любым ссылочным типом. Есть подозрение, что пора искать программиста.


Edgar_Wine   (01.10.12 05:56[20]

А вы пробовали? Ну и что же здесь неправильно?:

procedure TForm1.Button8Click(Sender: TObject);
var Element: OleVariant;
begin
if Element<>nil then ShowMessage('OK');
end;



>> [Error] Incompatible types


sniknik ©   (01.10.12 09:43[21]

> nil соместим с любым ссылочным типом.
вариант не ссылка, он структура 16 байт длинной, а ссылка только 4 байта (в 32 разрядной оси).

+
nil <> null
см.прям тут
sniknik ©   (29.09.12 11:54) [14]
varEmpty    = $0000; { vt_empty        0 }
varNull     = $0001; { vt_null         1 }

будет портить последовательность.


sniknik ©   (01.10.12 10:12[22]

для наглядности, не значение, а структура (иногда включает и значение)
procedure TForm1.Button1Click(Sender: TObject);
var
 v, iv, id: Variant;
 i: IUnknown;
 d: IDispatch;

 function VarStrucToStr(v: Variant): string;
 begin
   result:= StringOfChar('@', 32);
   BinToHex(@v, @result[1], 16);
 end;

begin
 iv:= i;
 id:= d;
 ShowMessage('Empty - '+VarStrucToStr(v)+' Null - '+VarStrucToStr(Null)+' IUnknown - '+VarStrucToStr(iv)+' IDispatch - '+VarStrucToStr(id)+#13#10+
             'Byte - '+VarStrucToStr(5)+' ShortInt - '+VarStrucToStr(-5)+' ...');
end;


Edgar_Wine   (01.10.12 21:40[23]

Спасибо! =)
В общем через VarIsClear() работает как часы.


sniknik ©   (01.10.12 22:02[24]

непонятно только почему
> Пытался проверить на NULL этими функциями: VarIsEmpty(), VarIsNull() - без результатов. =(
"без результатов". т.к.
> Показывает $00000000, а толку?
это оно и есть. а VarIsClear просто "более расширенная" вариация проверки нулевого значения для дополнительных типов... диспатч например, судя по
> "EVariantTypeCastError -> Could not convert variant of type (Dispatch) into type (String)".
должно быть оно... т.е типа $09000000


sniknik ©   (01.10.12 22:09[25]

а... отладчик показывает "чисто значение", если не взять по дампу памяти.


Edgar_Wine   (02.10.12 01:49[26]

Ваш пример показал что id == $09000000000000000000000000000000
А отладчик показывает id == $00000000 - он видимо откуда-то из "середины" кусок показывает. Может надо настроить где-то чтоб целиком показывал 16 байт?


Edgar_Wine   (02.10.12 02:19[27]

Для моей поделки на TWebBrowser в принципе хватило условия на VarIsClear(Element), а есть ли смысл подобного (в общем случае)?:

if (VarIsClear(Element) or VarIsEmpty(Element) or VarIsNull(Element)) then
     ShowMessage('Error with "Element" #0011001')
else
     ShowMessage(Element.innerText);


sniknik ©   (02.10.12 07:49[28]

> а есть ли смысл подобного (в общем случае)?:
в общем это вред без смысла, т.к. твое сообщение вообще не информативно, в отличие от ошибки полученной от обращения без проверки...

вон там смори
sniknik ©   (29.09.12 11:54) [14]
в VarIsClear есть
Result := (VType = varEmpty) or
то же что в VarIsEmpty, т.е дополнительная его проверка бессмысленна. это в частном.


Edgar_Wine   (03.10.12 16:09[29]

Сообщение? Про "#0011001" чтоль? Так это я просто, для примеру, обработка отсутствия так сказать. =)
А с VarIsEmpty это да, оплошал.. Будет думать ещё, спасибо вам огромное!


версия для печати

Написать ответ

Ваше имя (регистрация  E-mail 







Разрешается использование тегов форматирования текста:
<b>жирный</b> <i>наклонный</i> <u>подчеркнутый</u>,
а для выделения текста программ, используйте <code> ... </code>
и не забывайте закрывать теги! </b></i></u></code> :)


Наверх

  Рейтинг@Mail.ru     Титульная страница Поиск, карта сайта Написать письмо