Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: ActiveX/СОМ/CORBA > TWebBrower перехват JavaScript


Автор: Ищущий! 10.5.2005, 00:32
Есть такая страничка.. Загружается в TWebBrower

Код

<script>
window.close();
</script>


Проблема такая, что выскакивает сообщение, мол хотите закрыть страницу?... Нужно перехватить... или как-нить предотвратить это... можно посредством отключения JavaScript'а, но только для одного конкретного WebBrowera

...

Мож кто поможет smile

Автор: Fantasist 11.5.2005, 17:58
По идее, JavaScript интерпритатор грузиться как COM объект, и соответсвенно ты можешь достать его как минимум через GetActiveObject. Так что для начала я бы поискал инфу об интерпритаторе.

А так вообще проблема интересная. Тут можно подумать. Можно попытаться отлавливать и создание окна. Можно ли отключить на время выполнения JavaScript'a не знаю, тоже можно поискать.


Автор: Ищущий! 11.5.2005, 22:35
Вот бы кто поискал smile

Автор: December 11.5.2005, 22:38
Можно... Только ещё не знаю, как smile Это у меня заплаировано на через 2 недели - будет тот ещё геморрой.
Ищущий!
Можешь посмотреть на реализацию TEmbeddedWB - там есть такая или почти такая фишка, кажется.

Автор: Guest 12.5.2005, 18:23
Как в TWebBrowser определить на какой инпут был произведён клик и как выташить его содержимоё?

Автор: December 13.5.2005, 10:43
Модератор: один топик - один вопрос!

Автор: Girder 13.5.2005, 15:37
Попробуй... например вот так smile :
Код
var
  Form1: TForm1;
  bRes:DWord=0;

implementation

{$R *.dfm}

//...

function ChangeFunc(sDWord:DWord):DWord;
var DLL:DWord;
    fH:Pointer;
    OP:DWord;
    t:DWord;
begin
 Result:=0;
 DLL:=LoadLibrary('user32.dll');
 if DLL<>0 then
  begin
   fH:=GetProcAddress(DLL,'MessageBoxIndirectW');
   if fH<>nil then
    begin
     OP:=OpenProcess(PROCESS_ALL_ACCESS,false,GetCurrentProcessID);
     if OP<>0 then
      begin
       ReadProcessMemory(OP,fH,@Result,4,t);
       WriteProcessMemory(OP,fH,@sDWord,4,t);
       CloseHandle(OP);
      end;
    end;
   FreeLibrary(DLL);
  end;
end;

procedure TForm1.WebBrowser1NavigateComplete2(Sender: TObject;
  const pDisp: IDispatch; var URL: OleVariant);
begin
 bRes:=ChangeFunc($c3c031); //ставим заглушку
end;

procedure TForm1.WebBrowser1DocumentComplete(Sender: TObject;
  const pDisp: IDispatch; var URL: OleVariant);
var i,j,n:integer;
    s,sb,se:string;
begin
 if bRes<>0 then ChangeFunc(bRes); //первые скрипты обработаны и такая заглушка в принципе больше не нужна
 bRes:=0;
 //дальше: пытаемся вырезать из скриптов на странице windows.close();
 if (Webbrowser1.Document<>nil) then
  if IDispatch(Variant(Webbrowser1.Document).scripts)<>nil then
   begin
    i:=Variant(Webbrowser1.Document).scripts.length;
    for j:=0 to i-1 do
     begin
      try
       s:=lowercase(trim(WideString(Variant(Webbrowser1.Document).scripts.item(j).outerHTML)));
       n:=Pos('window.close();',s); //На самом деле может записанна вот так: windows. close () ; и так windows      . close () ; - Мне лень делать на все случаи жизни... :)
       if n<>0 then
        begin
         sb:=Copy(s,1,n-1);
         se:=Copy(s,n+15,Length(s));
         s:=sb+se;
         Variant(Webbrowser1.Document).scripts.item(j).outerHTML:=WideString(s);
        end;
      except
      end;
     end;
   end;
end;
//...


PS: Можно просто засунуть в OnCreate формы только вот енто ChangeFunc($c3c031), а весь остальной код выкинуть(кроме самой конечно функции ChangeFunc)... smile если ты конечно уверен что MessageBoxIndirectW - тебе не нужен.

Автор: Fantasist 13.5.2005, 20:36
Girder

Ай-ай-ай, нехорошо таким хаком заниматься. smile Хотя иногда, конечно, не остается выхода...


Автор: December 14.5.2005, 13:42
Girder
Круто. А поделись секретом, какую литературу надо прочитать, чтобы додуматься до этого метода?

Автор: Girder 14.5.2005, 13:48
December smile 

Автор: Fantasist 14.5.2005, 22:27
December Ну в принципе, перехват API - метод достадочно известный... Только не очень приветсвуемый. smile


Girder, да похоже ты прав. smile То что у меня получилось поискать ни к чему более хорошему не привело. Правда библиотека к этим объектом такая офигительно здаровая, что не уверен, что везде посмотрел. smile

Единственно, что похоже вторая часть (где затираются "windows.close()") не очень нужна - ему вроде не убить скрипт надо, а предотвратить окно. Если ты перехватил функцию создания мессадж бокса, то этого должно быть достадочно. Разве что неплохо бы вместо заглушки написать свою функцию, которая бы анализировала входящие параметры и вызывала бы стандартную (сохраненную) функцию, если этот бокс создает не WebBrowser.


Автор: Girder 17.5.2005, 01:57
Цитата(Fantasist @ 14.5.2005, 23:27)
Girder, да похоже ты прав.
Не... не прав smile. Вот еще... решение накатал smile :
Код
procedure TForm1.WebBrowser1NavigateComplete2(Sender: TObject;
  const pDisp: IDispatch; var URL: OleVariant);
var s:string;
    p:IDispatch;  
begin
 s:='<><script DEFER> window.close=closex; function closex(){}</script>';
 try
  p:=Variant(Webbrowser1.Document).body;
  Variant(p).insertAdjacentHTML(WideString('afterBegin'),WideString(s));
 except
  try
   p:=IDispatch(Variant(Webbrowser1.Document).all.item(0));
   Variant(p).insertAdjacentHTML(WideString('afterBegin'),WideString(s));
  except
  end;
 end;
end;


Срезает: window.close(); ... self.close();

PS: символы: <> перед <script DEFER> удалять не надо... можете например заменить их на <BR> или например так: s:=#255+'<script DEFER> window.close=closex; function closex(){}</script>'; хоть любой HTML элемент - но только не заменяйте на пробельных символы!... так как в ентом случаи скрипт не выполнится - как следствие работать код не будет.

Удачи.

Автор: Fantasist 17.5.2005, 10:20
Цитата(Girder @ 16.5.2005, 22:57)
Не... не прав


Ты же говорил, что NavigateComplete2 выполняется после исполнения скриптов в global scope.

Цитата(Girder @ 16.5.2005, 22:57)
Срезает: window.close(); ... self.close();



Так постановка задачи была все-таки подавить окно с сообщением, а не саму функцию. smile

Автор: Girder 17.5.2005, 10:36
Цитата(Fantasist @ 17.5.2005, 11:20)
Ты же говорил, что NavigateComplete2 выполняется после исполнения скриптов в global scope.
Не-а... сразу после(наверное... мы друг-друга не поняли smile ) - Но! до любого другого события, которое мы можем использовать от TWebBrowser. А предотвратить их исполнение(в NavigateComplete2)... без вот ентого кода(тот что выше... ни как неполучалось) - так как если просто даже на данном этапе считатать из outerHTML и без изменения записать в outerHTML - то на данной страницы выполнение всех скриптов - слетало! А "первичные скрипты"... все равно могли быть выполнены - если они "разбиты", т.е. "<script...></script>...<script...></script>" - т.к. в данном событии может быть доступен только самый первый скрипт(т.е. "<script...></script>") на странице!

Цитата(Fantasist @ 17.5.2005, 11:20)
Так постановка задачи была все-таки подавить окно с сообщением, а не саму функцию.
А мы её... переопределили smile. Как следствии попытка выполнения window.close() - перебросит в нашу функцию closex... а она ни чего не делает smile PS: Короче подавили... в зародыше smile (для javascript smile )

Автор: Fantasist 17.5.2005, 18:28
Цитата(Girder @ 17.5.2005, 07:36)
А мы её... переопределили smile. Как следствии попытка выполнения window.close() - перебросит в нашу функцию closex... а она ни чего не делает


Так я про это и говорю. Мне просто показалось, что требовалось подавить сообщение, но сама функциональность должна была остаться (то есть окно должно было закрыться), однако перечитав первое сообщение, понял, что был не прав.


Цитата(Girder @ 16.5.2005, 22:57)
Не... не прав smile. Вот еще... решение накатал smile :


Ну так, я же говорил, что в этом браузере такая куча интерфейсов, что что-нибудь должно помочь. smile Молодец.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)