TWebBrowser crashes with embedded Youtube clips-Collection of common programming errors
Here is my code:
type
TForm1 = class(TForm)
WebBrowser1: TWebBrowser;
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
end;
implementation
uses ActiveX;
procedure TForm1.Button1Click(Sender: TObject); // method 1
var
HtmlFile: string;
begin
HtmlFile := ExtractFilePath(Application.ExeName) + 'test.html';
WebBrowser1.Navigate(HtmlFile);
end;
procedure LoadHtml(wb: TWebBrowser; HTMLStr: string);
var
aStream: TMemoryStream;
begin
wb.Navigate('about:blank'); // reset the webbrowser
while wb.ReadyState < READYSTATE_INTERACTIVE do // wait to load the empty page
Application.ProcessMessages;
if Assigned(wb.Document) then
begin
aStream := TMemoryStream.Create;
try
aStream.WriteBuffer(Pointer(HTMLStr)^, Length(HTMLStr));
aStream.Seek(0, soFromBeginning);
(wb.Document as IPersistStreamInit).Load(TStreamAdapter.Create(aStream));
finally
aStream.Free;
end;
end;
end;
procedure TForm1.Button2Click(Sender: TObject); // method 2
begin
LoadHtml(WebBrowser1,
''+
' '+
' '+
' '+
' '+
' '+
' '+
''
);
end;
test.html
My application crashes in both methods. I get An unhandled win32 exception (caused by Flash player Exception EInvalidOp in module Flash10u.ocx at 00108657. Invalid floating point operation
).
- I tried this code on D5, D7, D9.
- I tried to re-import SHDocVw.dll.
- I also tried to use EmbeddedWB control instead of TWebBroser…
- Internet Explorer/Avant/Maxthon has no problems with this HTML (all based on IE ActiveX).
Any suggestions or a fix?
How can I catch this error or even suppress it?
Is there a way to manipulate or change the HTML on the fly via a TWebBrowser event, so I can display an Image instead of the Flash player, same as Ad-Blockers works? (My customers have that code in their sites over the internet, and my Delphi application provides a fast preview)
UPDATE
I used a TTimer to enable/disable FPU (based on Arjen’s idea):
function Get8087CW: Word; // for D5
asm
PUSH 0
FNSTCW [ESP].Word
POP EAX
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Timer1.Enabled := False;
Timer1.Interval := 5000; // 5 sec
Saved8087CW := Get8087CW;
end;
procedure TForm1.WebBrowser1BeforeNavigate2(Sender: TObject;
const pDisp: IDispatch; var URL, Flags, TargetFrameName, PostData,
Headers: OleVariant; var Cancel: WordBool);
begin
Timer1.Enabled := False;
System.Set8087CW($133F); // Disable all fpu exceptions
end;
procedure TForm1.WebBrowser1DocumentComplete(Sender: TObject;
const pDisp: IDispatch; var URL: OleVariant);
begin
Timer1.Enabled := True;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
Timer1.Enabled := False;
Set8087CW(Saved8087CW);
end;
UPDATE (2)
I ended up masking the FPU exception in the application start-up. there was no (known) impact on my application ever since.
-
Try to disable temporarily FPU exception with Set8087CW(0x133f); info
-
A bit more beautiful solution:
Math.SetExceptionMask([exInvalidOp, exDenormalized, exZeroDivide, exOverflow, exUnderflow, exPrecision]);
If I read documentation correct,
Math.SetExceptionMask
silences every exception mentioned.However, it is just cleaner and more beautiful version of @Arjen’s approach.