尝试编辑 IHTMLDocument 会挂起应用程序

发布于 2024-12-23 09:17:47 字数 1119 浏览 2 评论 0原文

基于 IHTMLDocument2 的 MSHTML 文档,我正在尝试编写简单的 HTML 解析器。 不幸的是,尝试设置编辑模式失败,换句话说,resultState 永远不会获得“完整”值,因此应用程序挂起。

{$APPTYPE CONSOLE}

function ParseHtml(doc: TStringList): TStringList;
var
  iHtml: IHTMLDocument2;
  v: Variant;
  msg: tagMSG;
begin
  iHtml := CreateComObject(CLASS_HTMLDocument) as IHTMLDocument2;
  Result := TStringList.Create;
  try
    try
      iHtml.designMode := 'on';
      while iHtml.readyState <> 'complete' do
        PeekMessage(msg, 0, 0, 0, PM_NOREMOVE);
//    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//    above loop never finishes  
      v := VarArrayCreate([0, 0], varVariant);
      v[0] := doc.Text;
      iHtml.write( PSafeArray(TVarData(v).VArray) );
      iHtml.designMode := 'off';
      while iHtml.readyState <> 'complete' do
        PeekMessage(msg, 0, 0, 0, PM_NOREMOVE);
      // processing iHtml.body
      ...
    except
      ...
    end;
  finally
    ...
  end;
  ...
end;

begin
  CoInitialize(nil);
  ...
  CoUninitialize;  
end.

只是好奇为什么 IHTMLDocument2 接口的readyState 属性从未设置为“完整”,尽管基于官方文档它应该如此?

based on MSHTML documentation for IHTMLDocument2 I'm trying to write simple HTML parser.
Unfortunately trying to set edit-mode fails, in other words resultState never gets 'complete' value so application hangs.

{$APPTYPE CONSOLE}

function ParseHtml(doc: TStringList): TStringList;
var
  iHtml: IHTMLDocument2;
  v: Variant;
  msg: tagMSG;
begin
  iHtml := CreateComObject(CLASS_HTMLDocument) as IHTMLDocument2;
  Result := TStringList.Create;
  try
    try
      iHtml.designMode := 'on';
      while iHtml.readyState <> 'complete' do
        PeekMessage(msg, 0, 0, 0, PM_NOREMOVE);
//    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//    above loop never finishes  
      v := VarArrayCreate([0, 0], varVariant);
      v[0] := doc.Text;
      iHtml.write( PSafeArray(TVarData(v).VArray) );
      iHtml.designMode := 'off';
      while iHtml.readyState <> 'complete' do
        PeekMessage(msg, 0, 0, 0, PM_NOREMOVE);
      // processing iHtml.body
      ...
    except
      ...
    end;
  finally
    ...
  end;
  ...
end;

begin
  CoInitialize(nil);
  ...
  CoUninitialize;  
end.

Just curious why readyState property of IHTMLDocument2 interface is never set to 'complete', although based by official documentation it should ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

只是我以为 2024-12-30 09:17:47

readyState 属性未设置为 'complete',因为您尚未告知 IHTMLDocument2 对象实际加载文档。您必须加载一个文档,即使是空白文档(即:'about:blank' URL),才能影响 readyState 属性,否则它将保持其状态'uninitialized' 的初始值。

The readyState property is not being set to 'complete' because you have not told the IHTMLDocument2 object to actually load a document yet. You have to load a document, even a blank one (ie: the 'about:blank' URL), in order to affect the readyState property, otherwise it remains at its initial value of 'uninitialized'.

妞丶爷亲个 2024-12-30 09:17:47

无需将 designMode 设置为 on。也不需要轮询readyState。一旦您写入关闭文档,它就会被设置为“完成”

program Test;
{$APPTYPE CONSOLE}
uses
  SysUtils,
  MSHTML,
  ActiveX,
  ComObj;

procedure DocumentFromString(Document: IHTMLDocument2; const S: WideString);
var
  v: OleVariant;
begin
  v := VarArrayCreate([0, 0], varVariant);
  v[0] := S;
  Document.Write(PSafeArray(TVarData(v).VArray));
  Document.Close;
end;

var
  Document: IHTMLDocument2;
  Elements: IHTMLElementCollection;
  Element: IHTMLElement;
begin
  CoInitialize(nil);

  Document := CreateComObject(CLASS_HTMLDocument) as IHTMLDocument2;
  DocumentFromString(Document, '<b>Hello</b>');
  Writeln(string(Document.readyState));

  // process the Document here
  Elements := Document.all.tags('b') as IHTMLElementCollection;
  Element := Elements.item(0, '') as IHTMLElement;
  Writeln(string(Element.innerText));
  Readln;

  CoUninitialize;
end.

No need to set designMode to on. no need to poll the readyState either. it will be set to "complete" as soon as you write and close the document:

program Test;
{$APPTYPE CONSOLE}
uses
  SysUtils,
  MSHTML,
  ActiveX,
  ComObj;

procedure DocumentFromString(Document: IHTMLDocument2; const S: WideString);
var
  v: OleVariant;
begin
  v := VarArrayCreate([0, 0], varVariant);
  v[0] := S;
  Document.Write(PSafeArray(TVarData(v).VArray));
  Document.Close;
end;

var
  Document: IHTMLDocument2;
  Elements: IHTMLElementCollection;
  Element: IHTMLElement;
begin
  CoInitialize(nil);

  Document := CreateComObject(CLASS_HTMLDocument) as IHTMLDocument2;
  DocumentFromString(Document, '<b>Hello</b>');
  Writeln(string(Document.readyState));

  // process the Document here
  Elements := Document.all.tags('b') as IHTMLElementCollection;
  Element := Elements.item(0, '') as IHTMLElement;
  Writeln(string(Element.innerText));
  Readln;

  CoUninitialize;
end.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文