При попытке редактировать IHTMLDocument зависает приложение - PullRequest
1 голос
/ 29 декабря 2011

на основе документации MSHTML для IHTMLDocument2 Я пытаюсь написать простой анализатор 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.

Просто любопытно почему readyState свойство ofИнтерфейс IHTMLDocument2 никогда не устанавливается на «завершено», хотя на основании официальной документации это должно быть?

Ответы [ 2 ]

4 голосов
/ 29 декабря 2011

Свойство readyState не установлено на 'complete', поскольку вы еще не сказали объекту IHTMLDocument2 о фактической загрузке документа.Вам нужно загрузить документ, даже пустой (например, URL-адрес 'about:blank'), чтобы повлиять на свойство readyState, в противном случае он остается на своем первоначальном значении 'uninitialized'.

3 голосов
/ 23 февраля 2012

Нет необходимости устанавливать 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.
...