基于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属性永远不会设置为'complete',尽管它应该基于官方文档吗?
答案 0 :(得分:4)
readyState
属性未设置为'complete'
,因为您尚未告诉IHTMLDocument2
对象实际加载文档。您必须加载文档,即使是空白文档(即:'about:blank'
URL),以便影响readyState
属性,否则它将保持其初始值'uninitialized'
。< / p>
答案 1 :(得分:3)
无需将designMode
设置为on
。无需轮询readyState
。只要您"complete"
和write
文档,它就会设置为close
:
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.