首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >大多数html文件下的TWebBrowser崩溃。

大多数html文件下的TWebBrowser崩溃。
EN

Stack Overflow用户
提问于 2016-09-20 15:02:12
回答 1查看 554关注 0票数 0

我正在使用uHTMLEdit.pas 3中提供的RadPHP作为uHTMLEdit.pas(基于TWebbrowser)。

当我加载一些HTML文件时,程序会崩溃。例如,保存此StackOverflow页面并将其加载到TWebbrowser中。它会坠毁:

坠机详情:

代码语言:javascript
运行
复制
Access violation at address 005FAF9B in module 'TestHtmlEditRad.exe'. Read of address 00000000.

在线崩溃Doc.Body.SetAttribute('contentEditable', 'true', 0)

代码语言:javascript
运行
复制
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一起提供)。

代码语言:javascript
运行
复制
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.
EN

Stack Overflow用户

回答已采纳

发布于 2016-09-22 07:35:19

THTMLEdit.EditText方法中:

代码语言:javascript
运行
复制
...
wbBrowser.Navigate(f);
Doc := GetDocument;
if Doc <> NIL
then Doc.Body.SetAttribute('contentEditable', 'true', 0);  **Crash HERE**
...

wbBrowser.Navigate(f)异步。当您调用Doc.Body.SetAttribute时,DocDoc.Body可能还没有准备好/实例化。这就是AV的原因。

由于Navigate是异步的,所以需要等待TWebBrowser完全加载和初始化其DOM。这通常是通过以下方式完成的:

代码语言:javascript
运行
复制
  wbBrowser.Navigate(f);
  while wbBrowser.ReadyState <> READYSTATE_COMPLETE do
    Application.ProcessMessages;
  ...

由于Application.ProcessMessages被认为是“邪恶的”,并且可能导致重新进入问题(除非您正确地处理它),一个更好的方法应该是在文档/框架完全加载的情况下使用TWebBrowser.OnDocumentComplete事件,并在那里访问(就绪/初始化) DOM。

票数 2
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39597544

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档