Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.03.10;
Скачать: CL | DM;

Вниз

Ошибка сценария в TWebBrowser.   Найти похожие ветки 

 
crash123   (2003-01-18 16:48) [0]

Я использую компоненту TWebBrowser. Встала проблема избаиться от окна "Ошибка сценария Internet Explorer". Оно появляется на многих сайтах в которых есть ошибки в JAVA скриптах. Версия IE - 5.0.
Помогите пожалуйста!


 
Ihor Osov'yak ©   (2003-01-18 22:42) [1]


Есть ошибка - значит будет сообщение об ошибке :-).

Зы - если кто-то посоветует Silent установить в true - не слушай его. Ибо в первых, Silent не все сообщения перехватывает - о твоем случае не знаю, нужно экспериментировать. Но проблема не в том – если даже это заблокирует сообщение об ошибке – то это будет равнозначно ответу “не выполнять скрипты более”. А как показывает опыт – сейчас очень модно на всякие линки и кнопки скрипты вешать – следовательно, броузер соотв. клики уже не будет обрабатывать. Со всеми вытекающими последствиями.

Юзание IDOCHOSTSHOWUI (пример реализации смотрим в TEmbeddedWB) тоже вряд ли (когда-то делал эксперименты – сообщения об ошибках здесь тоже не ловятся – но могу ошибиться за древностью – проверьте, если есть желанию).

Делаю так – немного в лоб, но работает наверняка (IE от 5, все винды)

- хук на создание окна для своего потока.
- в хуке смотрим класс окна, если это Internet Explorer_Server - вполне может быть, что это окно с сообщением об ошибке. Тогда – PostMessage на взвод таймера примерно на 0.1 сек – єто нужно для того, что в соотв. окне еще ничего нет. По срабатыванию таймера запрашиваем IHtmlDocument2 от соотв. хидера окна – как это сделать, здесь уже говорили, поищи по ключевым словам ObjectFromLresult,IHtmlDocument2

- парсим соотв. IHtmlDocument2, и если там есть бутончик, в html коде которого есть id=btnYes, то кликаем по нему. Иначе – просто прибываем


 
crash123   (2003-01-19 10:29) [2]

Уважаемый Ihor Osov"yak, если Вас не затруднит, напишите исходный код. Заранее спосибо!


 
Ihor Osov'yak ©   (2003-01-19 11:31) [3]

Держи фрагменты, выдернуто с реального проекта, убраны некоторые несущественные детали, но может и не все, посему некоторые фрагменты "будут лишними", также не даю кода всякой мелочовки вида WrTm - это у меня отладочный вывод:


function GetWndClassName(aWnd:THandle):string;
var wS:string;
l:integer;
begin
SetLength(ws,160);
l:=GetClassName(aWnd,PChar(ws),length(ws));
if length(ws)>0
then Result := Copy(ws,1,l)
else Result := "";
SetLength(ws,0);
end;



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

При юзании только для своего процесса
оформлять в виде длл необязательно:


function Kah_hook(Code:integer; aWParam:WPARAM; aLParam:LParam{var _Msg: TMsg}):longint; stdcall;
var wnd: dword;


begin

wnd :=aWParam;
fl:= 0;
if code <0 then begin
Result := CallNextHookEx(HookHandle, Code, aWParam, aLParam {Longint(@_Msg)});
Exit;
end;


if Code = HCBT_CREATEWND then begin
//WrTm(2,"HCBT_CREATEWND");
if GetWndClassName(wnd)="Internet Explorer_Server" then begin
WrTm(2,"Hooked Internet Explorer_Server");
PostMessage(notifHandle,WUM_HookIEFired,wnd,0);
end;

end;


Result:= CallNextHookEx(HookHandle, Code, aWParam, aLParam );
end;


ну и собственно обработчик WUM_HookIEFired:

procedure TFormMain_DreamMates14_2.WUMHookIEFired(var Msg: TMessage);
begin

if Msg.WParam <> 0 then begin
fHWndHookedIEFrame := Msg.WParam;
fHWndHooked := Msg.LParam;

end
else exit;
TimerHook.Enabled := true;

end;


И обработчик таймера(здесь основная работа) - почему через таймер - я уже говорил - нужно дать время на формирование сообщения, оно начинает формироватся даже не при создании окна, а сразу после активации (у меня такое впечатление сложилось, но в прочем на єтом я не настаиваю - в смысле, когда формируется, но что задержка нужна - это обнозначно, я ставлю 0.2 сек)


type
TObjectFromLResult = function(LRESULT: lResult; const IID: TIID; WPARAM:
wParam; out pObject): HRESULT; stdcall;

const MSG: Integer = 0;
hInstLib: HWND =0;
ObjectFromLresult: TObjectFromLresult = nil;

function GetIDocFromHWND(WHandle: HWND; var iDoc: IHtmlDocument2): HRESULT;
var
lRes: Cardinal;
begin
Result := S_FALSE;
if hInstLib = 0 then hInstLib := LoadLibrary("Oleacc.dll");
if not assigned(ObjectFromLresult) then @ObjectFromLresult := GetProcAddress(hInstLib, "ObjectFromLresult");
if @ObjectFromLresult <> nil then begin
try
if MSG=0 then MSG := RegisterWindowMessage("WM_HTML_GETOBJECT");
SendMessageTimeOut(WHandle, MSG, 0, 0, SMTO_ABORTIFHUNG, 1000, lRes);
Result := ObjectFromLresult(lRes, IHTMLDocument2, 0, iDoc);
finally
//eeLibrary(hInst);
end;
end;
end;


procedure TFormMain_DreamMates14_2.TimerHookTimer(Sender: TObject);
var
WndChild: HWND;
//IE:IWebbrowser2;
iElem:IHtmlElement;
iDoc:IHtmlDocument2;

procedure HtmlCodToLog;
begin
if not assigned(iDoc) then exit;
WrTm(2,"Hooked text:" + GetTxtBoby(iDoc));
WrTm(2,"Hooked html:" + GetHtmlBoby(iDoc));

end;

procedure TryForceCloseHokkedWnd;
var h1,h:thandle;
begin
if fHWndHooked<>0 then begin
PostMessage(fHWndHooked,WM_Close,0,0);
exit;
end;
h1:= fHWndHookedIEFrame;

repeat
h:=GetParent(h1);

if ((h=0) or (h=Handle)) then begin
PostMessage(h1,WM_Close,0,0);
exit;
end;
h1 := h;

until false;


end;

var s:string;
begin //
try
TimerHook.Enabled := false;

if ((fHWndHookedIEFrame<>0) and (fHWndHooked=0)) then begin

GetiDocFromHWND(fHWndHookedIEFrame,IDoc);

end;

if not assigned(iDoc) then begin

WndChild := FindWindowEX(fHWndHookedIEFrame, 0, "Internet Explorer_Server", nil);
if WndChild=0 then begin
WrTm(2,"TimerHookTimer: cp1");
WndChild := FindWindowEX(fHWndHooked, 0, "Internet Explorer_Server", nil);
end;
if WndChild=0 then begin
WrTm(2,"TimerHookTimer: cp2");
Exit;
end;
if GetiDocFromHWND(WndChild,IDoc)<>S_OK then begin
WrTm(2,"TimerHookTimer: cp3");
exit;
end;
end;
if not assigned(iDoc) then begin
WrTm(2,"TimerHookTimer: cp4");
exit;
end;




//fIsOtherHTMLWarning := true;


WrTm(0,"** Catch window with a html-warnintg ....");
HtmlCodToLog;

s:=lowercase(GetTxtBoby(iDoc));

if Pos("error has occurred in the script on this page",s)>0 then begin
iElem := GetButtonWithSubstrInOuterHtml2(iDoc,"id=btnYes");
if assigned(iElem) then begin
iElem.Click;
WrTm(2,"TimerHookTimer: click on "continue running scripts"");
exit;
end;
end;

TryForceCloseHokkedWnd;


finally


end;

end;





 
Ihor Osov'yak ©   (2003-01-19 11:34) [4]

Да, функция постановки хука: :-)

procedure OnHook(aHNotif:THandle);
begin
if HookHandle<>0 then exit;
notifHandle := aHNotif;
HookHandle:=SetWindowsHookEx(WH_CBT,@Kah_hook,0,GetCurrentThreadId);

end;


 
int64 ©   (2003-01-19 12:57) [5]

crash123 (18.01.03 16:48)

Сделай так, и вообще никаких окон не будет. Во всяком случае, посмотри, может получится.

type
TForm1 = class(TForm)
WebBrowser1: TWebBrowser;
procedure FormCreate(Sender: TObject);
private
FOldWindowProc: TWndMethod;
procedure FormWndProc(var AMsg: TMessage);
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
FOldWindowProc:= WindowProc;
WindowProc := FormWndProc;
WebBrowser1.Navigate("c:\temp\1.htm");
end;

procedure TForm1.FormWndProc(var AMsg: TMessage);
var
ChWnd, wnd: Integer;
Msg: TWmActivate;
i: integer;
s: string;
begin
if AMsg.Msg = WM_ACTIVATE then
begin
Msg := TWmActivate(AMsg);
wnd := Msg.ActiveWindow;
//if ... then
SendMessage(wnd, WM_CLOSE, 0, 0);
end;
FOldWindowProc(AMsg);
end;

end.


А если хочешь, чтоб какое-то конкретное окно пропадало, то перед SendMessage(wnd, WM_CLOSE, 0, 0) ставь проверку на корректную идентификацию этого окна.

Ihor Osov"yak © (19.01.03 11:34)
Что-то ты много написал. Может ты практически подходил? А я вот теоритически. )


 
Ihor Osov'yak ©   (2003-01-19 13:48) [6]

2 int64 © (19.01.03 12:57)

> Что-то ты много написал. Может ты практически подходил? А я вот теоритически. )


Практик я, практик. :-)
Для теоретиков повторяю: прибитие окна на взлете равнозначно тисканию на кнопочку "не выполнять более скриптов" - или как она там зовется, пишу по-памяти, что в болшинстве практических случаев ведет к нарушению функционирования сайта - сейчас часто на всякие линки и кнопки скрипты разработчики сайтов вешают...
Хотя в конкретном случае вариант от int64 пройдет. Но нужно быть готовым к тому, что через некоторое время софту доделывать придется, так как авторы сайта подпадут под модные течения и ... (см. выше)


 
Ihor Osov'yak ©   (2003-01-19 13:50) [7]

Зы
> прибитие окна на взлете равнозначно тисканию на кнопочку
> "не выполнять более скриптов"
- сие проверялось практически и не единыжды :-)


 
Ihor Osov'yak ©   (2003-01-19 13:57) [8]

Зы еще - в коде от int64 наверно есть ошибка - FormWndProc делает сабклассинг для делфийской формы и будет соотв. ловить ее активацию, а не активацию окна с сообщением с ошибкой...
Имхо, активацию окна с ошибкой - только через хуки.

Зы - на сей раз это теоритическое размышление, практически проверять влом. Но думаю, что я прав.


 
sergey2   (2003-01-21 15:00) [9]

Я лично у себя написал:

try
WebBrowser1.Navigate(URL);
except
end;

и никаких ошибок не вылазит.



Страницы: 1 вся ветка

Текущий архив: 2003.03.10;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.014 c
9-29684
NudeRaven
2002-10-03 21:19
2003.03.10
BMP JPG GIF итд в dll


14-30135
{{{KOTOS}}}
2003-02-23 13:20
2003.03.10
МАСТЕРА СКИНЬТЕ ФАЙЛ ПОЖАЛУЙСТА GDS32.dl для NT


9-29682
][рюн
2002-10-09 10:48
2003.03.10
Пара простых вопросов по DelphiX:


14-30130
Anatoly Podgoretsky
2003-02-23 16:25
2003.03.10
Именинник 22 февраля


7-30151
Anatlij
2003-01-11 17:06
2003.03.10
Изменение видео режима Windows из преложения Delphi