Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

TWebBrowser [CommandStateChange] получение перменных. [D7, XP]


vegarulez ©   (2015-11-29 11:55:00) 

Всем доброго времени суток!
Мастера, подскажите где почитать, или может кто подскажет как правильно и корректно обойти вот такой затык. Есть страничка, которую подгружаю в 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-12-04 10:03:00) [1]

>
поэтому и использую CommandStateChange защищая себя при загрузки при ещё не инициализированных переменных.


vegarulez   (2015-12-04 10:01:00) [2]

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

Документкомплит отрабатывает лишь при загрузки страницы - но не отслеживает изменений переменных в ходе работы с яваскриптом, и переменными, которые в нем изменяются.


sniknik   (2015-12-04 00:46:00) [3]

+
> изящное и 100% работающее
может оно изящное и работающее но поставленной цели - читать переменную "в каждый момент времени, так как она меняется" не выполняет. такого события объект  WebBrowser-а не выдает.


sniknik   (2015-12-04 00:42:00) [4]

> нашёл изящное и 100% работающее решение
все что делает этот код, это фактически ждет пока сформируется документ (тело, body, документа это уже внутри него). в общем ты сделал "велосипедный" DocumentComplete.
а то еще и немного позже чем в нем у тебя проверки пройдут, из-за body... проверить конечно надо. сделай "тайминг" - замерь время когда они происходят.


vegarulez   (2015-12-03 20:29:00) [5]

Спасибо тебе большое за код. Очень поучительно для меня. Но это немного не то, что мне нужно. У меня переменная должна считываться не в момент когда документ загружен, а в каждый момент времени, так как она меняется. И при загрузке документа надо просто отрезать тот временной интервал пока она ещё не сформирована так как документ не загружен до конца. В твоём коде это как раз блок 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-01 10:19:00) [6]

для примера использую текущую страницу:
думаю все очевидно. ошибка будет на чтении локальной переменной, но если проверять глобальную gaJsHost вместо search то "прокатит".

procedure TForm1.FormShow(Sender: TObject);
var
 url: OleVariant;
begin
 url:= ' http://delphimaster.ru/cgi-bin/forum.pl?id=1448787318&n=18';
 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;


sniknik   (2015-11-30 20:43:00) [7]

> Так я ее в начале яваскрипта оапределяю
а яваскрипт определяется только у сформированного документа.

> поэтому и опрашиваю ее в секции CommandStateChange
честно говоря не помню, и проверять не охота но это смена команд, типа следующая страница/предыдущая... ну когда в обычном браузере стрелки жмешь/новую страницу по ссылке в том же окне отрываешь...
но точно не смена состояний значений переменной в документе, про внутренности внешний объект и не догадывается.

> пробовал - не получается с ними.
опять не помню, но посмотрю завтра на работе, помню определял, и даже комментарий писал на чем "палилось". может там даже не 2 состояния, а три... в общем если найду пример набросаю.


vegarulez   (2015-11-30 19:56:00) [8]

sniknik ©  >>

>переменная должна быть глобальной.
Так я ее в начале яваскрипта оапределяю. Она же не внутри функции - а значит - глобальная.
var step=0;

>это нужно тогда в "докумнеткомплитед"/после делать, а не в смене статуса.
Дак ведь переменная то меняется в самом яваскрипте на страничке при обработки тех или иных действий пользователя  поэтому я должен знать её значение в каждый момент времени. Ведь когда она поменяет значение мне надо будет то или иное действие тут же применить в зависимости от значения этой переменной в яваскрипте. поэтому и опрашиваю ее в секции CommandStateChange, или я не прав???

>проверка на nil, а в вебе либо null либо unassigned
Ок, как ее осуществить??
VarIsNull
VarIsEmpty
пробовал - не получается с ними.


sniknik   (2015-11-30 08:58:00) [9]

> т.к. через if (Assigned(V.step)) не работает - несоотвествие типов.
проверка на nil, а в вебе либо null либо unassigned, и не смотри на Document. типа по аналогии, это часть "внешней" структуры/объекта, а твоя переменная "внутри" (да, выносится "наружу" но as is).

> но после того как страница уже загружена и переменные есть.
это нужно тогда в "докумнеткомплитед"/после делать, а не в смене статуса.

> Method 'step' not supported by automation object
нет такого метода, т.е. нет(не найдена) переменной которую можно было бы вынести.
переменная должна быть глобальной.


vegarulez   (2015-11-29 12:01:00) [10]

И забыл ещё описать ошибку exception`a  :

FM1
Method 'step' not supported by automation object
0


vegarulez   (2015-11-29 11:58:00) [11]

Да забыл написать, опрашиваю значение переменной step
Хотя из кода понятно, но всё же.


Наверх

Титульная страница Поиск, карта сайта Написать письмо