Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум на Исходниках.RU > Delphi: Общие вопросы > Подскажите, хороший, компонент для просмотра HTML, DHTML


Автор: DelphiLexx 12.09.07, 11:33
Сейчас я работаю над приложением, где необходим справочник, в котором будут показываться HTML-документы, подскажите, пожалуйста, хороший, бесплатный компонент для просмотра HTML-документов.

Автор: Rouse_ 12.09.07, 11:50
TWebBrowser - бесплатен по самое нехочу :)

Автор: DelphiLexx 12.09.07, 12:00
Цитата Rouse_ @
TWebBrowser - бесплатен по самое нехочу

Не устраивает тем, что не умеет читать данные из потока (Stream). У меня Html-документы будут храниться в базе данных, затем с помощью Sql-запроса помещается в DataSet, после чего мне нужно, чтобы эти данные отобразились в виде Html-документа.

Автор: Rouse_ 12.09.07, 12:16
Цитата DelphiLexx @
Не устраивает тем, что не умеет читать данные из потока (Stream).

Это ты просто не умеешь в него писать из потока :)
Ищи примеры в FAQ.

Автор: rapido 12.09.07, 17:03
ThtmlLite. У него есть LoadFromStream.

Автор: DelphiLexx 13.09.07, 11:01
Цитата Rouse_ @
Это ты просто не умеешь в него писать из потока
Ищи примеры в FAQ.

Нашел
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    uses
    ActiveX;
     
    procedure WB_LoadHTML(WebBrowser: TWebBrowser; HTMLCode: string);
    var
    sl: TStringList;
    ms: TMemoryStream;
    begin
     
    WebBrowser.Navigate('about:blank');
    while WebBrowser.ReadyState < READYSTATE_INTERACTIVE do
      Application.ProcessMessages;
     
    if Assigned(WebBrowser.Document) then
    begin
       sl := TStringList.Create;
       try
         ms := TMemoryStream.Create;
         try
           sl.Text := HTMLCode;
           sl.SaveToStream(ms);
           ms.Seek(0, 0);
           (WebBrowser.Document as IPersistStreamInit).Load(TStreamAdapter.Create(ms));
         finally
           ms.Free;
         end;
       finally
         sl.Free;
       end;
    end;
     
    end;
     
    procedure TForm1.Button1Click(Sender: TObject);
    begin
     
    WB_LoadHTML(WebBrowser1,'SwissDelphiCenter');
    end;

Но есть одна проблема, у меня в ms - будет храниться Html-код, после исполнения кода указанного выше, TWebBrowser - отображает не саму страницу (толькл информационный текст), а Html-код, т.е. тэги, информационный текст и прочую фигню. Как быть?

Автор: Rouse_ 13.09.07, 11:32
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    var
      Document: IHtmlDocument2;
      V: Variant;
     
    ...
     
      WebBrowser2.Navigate('about:blank');
      while WebBrowser2.Document = nil do
        Application.ProcessMessages;
      Document := WebBrowser2.Document as IHtmlDocument2;
      V := VarArrayCreate([0, 0], varVariant);
      V[0] := HTMLCode;
      Document.Writeln(PSafeArray(TVarData(v).VArray));
    end;

Автор: Romkin 13.09.07, 11:35
Делай тупо
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    var
      V: OleVariant;
      HtmlDoc: IHTMLDocument2;
    begin
      WB.Navigate('about:blank');
      OleCheck(WB.Document.QueryInterface(IHTMLDocument2, HtmlDoc));
      V := VarArrayCreate([0, 0], varVariant);
      V[0] := ppText.Content; //строка
      HtmlDoc.write(PSafeArray(TVarData(V).VArray));
      HtmlDoc.close;


Добавлено
:lool:
Розыч, close в конце не помешает ;)

Автор: Rouse_ 13.09.07, 11:41
Цитата Romkin @
Розыч, close в конце не помешает

Я когда даю демки, обычно на такое не смотрю - должен же вопрошающий сам над чем нибудь поразмыслить :)

Автор: DelphiLexx 13.09.07, 12:03
Цитата Romkin @
Делай тупо
var
V: OleVariant;
HtmlDoc: IHTMLDocument2;
begin
WB.Navigate('about:blank');
OleCheck(WB.Document.QueryInterface(IHTMLDocument2, HtmlDoc));
V := VarArrayCreate([0, 0], varVariant);
V[0] := ppText.Content; //строка
HtmlDoc.write(PSafeArray(TVarData(V).VArray));
HtmlDoc.close;

Так мне же нужно через поток

Автор: Romkin 13.09.07, 12:10
:wall:
Цитата DelphiLexx @
У меня Html-документы будут храниться в базе данных, затем с помощью Sql-запроса помещается в DataSet, после чего мне нужно, чтобы эти данные отобразились в виде Html-документа.

Вопрос на засыпку: Есть ли у TField метод AsString?!

Автор: Rouse_ 13.09.07, 12:10
Используй TStringStream - будет тебе поток, легко трансформируемый в строку :)

Автор: DelphiLexx 13.09.07, 14:01
Цитата Romkin @
Вопрос на засыпку: Есть ли у TField метод AsString?!

Есть.

Добавлено
А как узнать, пустой ли докумет или нет?

Автор: Romkin 14.09.07, 04:32
А если есть, ничего не мешает писать V[0] := MyField.asString; ;)
Цитата DelphiLexx @
А как узнать, пустой ли докумет или нет?

В где?

Автор: DelphiLexx 14.09.07, 05:41
Цитата Romkin @
В где?

В TWebBrowser'e.
1. Мне это нужно, для следующих целей, если документ пустой, т.е. если загружен html - который не содержит информационного текста, тогда я блокирую кнопку очистить (она очищает содержимое документа TWebBrowser'a). Кстати, умеет ли TWebBrowser очищать документ, если ли у него такой метод?
2. Как сохранить исходник TWebBrowser.Document'a в TStringStream, я так понимаю вот так:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
     ts := TStringStream.Create;
     try
      ((WebBrowser.Document as IHTMLDocument2) as IPersistStreamInit).Save(TStreamAdapter.Create(ts), 'вот здесь что ставить?')
      ...
     finally
      ts.Free;
     end;

Автор: Rouse_ 14.09.07, 05:56
Document.body.outerText даст тебе PlainText страницы. Эсли страница будет пуста, то там будет тоже пусто (ну или пробелы)

Автор: DelphiLexx 14.09.07, 07:28
Цитата Rouse_ @
Document.body.outerText даст тебе PlainText страницы. Эсли страница будет пуста, то там будет тоже пусто (ну или пробелы)

А как насчет, сохранения в поток исходного текста Html.

Автор: Rouse_ 14.09.07, 07:44
Цитата DelphiLexx @
А как насчет, сохранения в поток исходного текста Html.

Почитай вот эту статью: http://www.delphikingdom.com/asp/viewitem.asp?catalogid=366

Автор: DelphiLexx 14.09.07, 08:06
Цитата Rouse_ @
Почитай вот эту статью: http://www.delphikingdom.com/asp/viewitem.asp?catalogid=366

Там ни слова про сохранение в поток исходного текста Html.

Автор: Rouse_ 14.09.07, 08:13
Сохранение это
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    TStream.Write(HTMLCode[1], Length(HTMLCode));

Неужели тебя интересует такой простой момент?
А статью я тебе дал чтобы ты разобрался в принципах работы

Автор: DelphiLexx 14.09.07, 08:26
Цитата Rouse_ @
Неужели тебя интересует такой простой момент?
А статью я тебе дал чтобы ты разобрался в принципах работы

Не так все просто, вот мой пример:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    var
      Document: IHTMLDocument2;
      ss: TStringStream;
      HtmlCode: string;
    begin
      Result := S_ERROR;
      if (WebBrowser.Document <> nil) then
      begin
        ss := TStringStream.Create('');
        ss.Position := 0;
        try
          Document := WebBrowser.Document as IHTMLDocument2;
         (Document as IPersistStreamInit).Save(TStreamAdapter.Create(ss), true);
          HtmlCode := ss.DataString;{так вот если, страница Document.charset <> 'unicode', тогда все нормально,
                                     в противном случае получается бред}
          ExecFibSql(TheApp.MainDBConnection.fdbApp,
            'update WHAT_TODO_GROUPS ' +
            'set ' +
            'artcle_group_text = :p1 ' +
            'where article_group_id = :p2',
            [HtmlCode, LastArticleID], fibtDct);
          Result := S_OK;
        finally
          ss.Free;
        end;
      end;
    end;

Автор: Rouse_ 14.09.07, 08:43
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    var
      Document: IHTMLDocument2;
      ss: TMemoryStream;
      HtmlCode: string;
    begin
      Result := S_ERROR;
      if (WebBrowser.Document <> nil) then
      begin
        ss := TStringStream.Create('');
        ss.Position := 0;
        try
          Document := WebBrowser.Document as IHTMLDocument2;
         (Document as IPersistStreamInit).Save(TStreamAdapter.Create(ss), true);
         SetLength(HtmlCode, ss.size);
         ss.read(HtmlCode[1], ss.Size);
          ExecFibSql(TheApp.MainDBConnection.fdbApp,
            'update WHAT_TODO_GROUPS ' +
            'set ' +
            'artcle_group_text = :p1 ' +
            'where article_group_id = :p2',
            [HtmlCode, LastArticleID], fibtDct);
          Result := S_OK;
        finally
          ss.Free;
        end;
      end;
    end;


Добавлено
Но вообще для этого лучше использовать не String а array of Byte и в нужный момент просто производить преобразование

Автор: DelphiLexx 14.09.07, 08:50
Цитата Rouse_ @
лучше использовать не String а array of Byte

Написал так, Buffer заполняется нулями
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    var
    ...
    Buffer: array of byte;
    begin
    ..
      SetLength(Buffer, ss.Size);
      ss.Read(Buffer, ss.Size);
    ...
      end;

Цитата Rouse_ @
просто производить преобразование

Где можно взять нормальный рабочий код, сохранения html-кода (любой кодировки) в переменную типа string? Везде приводится пример сохранения на диск, любой ебл..н сможет это сделать.

Автор: Rouse_ 14.09.07, 09:24
Цитата DelphiLexx @
Написал так, Buffer заполняется нулями

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    ss.Read(Buffer[0], ss.Size);

Автор: DelphiLexx 14.09.07, 09:43
Цитата Rouse_ @
ss.Read(Buffer[0], ss.Size);

То же самое

Автор: Rouse_ 14.09.07, 10:04
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
      SetLength(Buffer, ss.Size);
      ss.Position := 0;
      ss.Read(Buffer[0], ss.Size);

Автор: DelphiLexx 14.09.07, 11:05
Цитата Rouse_ @
SetLength(Buffer, ss.Size);
ss.Position := 0;
ss.Read(Buffer[0], ss.Size);

Так хорошо, сейчас работает, проблема была - не стоял ss.Position := 0;
Что дальше-то делать, теперь это Buffer надо перевести из Unicode в Ansi

Автор: Rouse_ 14.09.07, 11:08
А зачем? Тебе же потом этот текст нужно обратно бараузеру отдать. Так? Ну так сохраняй его в базе, а потом когда нужно - вытащишь и в таком-же виде отдашь обратно браузеру - он сам разберется...

Автор: DelphiLexx 14.09.07, 11:29
Цитата Rouse_ @
А зачем? Тебе же потом этот текст нужно обратно бараузеру отдать. Так? Ну так сохраняй его в базе, а потом когда нужно - вытащишь и в таком-же виде отдашь обратно браузеру - он сам разберется...

Дело в том что я встроил функции редактирования, т.е. в WebBrowser'e пользователь может редактировать текст, как только он выходит из редактирования то, текст сохраняется в БД. Вот посмотри после долгих условий, получил такой код:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    function
      TfmDictWhatToDoIF.SaveArticle:
      HRESULT;
    var
      Document: IHTMLDocument2;
      ss: TStringStream;
      HtmlCodeA: string;
      Buffer: TDynArrOfByte;
    begin
     
      Result := S_ERROR;
      if (WebBrowser.Document <> nil) then
      begin
        ss := TStringStream.Create('');
        ss.Position := 0;
        try
          Document := WebBrowser.Document as IHTMLDocument2;
         (Document as IPersistStreamInit).Save(TStreamAdapter.Create(ss), false);
          SetLength(Buffer, ss.Size);
          ss.Position := 0;
          ss.Read(Buffer[0], ss.Size);
          if Document.charset = 'unicode' then
            HtmlCodeA := PWChar(@Buffer[2]) //вот здесь сомнения мучают мож сделать HtmlCodeA: WideString'ом
          else                          //правда здесь будет не хорошо, хотелось бы чтобы сохранение шло в Ansi--|
            HtmlCodeA := PChar(@Buffer[0]);                                                                      |
          ExecFibSql(TheApp.MainDBConnection.fdbApp,                                                             |
            'update WHAT_TODO_GROUPS ' +                                                                         |
            'set ' +                                                                                             |
            'artcle_group_text = :p1 ' +                                                                         |
            'where article_group_id = :p2',                                                                      |
            [HtmlCodeA, LastArticleID], fibtDct);    <------------------------------------------------------------
          Result := S_OK;
        finally
          ss.Free;
        end;
      end;
    end;

Автор: DelphiLexx 14.09.07, 14:41
1) Как очистить документ
2) Как оранизовать progressbar загрузки документа.

Powered by Invision Power Board (https://www.invisionboard.com)
© Invision Power Services (https://www.invisionpower.com)