4

この質問に基づいて: TWebBrowser から HTML ソース コードを取得するにはどうすればよいですか?

Unicode コード ページを含む html ページでこのコードを実行すると、D7 では TStringStream が Unicode ではないため、結果は意味不明になります。ページは UTF8 でエンコードされているか、他の (Ansi) コード ページでエンコードされている可能性があります。

TStream/IPersistStreamInit が Unicode/UTF8/Ansi かどうかを検出するにはどうすればよいですか?

この関数のWideStringとして常に正しい結果を返すにはどうすればよいですか?

function GetWebBrowserHTML(const WebBrowser: TWebBrowser): WideString;

TStringStream を TMemoryStream に置き換えて、TMemoryStream をファイルに保存すれば、問題ありません。Unicode/UTF8/Ansi のいずれかです。しかし、私は常にストリームを WideString として返したいと思っています:

function GetWebBrowserHTML(const WebBrowser: TWebBrowser): WideString;
var
  // LStream: TStringStream;
  LStream: TMemoryStream;
  Stream : IStream;
  LPersistStreamInit : IPersistStreamInit;
begin
  if not Assigned(WebBrowser.Document) then exit;
  // LStream := TStringStream.Create('');
  LStream := TMemoryStream.Create;
  try
    LPersistStreamInit := WebBrowser.Document as IPersistStreamInit;
    Stream := TStreamAdapter.Create(LStream,soReference);
    LPersistStreamInit.Save(Stream,true);
    // result := LStream.DataString;
    LStream.SaveToFile('c:\test\test.txt'); // test only - file is ok
    Result := ??? // WideString
  finally
    LStream.Free();
  end;
end;

編集:私はこの記事を見つけました - How to load and save documents in TWebBrowser in a Delphi-like way

これは私が必要とすることを正確に行います。ただし、Delphi Unicode コンパイラ (D2009+) でのみ正しく動作します。結論セクションを読んでください:

明らかに、私たちにできることはもっとたくさんあります。いくつかのことがすぐに思い浮かびます。一部の Unicode 機能と非 ANSI エンコーディングのサポートを、Unicode 以前のコンパイラ コードにレトロフィットします。ドキュメントの文字セットが ANSI でない場合、Delphi 2009 より前のバージョンでコンパイルされた現在のコードは、ドキュメント コンテンツを文字列に正しく保存しません。

魔法は明らかにTEncodingクラス ( TEncoding.GetBufferEncoding) にあります。しかしD7にはありませんTEncoding。何か案は?

4

1 に答える 1

2

変換を処理するためにGpTextStreamを使用しました(すべてのDelphiバージョンで機能するはずです):

function GetCodePageFromHTMLCharSet(Charset: WideString): Word;
const
  WIN_CHARSET = 'windows-';
  ISO_CHARSET = 'iso-';
var
  S: string;
begin
  Result := 0;
  if Charset = 'unicode' then
    Result := CP_UNICODE else
  if Charset = 'utf-8' then
    Result := CP_UTF8 else
  if Pos(WIN_CHARSET, Charset) <> 0 then
  begin
    S := Copy(Charset, Length(WIN_CHARSET) + 1, Maxint);
    Result := StrToIntDef(S, 0);
  end else
  if Pos(ISO_CHARSET, Charset) <> 0 then // ISO-8859 (e.g. iso-8859-1: => 28591)
  begin
    S := Copy(Charset, Length(ISO_CHARSET) + 1, Maxint);
    S := Copy(S, Pos('-', S) + 1, 2);
    if S = '15' then // ISO-8859-15 (Latin 9)
      Result := 28605
    else
      Result := StrToIntDef('2859' + S, 0);
  end;
end;

function GetWebBrowserHTML(WebBrowser: TWebBrowser): WideString;
var
  LStream: TMemoryStream;
  Stream: IStream;
  LPersistStreamInit: IPersistStreamInit;
  TextStream: TGpTextStream;
  Charset: WideString;
  Buf: WideString;
  CodePage: Word;
  N: Integer;
begin
  Result := ''; 
  if not Assigned(WebBrowser.Document) then Exit;
  LStream := TMemoryStream.Create;
  try
    LPersistStreamInit := WebBrowser.Document as IPersistStreamInit;
    Stream := TStreamAdapter.Create(LStream, soReference);
    if Failed(LPersistStreamInit.Save(Stream, True)) then Exit;
    Charset := (WebBrowser.Document as IHTMLDocument2).charset;
    CodePage := GetCodePageFromHTMLCharSet(Charset);
    N := LStream.Size;
    SetLength(Buf, N);
    TextStream := TGpTextStream.Create(LStream, tsaccRead, [], CodePage);
    try
      N := TextStream.Read(Buf[1], N * SizeOf(WideChar)) div SizeOf(WideChar);
      SetLength(Buf, N);
      Result := Buf;
    finally
      TextStream.Free;
    end;
  finally
    LStream.Free();
  end;
end;
于 2013-01-13T22:59:24.643 に答える