In Delphi 2010 and Delphi 2007 I am using Set8087CW on WebBrowserBeforeNavigate / WebBrowserDocumentComplete to prevent FPU errors inside ActiveX to cripple my application.
But somehow this is not working in Delphi XE2, at least when in 64bit mode.
When clicking links (any) I get "float divide by zero". (The initial loading of a website address or content into TWebBrowser works fine.)
The callstack shows this to happen inside system32\D3D10Warp.dll (maybe used by IE9?) in response to TApplication.ProcessMessage (and some ??? inbetween the two)
You will need to mask SSE exceptions on 64 bit because 64 bit code typically uses SSE to perform floating point arithmetic.
Call SetMXCSR
to change the control state of the SSE unit. Personally I would continue masking 8087 exceptions since 64 bit code is perfectly at liberty to use the 8087 unit should it so wish. The magic MXCSR value that you want to use when calling the web browser code is $1F80
. This is the default Windows value for MXCSR.
Alternatively, you can call SetSSEExceptionMask
and SetFPUExceptionMask
passing exAllArithmeticExceptions
to mask all exceptions. These convenience methods would make your code more readable.
If you are satisfied that you only need to mask exceptions on 8087 under x86 and SSE under x64 then you can just call SetExceptionMask
. This will change the 8087 control state under x86 and change the SSE control state under x64.
If I had to choose between setting the entire control state or using the convenience methods to change just the exception masking part of the state, I would set the entire control state. These ActiveX controls are written under the assumption that you will be using MS tooling and expect a specific FP control state. I would give these controls the exact control state that they expect and then revert back to the Delphi control state when execution returns from the controls.