Форум: "Начинающим";
Текущий архив: 2017.10.22;
Скачать: [xml.tar.bz2];
ВнизTWebBrowser [CommandStateChange] получение перменных. Найти похожие ветки
← →
vegarulez (2015-11-29 11:55) [0]Всем доброго времени суток!
Мастера, подскажите где почитать, или может кто подскажет как правильно и корректно обойти вот такой затык. Есть страничка, которую подгружаю в TWebBrowser. Нужно отслеживать переменные в яваскрипте странички, которые меняются, и зависимости от их значений предпринимать те или иные действия. Я отслеживаю изменения через CommandStateChange - всё работает , но вот в чем проблема - дело в том что пока страничка подгружается это событие происходит несколько раз, до того как переменные в яваскрипте сформируются. Я соотвественно по try except получаю ошибку, что дескать делфин ещё не в знает что это за переменная. И собственно вопрос как правильно запрашивать значение переменных, т.к. через if (Assigned(V.step)) не работает - несоотвествие типов.
Т.е. фактически мне надо сравнить значения в этих переменых, но после того как страница уже загружена и переменные есть.
procedure TFormMain.WebBrowser2CommandStateChange(Sender: TObject;
Command: Integer; Enable: WordBool);
var
document: IHTMLDocument2;
V:olevariant;
s,p:string;
begin
document := WebBrowser2.Document as IHTMLDocument2;
if Assigned(document) then
try
V := WebBrowser2.Document;
V := V.parentWindow;
if (V.step=-1) then
Mainmenu;
except on E:Exception do
Begin
MessageDlg("FM1" +#10#13+ E.Message +#10#13+ inttostr(E.HelpContext), mtWarning,[mbOk], 0);
document.clear;
End;
end;
end;
← →
vegarulez (2015-11-29 11:58) [1]Да забыл написать, опрашиваю значение переменной step
Хотя из кода понятно, но всё же.
← →
vegarulez (2015-11-29 12:01) [2]И забыл ещё описать ошибку exception`a :
FM1
Method "step" not supported by automation object
0
← →
sniknik © (2015-11-30 08:58) [3]> т.к. через if (Assigned(V.step)) не работает - несоотвествие типов.
проверка на nil, а в вебе либо null либо unassigned, и не смотри на Document. типа по аналогии, это часть "внешней" структуры/объекта, а твоя переменная "внутри" (да, выносится "наружу" но as is).
> но после того как страница уже загружена и переменные есть.
это нужно тогда в "докумнеткомплитед"/после делать, а не в смене статуса.
> Method "step" not supported by automation object
нет такого метода, т.е. нет(не найдена) переменной которую можно было бы вынести.
переменная должна быть глобальной.
← →
vegarulez (2015-11-30 19:56) [4]sniknik © >>
>переменная должна быть глобальной.
Так я ее в начале яваскрипта оапределяю. Она же не внутри функции - а значит - глобальная.
var step=0;
>это нужно тогда в "докумнеткомплитед"/после делать, а не в смене статуса.
Дак ведь переменная то меняется в самом яваскрипте на страничке при обработки тех или иных действий пользователя поэтому я должен знать её значение в каждый момент времени. Ведь когда она поменяет значение мне надо будет то или иное действие тут же применить в зависимости от значения этой переменной в яваскрипте. поэтому и опрашиваю ее в секции CommandStateChange, или я не прав???
>проверка на nil, а в вебе либо null либо unassigned
Ок, как ее осуществить??
VarIsNull
VarIsEmpty
пробовал - не получается с ними.
← →
sniknik © (2015-11-30 20:43) [5]> Так я ее в начале яваскрипта оапределяю
а яваскрипт определяется только у сформированного документа.
> поэтому и опрашиваю ее в секции CommandStateChange
честно говоря не помню, и проверять не охота но это смена команд, типа следующая страница/предыдущая... ну когда в обычном браузере стрелки жмешь/новую страницу по ссылке в том же окне отрываешь...
но точно не смена состояний значений переменной в документе, про внутренности внешний объект и не догадывается.
> пробовал - не получается с ними.
опять не помню, но посмотрю завтра на работе, помню определял, и даже комментарий писал на чем "палилось". может там даже не 2 состояния, а три... в общем если найду пример набросаю.
← →
sniknik © (2015-12-01 10:19) [6]для примера использую текущую страницу:
думаю все очевидно. ошибка будет на чтении локальной переменной, но если проверять глобальную gaJsHost вместо search то "прокатит".
procedure TForm1.FormShow(Sender: TObject);
var
url: OleVariant;
begin
url:= "http://delphimaster.net/view/2-1448787318/";
WebBrowser1.Navigate2(url);
end;
procedure TForm1.WebBrowser1DocumentComplete(Sender: TObject; const pDisp: IDispatch; var URL: OleVariant);
var
Document: IHTMLDocument2;
Doc: OleVariant;
function MethodExists(const Disp: IDispatch; const MethodName: WideString): Boolean;
function GetDispID: integer;
begin
Disp.GetIDsOfNames(GUID_NULL, @MethodName, 1, LOCALE_SYSTEM_DEFAULT, @Result);
end;
begin
Result:= GetDispID <> DISPID_UNKNOWN;
end;
function VarIsNullClear(const V: Variant): Boolean;
begin
result:= VarIsNull(V) or VarIsClear(V); //getElementById/..., в IE 7ке возвращает анансигнед, а если установить "использование 8-го" то в XP также а на win-7 почему-то null
//т.е. на всякий случай будем использовать эту функцию
end;
begin
try
Document:= WebBrowser1.Document as IHTMLDocument2;
if not Assigned(Document) then
raise Exception.Create("Document не сформирован");
Doc:= OleVariant(WebBrowser1.Document).parentWindow;
if not MethodExists(Doc, "getCookie") then
raise Exception.Create("Переменной/метода getCookie не существует");
if VarIsNullClear(Doc.search) then
Exception.Create("Переменняа search не инициализирована");
except
on E: Exception do
Application.MessageBox(PChar(E.Message), "Проблема чтения данных Document", MB_OK);
end;
end;
← →
vegarulez (2015-12-03 20:29) [7]Спасибо тебе большое за код. Очень поучительно для меня. Но это немного не то, что мне нужно. У меня переменная должна считываться не в момент когда документ загружен, а в каждый момент времени, так как она меняется. И при загрузке документа надо просто отрезать тот временной интервал пока она ещё не сформирована так как документ не загружен до конца. В твоём коде это как раз блок try. Покурив интернет ещё немного по поводу этого вопроса - нашёл изящное и 100% работающее решение
https://theroadtodelphi.wordpress.com/2011/06/24/using-the-google-maps-api-v3-from-delphi-–-part-iii-getting-the-latitude-and-longitude-of-a-mouse-click/
которое заюзал, делюсь:
//is a valid command?
if TOleEnum(Command) <> CSC_UPDATECOMMANDS then //-1
Exit;
//The page is loaded?
Document := WebBrowser2.Document as IHTMLDocument2;
if not Assigned(Document) then
Exit;
//the page has body?
if not Supports(Document.body, IHTMLElement2, ABody) then
exit;
> sniknik ©
Кстати по ссылке тоже довольно интересный топик про разработку гугл мапс приложения - может быть тебе тоже будет интересно - рекомендую посомтреть. Ещё раз благодарю за код.
← →
sniknik © (2015-12-04 00:42) [8]> нашёл изящное и 100% работающее решение
все что делает этот код, это фактически ждет пока сформируется документ (тело, body, документа это уже внутри него). в общем ты сделал "велосипедный" DocumentComplete.
а то еще и немного позже чем в нем у тебя проверки пройдут, из-за body... проверить конечно надо. сделай "тайминг" - замерь время когда они происходят.
← →
sniknik © (2015-12-04 00:46) [9]+
> изящное и 100% работающее
может оно изящное и работающее но поставленной цели - читать переменную "в каждый момент времени, так как она меняется" не выполняет. такого события объект WebBrowser-а не выдает.
← →
vegarulez (2015-12-04 10:01) [10]>
может я не так выразился - в моменты изменения переменных, внутри загруженной странички, когда пользователь кликает по яваскрипт кнопкам и переходит между формами на страничке и т.д., вообщем при любых действиях.
Документкомплит отрабатывает лишь при загрузки страницы - но не отслеживает изменений переменных в ходе работы с яваскриптом, и переменными, которые в нем изменяются.
← →
vegarulez (2015-12-04 10:03) [11]>
поэтому и использую CommandStateChange защищая себя при загрузки при ещё не инициализированных переменных.
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2017.10.22;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.002 c