На главную        
         

Визуальный HTML редактор своими руками.
Часть II.

В прошлый раз речь шла о том, как работать с текстом в HTML редакторе. В этот раз мы поговорим о том, как работать с другими объектами HTML страниц - контролами. К ним относятся всевозможные элементы управления, изображения, фреймы, таблицы.

Рассмотрим общий принцип работы с этими элементами. Как и в случае с текстом, прежде всего надо создать объект-выделение (назовем его Range):

Range: IHTMLControlRange;

Интерфейс IHTMLControlRange предназначен специально для выполнения различных операций с выделенными объектами страницы, однако, его совершенно невозможно применять для работы с текстовым выделением - вы получите исключительную ситуацию EIntfCastError с сообщением о том, что выбраннй интерфейс не поддерживается (тоже самое будет, если использовать IHTMLTxtRange для работы с контролами). Чтобы избегать подобных ситуаций, в интерфейсе IHTMLSelectionObject введено поле Type_: widestring. В зависимости от типа выделения оно будет содержать 'Control' или 'Text' (если ничего не выделено, то это поле будет содежать 'None'). Вот простой пример того, как можно вставить картинку в определенное место документа (как открыть документ в режиме редактирования было описано в первой статейке):

procedure TForm1.SpeedButton13Click(Sender: TObject);
var
  CtrlRange: IHTMLControlRange;
  TextRange: IHTMLTxtRange;
begin
  if editor.selection.type_='Control' then
    begin
      CtrlRange:=(editor.selection.createRange as IHTMLControlRange);
      if not CtrlRange.queryCommandEnabled('InsertImage') then
        Application.MessageBox('Not Supported!','');
      else
        CtrlRange.execCommand('InsertImage',false,'C:\my files\porshe1.jpg')     end
  else
    begin

      TextRange:=(editor.selection.createRange as IHTMLTxtRange);
      TextRange.execCommand('InsertImage',false,'C:\my files\porshe1.jpg')
    end;
end;

Обратите внимание на то, что когда веделен объект, мы используем метод queryCommandEnabled чтобы убедиться, что данную комманду можно выполнить над выделенным контролом. Это связано с тем, что, например, встроенный фрейм нельзя заменить на картинку. На самом деле это проверка необязательная, но я все же рекомендую её проводить во избежание неприятных последствий. Еще один метод - queryCommandSupported(CmdID: WideString): boolean позволяет выянить, поддерживается ли данная комманда данным типом выделения. Такие же методы есть и у интерфейса IHTMLTxtRange, но в данном случае в них нет необходимости.

С таблицами дело обстоит гораздо сложнеее. Контролы типа HTMLTable, HTMLRow и HTMLCell, согласно документации от Microsoft, предназначены для создания таблиц при формировании страницы на стороне сервера. Соответсвенно, в нашем случае возникают некоторые трудности: в частности, как добавить полученную таблицу в документ (во всяком случае, у меня ничего не вышло). Как вариант я предлагаю следующее: создавать таблицу типа HTMLTable, работать с ней так, как будто мы формируем документ на сервере, а затем, использовать свойство OuterHTML. Это поле содержит текстовое представление таблицы в формате HTML. Рассмотрим подробнее этот способ на примере: procedure TForm1.SpeedButton14Click(Sender: TObject);
var
  Table: HTMLTable;
  TextRange: IHTMLTxtRange;
  row: HTMLTableRow;
  Col: HTMLTableCol;
  i: integer;
begin
  if editor.selection.type_<>'Control' then
    begin
      table:=(editor.createElement('Table') as HTMLTable);
      for i:=0 to 3 do
        begin

           row:=(table.insertrow(i) as DispHTMLTableRow);
          col:=(row.insertCell(0) as DispHTMLTableCol);
          col.width:='200';
          col.style.borderColor:='#FF0000';
          col.innerText:='Ячейка #'+inttostr(i);
        end;
      table.style.bordercolor:='#00FF00';
      textrange:=(editor.selection.createrange as IHTMLTxtRange);
      textrange.pasteHTML(table.OuterHTML);
    end;
end;

На мой взгляд, этот пример достаточно информативен. Очевидное преимущество использования объекта HTMLTable и сопутствующих ему объектов состоит в том, что программисту не надо беспокоится о том, как описать на HTML то или иное свойство таблицы, нет необходимости работать со строками, писать парсеры и т.п. - таблица сама себя опишет. Однако, очевидным недостатком такого метода является то, что в последствии невозможно будет обратиться к созданной таблице как к объекту, и изменить её програмным методом (использование парсеров и интерпритаторов кода в расчет брать не будем).
[Дополнение от 27.07.2004:
Я еще несколько раз прочитал MSDN и нашел таки способ нормально работать с таблицами и ячейками. Вот простой пример того, как можно заменить текст в уже созданной таблице:

var
  i, j: integer;
  ovTable: OleVariant;
  t: HTMLTable;
begin
  // В документе должна быть таблица, описанная примерно так:
  //<table ... id="MyTable">

  ovTable := WebBrowser1.OleObject.Document.getElementsByName('MyTable').item(0);
  //WebBrowser1.OleObject.Document.getElementsByName('MyTable') -
  //это коллекция элементов (ведь несколько элементов могут иметь
  //id равный "MyTable"

  for i := 0 to (ovTable.Rows.Length - 1) do
    for j := 0 to (ovTable.Rows.Item(i).Cells.Length - 1) do
      ovTable.Rows.Item(i).Cells.Item(j).InnerText:='New text!';
end;

То есть теперь у нас есть возможность как получать данные из таблицы, так и заносить их туда в любой момент времени. Все свойства соответствуют свойствам DOM. Остается только сказать, что таким образом можно работать и с формами, и с изображениями, в общем со всем, что поддерживается в Объектной модели докумета (DOM).]
Если вы знаете более изящный способ работы с таблицами, или можете чем-то дополнить изложенное выше, очень прошу вас написать мне на e-mail : Samum2000@mail15.com

 

© Дизайн: B-studio, 2004.
© Боднар Денис aka Samum 2003-2004.

Внимание! При использовании материалов с этого сайта ссылка на www.samum2000.narod.ru обязательна!

Сайт создан в системе uCoz