我正在使用uHTMLEdit.pas 3中提供的RadPHP作为uHTMLEdit.pas(基于TWebbrowser)。
当我加载一些HTML文件时,程序会崩溃。例如,保存此StackOverflow页面并将其加载到TWebbrowser中。它会坠毁:
坠机详情:
Access violation at address 005FAF9B in module 'TestHtmlEditRad.exe'. Read of address 00000000.在线崩溃Doc.Body.SetAttribute('contentEditable', 'true', 0):
procedure THTMLEdit.EditText(const text: string);
VAR
Doc: IHTMLDocument2;
sl: TStringList;
f: string;
begin
sl := TStringList.Create;
TRY
sl.Text := text;
f := gettempfile('.html');
sl.SaveToFile(f);
wbBrowser.Navigate(f);
Doc := GetDocument;
if Doc <> NIL
then Doc.Body.SetAttribute('contentEditable', 'true', 0); **Crash HERE**
DeleteFile(f);
FINALLY
FreeAndNil(sl);
END;
end;它适用于小型(不太复杂)的HTML文件。
我的问题是: TWebBrowser崩溃是正常的吗?
要再现,您只需要这些代码和uHTMLEdit.pas (已经与Embarcadero RadPHP一起提供)。
unit FormMain;
interface
USES
Vcl.Controls, Vcl.Forms, Vcl.StdCtrls, uHTMLEdit;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
end;
var
Form1: TForm1;
IMPLEMENTATION {$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
VAR debug: string;
begin
debug:= stringfromfile('test.htm'); // this temporary line of code is mine, for testing. All other code is Embarcadero's
with THTMLEditDlg.Create(application) do begin
try
edittext(debug);
if ShowModal= 0
then debug:= getText;
finally
free;
end;
end;
end;
end.发布于 2016-09-22 07:35:19
在THTMLEdit.EditText方法中:
...
wbBrowser.Navigate(f);
Doc := GetDocument;
if Doc <> NIL
then Doc.Body.SetAttribute('contentEditable', 'true', 0); **Crash HERE**
...wbBrowser.Navigate(f)是异步。当您调用Doc.Body.SetAttribute时,Doc或Doc.Body可能还没有准备好/实例化。这就是AV的原因。
由于Navigate是异步的,所以需要等待TWebBrowser完全加载和初始化其DOM。这通常是通过以下方式完成的:
wbBrowser.Navigate(f);
while wbBrowser.ReadyState <> READYSTATE_COMPLETE do
Application.ProcessMessages;
...由于Application.ProcessMessages被认为是“邪恶的”,并且可能导致重新进入问题(除非您正确地处理它),一个更好的方法应该是在文档/框架完全加载的情况下使用TWebBrowser.OnDocumentComplete事件,并在那里访问(就绪/初始化) DOM。
https://stackoverflow.com/questions/39597544
复制相似问题