Hallo zusammen,
first of all: ich habe bereits alle relevanten TWebbrowser Threads in der
DP durch.
Ich habe das Problem, dass auf
Terminalservern bei Benutzern die per RDP aufgeschaltet sind, öfters das Laden von 'about
:blank' fehl schlägt.
Das Problem ist nicht häufig reproduzierbar und daher ein bisschen tricky zu analysieren. Vor allem tritt es nur auf Terminalservern von Windows auf. Auf Windows 7 oder 8 Rechnern ist das Problem bisher nie (in Worten "NIE") aufgetreten.
Der TWebbrowser ist ein Texteditor mit einem IHTMLDocument2 Dokument mit dem man Text formatieren kann.
Ich schreibe erstmal ein bisschen Code:
Delphi-Quellcode:
Procedure InitFrame;
function LadeAboutBlank: Boolean;
var SleepSumme: Integer;
Flags: OleVariant;
begin
Result := True;
// don't use cache for local files
Flags := Flags
or navNoReadFromCache
or navNoWriteToCache;
// Ein Navigate muss gemacht werden, damit der restliche HTML-Code in dieses leere
// Dokument eingefügt werden kann.
if WarteAufWebbrowser(WebBrowser1)
then
WebBrowser1.Navigate('
about:blank', Flags);
SleepSumme := 0;
//and ((WebBrowser1.ReadyState < READYSTATE_INTERACTIVE) or WebBrowser1.Busy)
while not FNavigateComplete
do begin
Pause(5);
SleepSumme := SleepSumme + 5;
if SleepSumme > 2500
then begin
Result := False;
break;
end else
Result := True;
end;
end;
begin
for I := 0
to 3
do begin
LadeAboutBlankDone := LadeAboutBlank();
if LadeAboutBlankDone
then
break;
end;
end;
Das schlägt häufig 3 mal hintereinander fehl. Da ich keine Endlosschleife generieren möchte, springe ich dann andernfalls mit einem Exit aus der Initialisierung des Webbrowser heraus und versuche es im OnShow nochmal (s.u.)
FNavigate wird folgendermaßen gesetzt:
Delphi-Quellcode:
procedure TFrameHTMLEditor.WebBrowser1BeforeNavigate2(ASender: TObject;
const pDisp: IDispatch;
var URL, Flags, TargetFrameName, PostData,
Headers: OleVariant;
var Cancel: WordBool);
begin
FCurDispatch :=
nil;
FNavigateComplete := False;
end;
procedure TFrameHTMLEditor.WebBrowser1NavigateComplete2(ASender: TObject;
const pDisp: IDispatch;
var URL: OleVariant);
begin
FNavigateComplete := True;
if FCurDispatch =
nil then
FCurDispatch := pDisp;
end;
Ich versuche das einmal im OnCreate des Forms. Im OnShow prüfe ich ob das Document geladen wurde. Wenn nicht, lade ich es stumpf neu. Das schlägt allerdings ebenso häufig fehl
Delphi-Quellcode:
procedure TFormSendMail.FormShow(Sender: TObject);
begin
if FrameHTMLEditor1.WebBrowser1.Document = nil then
FrameHTMLEditor1.InitFrame();
end;
Was mir aufgefallen ist: Beim ersten Laden wird das OnDocumentComplete-Event nicht ausgelöst. Beim zweiten Navigate zu about
:blank schon. Sense where?
Das grundlegende Problem ist folgendes: Das Document des Webbrowser wird nicht richtig initialisiert, d.h. er zeigt eine weiße Seite an (es wird kein Document geladen).
Das WarteAufWebbrowser macht folgendes:
Delphi-Quellcode:
function WarteAufWebbrowser(AWebBrowser: TWebBrowser): Boolean;
var SleepSumme: Integer;
begin
Result := True;
SleepSumme := 0;
while (AWebBrowser.ReadyState < READYSTATE_INTERACTIVE) or AWebBrowser.Busy do begin
Pause(5);
SleepSumme := SleepSumme + 10;
if SleepSumme > 5000 then begin
Result := False;
break;
end else
Result := True;
end;
end;
Wie kann ich sicherstellen, dass das IHTMLDocument2 mit dem "navigate('about
:blank')" richtig geladen wird? Bringt das setzen der
URL-Property eventuell was?
In meinem Fall ist wohl, das Problem, dass das OnNavigateComplete-Event nicht ausgelöst wird und es deswegen nicht weiter geht im Code.
Irgendwelche Ideen, eventuell auch mal rechts und links abseits des Weges?