Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > TWebBrowser и копирование страницы


Автор: Pcrepair 14.12.2011, 16:06
Добрый день. Есть простой код браузера, позволяющий скачать странцу, "выделить все" на странице и скопировать в буфер обмена ОС. все работает (кроме ХТМЛ-страниц с фреймами, там ничего не выделяется)
Но использовать Буфер обмена нежелательно, его могут использовать и другие программы что может привести к ошибкам
вот текущий код:
Код

procedure TForm1.Button1Click(Sender: TObject);
var
  URL, Flags, TargetFrameName, PostData, Headers: Olevariant;
begin
  URL := Edit1.Text;
  Flags := 0;
  TargetFrameName := 0;
  Postdata := 0;
  Headers := 0;
  EmptyParam;
  WebBrowser1.Navigate(URL, Flags, TargetFrameName, PostData, Headers);
  repeat
    Application.ProcessMessages;
  until WebBrowser1.ReadyState >= READYSTATE_COMPLETE;
  if WebBrowser1.Document <> nil then
  (Webbrowser1.Document as IHTMLDocument2).ParentWindow.Focus;
  WebBrowser1.ExecWB(OLECMDID_SELECTALL,OLECMDEXECOPT_DONTPROMPTUSER);
  Application.ProcessMessages;
  if (Webbrowser1.Document as IHTMLDocument2).queryCommandEnabled('Copy') then
  WebBrowser1.ExecWB(OLECMDID_COPY,OLECMDEXECOPT_DONTPROMPTUSER); //вот тут копируем в буфер обмена
  Application.ProcessMessages;
end;

initialization
  Set8087CW($133F);
  OleInitialize(nil);
finalization
  OleUninitialize;
end.

ВОПРОС: каким образом копировать содержимое страницы в ПЕРЕМ?
Наверно что то вроде:
Код

var
HTML : TMemoryStream; //та самая ПЕРЕМ, далее остальной код, меняем {WebBrowser1.ExecWB(OLECMDID_COPY,OLECMDEXECOPT_DONTPROMPTUSER);} на что то типа

if (Webbrowser1.Document as IHTMLDocument2).queryCommandEnabled('Copy') then
  begin
    HTML := TMemoryStream.create; //создадим поток
     вот тут какой то код, который переносит в ПЕРЕМ содержимое контейнера браузера
  end;
Application.ProcessMessages; //хотя зачем это несовсем понятно
end;

Если кто в курсе, подскажите код
Заранее спасибо.

Автор: MetalFan 14.12.2011, 17:55
зачем же через буфер обмена?
IHTMLDocument2.Body.innerHTML (или outerHTML) ?

з.ы. поправь заголовк темы. а то там кто-то кого-то куда-то вПЕР..

Автор: Pcrepair 15.12.2011, 13:50
Цитата

зачем же через буфер обмена?
IHTMLDocument2.Body.innerHTML (или outerHTML) ?

через буфер обмена не надо, надо в ПЕРЕМенную. вопрос в том как это сделать корректно

Цитата

з.ы. поправь заголовк темы. а то там кто-то кого-то куда-то вПЕР..

что то не нашел где править?

Автор: MetalFan 15.12.2011, 14:35
Цитата(Pcrepair @  15.12.2011,  13:50 Найти цитируемый пост)
как это сделать корректно


Цитата(MetalFan @  14.12.2011,  17:55 Найти цитируемый пост)
IHTMLDocument2.Body.innerHTML (или outerHTML) ?

?

Автор: Pcrepair 16.12.2011, 17:56
приискал вот такое решение

Код

var
  Form1: TForm1;
  MS : Variant;

.....................
if (Webbrowser1.Document as IHTMLDocument2).queryCommandEnabled('Copy') then
  Application.ProcessMessages;
  MS := (WebBrowser1.Document as IHTMLDocument2).body.innerHTML;
  begin
     MEMO;
  end;
end;

procedure TForm1.MEMO; // для проверки
    begin
      Memo1.Clear;
      Memo1.Text := MS;
    end;



но .body.innerHTML почемуто неправильно копирует сслылки, к примеру
то что в коде страницы, ЕСЛИ ВРУЧНУЮ копировать в ХТМЛ-редактор

Код

<a target="_top" href="http://vkontakte.ru/login?act=forgot">Не можете войти?</A>


а вот это в коде самой страницы, отсутствует протокол и имя сервера

Код

<A href="/login?act=forgot" target=_top>Не можете войти?</A>


как такое вообще получается и что с этим можно сделать?

Автор: MetalFan 16.12.2011, 18:03
Цитата(Pcrepair @  16.12.2011,  17:56 Найти цитируемый пост)
как такое вообще получается и что с этим можно сделать? 

ну какбы такую сервер отдает страницу. Зачем ему прописывать полные пути то?
А браузер видимо уже автоматом подставляет текущий протокол, сервер, порт, путь и т.п.
Что сделать - а надо ли что-то с этим делать то? если да, то "пробежаться" по всем anchor'ам и допрописать нужную информацию в href.
Хотя возможно есть стандартный способой, но я его не знаю.

Автор: Pcrepair 17.12.2011, 22:37
вот еще вариант
- копируем в буфер обмена
- из буфера обмена копируем в ПЕРЕМ типа HTML : TClipboard;
- обнуляем буфер обмена. времени на это пойдет миллисекунды, вероятность размещения в буфере данных из других программ практически сходит на нуль
- копируем из ПЕРЕМ в МЕМО, для контроля
итого
Код


WebBrowser1.ExecWB(OLECMDID_COPY,OLECMDEXECOPT_DONTPROMPTUSER);
  Application.ProcessMessages;
  begin
      HTML.Free; //обнуляем ПЕРЕМ перед новым циклом
      HTML := TClipboard.Create;
      HTML := Clipboard; //копируем содер. Буфера в ПЕРЕМ типа строка
      Clipboard.Clear;  //очищаем Буфер обмена
      Memo1.Clear;  //очистить МЕМО
      Memo1 := HTML;  //копировать содержимое в МЕМО из ПЕРЕМ
  end;
end;


но вот проблема - на строке Memo1 := HTML; компилятор пишет: несовместипые типы
никто не в курсе что тут млжно сделать? чтоб в МЕМО поместить данные из буфера?

Автор: MetalFan 17.12.2011, 22:53
Pcrepair, да что-то жесть какая-то понаписана...
Код

uses Clipbrd;
...
var
  ClipboardText: string;
...
  ClipboardText := Clipboard.AsText;
  

Автор: Pcrepair 17.12.2011, 23:12
Теперь компилятор компилирует
Код

begin
      //HTML.Free; //обнуляем ПЕРЕМ перед новым циклом
      //HTML := TClipboard.Create;
      HTML := Clipboard.AsText; //копируем содер. Буфера в ПЕРЕМ типа строка
      Clipboard.Clear;  //очищаем Буфер обмена
      Memo1.Clear;  //очистить МЕМО
      Memo1.Text := HTML;  //копировать содержимое в МЕМО из ПЕРЕМ
  end;
end;

НО..... в МЕМО выводится только тестовая часть страницы, а ХТМЛ-код пропал
может можно что то типа HTML := Clipboard.AsHtml; ????
Еще раз, если в автомате сделать КОНТР+А и КОНТР+С (это делает выше стоящий код) то, если вставить потом код в ХТМЛ-редактор, там ссылки имеют полный путь. просто хотелось проверить, что на самом деле содержит буфер обмена ОС, действительно Ишак ссылки восстановил, или все же это работа ХТМЛ-редактора

Автор: MetalFan 18.12.2011, 00:24
В общем приятных извращений с буфером.
Я предложил внятный и самый на мой взгляд правильный вариант (через innerHTML). 

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