-
Здравствуйте. Подскажите как проверить, делаю так вот:
Var Element: OleVariant;
.....
Element:=WebBrowser1.OleObject.document.all.tags('div').namedItem('my_id');
.....
Когда в странице есть хотя бы один тег [div] у которого id="my_id" или name="my_id" - то всё работает как нужно.
Но если таковых нет - функция вылетает в небеса. =(
Руководствуясь этим:
http://msdn.microsoft.com/en-us/library/ms536634(v=vs.85).aspx
метод namedItem() должен: либо вернуть первый из подходящих элементов, либо вернуть NULL.
Пытался проверить на NULL этими функциями: VarIsEmpty(), VarIsNull() - без результатов. =(
-
> Пытался проверить на NULL этими функциями: VarIsEmpty(), VarIsNull() - без результатов. =(
значит не то проверял. VarIsNull при том что возвращается именно он, то что надо...
-
> метод namedItem() должен:
a tags('div') не должен?
-
оой.. Куда-то я кажется в не тот раздел вообще написал.. 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);
ShowMessage(Element.InnerText);
Может в Делфи заголовочник как-то не так что-то? А что тогда делать? =(
-
// Все 3 пишут "false" (в обоих случаях), а если попытаться что-то делать дальше с Element - вылетает в трубу. =(
а та проверь что пишут после каждого... кашу маслом можно испортить.
// ... Например вот это: AV at 0045DE47 ... Read of address 00000000
+ VarToStr
> Может в Делфи заголовочник как-то не так что-то?
начинаешь задаваться такими вопросами, значит нужен ответ на другой "а программирование это мое? не пойти ли в дворники...".
глюки у тебя! в 99,98% случаев, точка. по другому не думай.
-
Ну отчего же? Просто заголовочники у моей D7 древние, много раз приходилось что-то вручную объявлять, некоторое объявлено не так как в оригинальном MSDN, например GradientFill() в D7 слегка через одно место... Ну это другая история уже. =))
Не очень понял что сделать после чего. VarToStr() в первом случае говорит [object], а во втором вылетает на ней с "EVariantTypeCastError -> Could not convert variant of type (Dispatch) into type (String)".
Брутфорс спасёт Мир! © =))
Перепробовал всё что начинается с VarIs - кажется мне нужно проверять по VarIsClear() - во всяком случае тока оно дало "true" на втором случае.
-
> "EVariantTypeCastError -> Could not convert variant of type (Dispatch) into type (String)".
означает что
> метод namedItem() должен: либо вернуть первый из подходящих элементов, либо вернуть NULL.
не правда... иначе хватило бы VarIsNull.
-
А я тут причём? =)
Это в MSDN так написано, я же давал ссыль: «Returns an object or a collection of objects if successful, or null otherwise.»
Ну ладно, сейчас ещё поподробнее потестю, с пристрастием... >:3
Но конструктивные идеи или ссылки приветствуются! =)
-
> я же давал ссыль:
а я говорил
> значит не то проверял.
> Но конструктивные идеи или ссылки приветствуются! =)
ошибка в программе. это самая что ни на есть конструктивная правда жизни. на 99.98%.
-
хм. все методы namedItem любых объектов в MSHTML_TLB возвращают интерфейс. в описанном случае не найдености это нулевой интерфейс, а не null. почему в мсдн написано null... не знаю, может справка не та, для net, или с++ где либо авто приведение типа либо игнорирование, в дельфи есть разница.
сорри, ошибался, дело не в твоей программе. 0,02% тоже бывают.
-
> Edgar_Wine (24.09.12 14:34) [3]
null в Delphi называется nil.
-
> null в Delphi называется nil.
> "EVariantTypeCastError -> Could not convert variant of type (Dispatch) into type (String)".
-
> 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);
> а если попытаться что-то делать дальше с Element - вылетает
> в трубу. =(
> ShowMessage(Element.InnerText);
> at 0045DE47 ... Read of address 00000000
>
> Может в Делфи заголовочник как-то не так что-то? А что тогда
> делать? =(
А что показывает отладчик на Element?
ЗЫ. У коллекции есть InnerText?
-
namedItem() возвращает не коллекцию, а один элемент. Вроде как. =)
У коллекции нету innerText. А нужно ли? =)))
Показывает $00000000, а толку?
хм... VarIsNull() даёт false даже когда переменная вообще не инициализирована. Ну то есть не использовалась ни разу, тока в var написана - видимо компилятор или-кто-там расстарались. =)
Зато VarIsClear() даёт true и когда не инициализирована и когда не найдено ничего в namedItem(). :3
-
> Зато VarIsClear() даёт true
там проверяется как раз на пустой интерфейс.
varEmpty = $0000;
varNull = $0001;
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;
-
> Показывает $00000000, а толку?
Это и есть nil. А "толк" программист знать должен.
-
Говорю же - VarIsNull() даёт false.
>> null в Delphi называется nil.
>> Это и есть nil.
Я знаю! Только попробуйте сделайте проверку на него в if чтоб оно работало. У меня не вышло. =(
Видимо компилятор как-то особо обрабатывает тип OleVariant.
-
If <какаятофигня> <> nil then делаем чë-то с <какаятофигня>
-
Именно так я прежде всего и пробовал:
>> [Error] Incompatible types
-
> Edgar_Wine (30.09.12 05:17) [18]
> Именно так я прежде всего и пробовал:
>
> >> [Error] Incompatible types
>
>
nil соместим с любым ссылочным типом. Есть подозрение, что пора искать программиста.
-
А вы пробовали? Ну и что же здесь неправильно?:
procedure TForm1.Button8Click(Sender: TObject);
var Element: OleVariant;
begin
if Element<>nil then ShowMessage('OK');
end;
>> [Error] Incompatible types
-
> nil соместим с любым ссылочным типом.
вариант не ссылка, он структура 16 байт длинной, а ссылка только 4 байта (в 32 разрядной оси).
+
nil <> null
см.прям тут
sniknik © (29.09.12 11:54)
[14]varEmpty = $0000;
varNull = $0001;
будет портить последовательность.
-
для наглядности, не значение, а структура (иногда включает и значение)
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;
-
Спасибо! =)
В общем через VarIsClear() работает как часы.
-
непонятно только почему
> Пытался проверить на NULL этими функциями: VarIsEmpty(), VarIsNull() - без результатов. =(
"без результатов". т.к.
> Показывает $00000000, а толку?
это оно и есть. а VarIsClear просто "более расширенная" вариация проверки нулевого значения для дополнительных типов... диспатч например, судя по
> "EVariantTypeCastError -> Could not convert variant of type (Dispatch) into type (String)".
должно быть оно... т.е типа $09000000
-
а... отладчик показывает "чисто значение", если не взять по дампу памяти.
-
Ваш пример показал что id == $09000000000000000000000000000000
А отладчик показывает id == $00000000 - он видимо откуда-то из "середины" кусок показывает. Может надо настроить где-то чтоб целиком показывал 16 байт?
-
Для моей поделки на TWebBrowser в принципе хватило условия на VarIsClear(Element), а есть ли смысл подобного (в общем случае)?:
if (VarIsClear(Element) or VarIsEmpty(Element) or VarIsNull(Element)) then
ShowMessage('Error with "Element" #0011001')
else
ShowMessage(Element.innerText);
-
> а есть ли смысл подобного (в общем случае)?:
в общем это вред без смысла, т.к. твое сообщение вообще не информативно, в отличие от ошибки полученной от обращения без проверки...
вон там смори
sniknik © (29.09.12 11:54) [14]
в VarIsClear есть
Result := (VType = varEmpty) or
то же что в VarIsEmpty, т.е дополнительная его проверка бессмысленна. это в частном.
-
Сообщение? Про "#0011001" чтоль? Так это я просто, для примеру, обработка отсутствия так сказать. =)
А с VarIsEmpty это да, оплошал.. Будет думать ещё, спасибо вам огромное!