Візуальний html редактор своїми руками

Розглянемо загальний принцип роботи з цими елементами. Як і у випадку з текстом, перш за все треба створити об'єкт-виділення (назвемо його Range):

Інтерфейс 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 filesporshe1.jpg') end
else
begin
TextRange: = (editor.selection.createRange as IHTMLTxtRange);
TextRange.execCommand ( 'InsertImage', false, 'C: my filesporshe1.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;

var
i, j: integer;
ovTable: OleVariant;
t: HTMLTable;
begin
// У документі повинна бути таблиця, описана приблизно так:
//

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;

Схожі статті