Einzelnen Beitrag anzeigen

Perlsau
(Gast)

n/a Beiträge
 
#5

AW: MsHtml in 64-Bit-Anwendung erzeugt Float Invalid Operation

  Alt 5. Mai 2015, 17:43
Nun ist ja der Internet-Explorer in Win 7-64 eine 32-Bit-Anwendung, somit auch die DLL, auf die MsHtml zurückgreift.
Irrtum. Auf jedem Windows x64 gibt es den IE in beiden Ausführungen, 32 und 64 Bit, inkl. der mshtml.dll.
Danke für den Hinweis. Da war ich offensichtlich auf der falschen Fährte
Zwar konnte ich den IE-11-64 nun doch noch installieren (nach Aktivierung diverser Update-Services, die bei mir deaktiviert waren), doch tritt der Fehler weiterhin auf.

In welcher Programmzeile wird denn die Exception geworfen?
Delphi-Quellcode:
    While IDoc.readyState <> 'completeDo
      Application.ProcessMessages;
    Result := IDoc.Body.InnerText;
Entweder beim Abfragen von IDoc.readyState oder beim Zuweisen von IDoc.Body.InnerText . Genauer läßt sich das nicht eingrenzen, da beim Durchsteppen mehrere Male ReadyState abgefragt wird und der Fehler manchmal beim dritten, manchmal erst beim zehnten Durchlauf auftritt. Ich bin mir nicht sicher, ob die Zuweisung von IDoc.Body.InnerText den Fehler auslöst oder die Abfrage von IDoc.readyState .

Ist das nicht das "übliche" dass die Exception nicht in deinem Programm, sondern im IE Code kommt? Und zwar weil Delphi mit seinem Floating Point-Exception Masking sich nicht "standard-microsoftig" verhält? Im Internet findet man auf den ersten Blick eine Menge zu TWebBrowser und Fließkomma-Exceptions, alle scheinen darauf hinauszulaufen, die FPU-Exceptions so zu drehen wie der IE-Code es auch erwartet:
z.B. http://stackoverflow.com/q/9359223/2298252
Okay, da vermeine ich etwas Licht am Ende des Tunnels zu erkennen. Ich hab jetzt erstmal das gemacht, was im Emba-Beispielcode steht:
Delphi-Quellcode:
...
VAR
  FormMain : TFormMain;
  Saved8087CW : Word;

IMPLEMENTATION
...
Procedure TFormMain.FormCreate(Sender: TObject);
begin
  Saved8087CW := Default8087CW;
  {$IFDEF WIN64}
  Self.Caption := GLD.Programmtitel + '64-Bit-Version';
  System.Set8087CW($133f);
  {$ELSE}
  Self.Caption := GLD.Programmtitel + '32-Bit-Version';
  System.Set8087CW(Saved8087CW);
  {$ENDIF}
...

Procedure TFormMain.FormDestroy(Sender: TObject);
begin
  System.Set8087CW(Saved8087CW);
end;
Nach dem Neu-Erzeugen tritt der Fehler jedoch leider immer noch auf. Doch wir sind ja noch nicht am Ende der Fahnenstange, denn David Heffeman bietet bei StackOverFlow eine Alternative an:
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.

Allerdings muß ich gestehen, daß ich diese Alternative nicht wirklich verstehe. Wo und wie muß ich diese drei Methoden aufrufen?
  Mit Zitat antworten Zitat