Delphi word выравнивание текста
Очень часто, когда поднимается вопрос о дизайне программы, программисты начинают изобретать решения, чтобы их программы нормально выглядели при разных размерах форм. Пишут тонны кода, которые не дают уменьшаться форме меньше положенного или вообще не дают изменять размер. Пишут код для того, чтобы при изменении размеров формы компоненты аккуратно заполняли её.
Но оказывается, что многие задачи в Delphi уже решены, надо только уметь использовать их. Рассмотрим свойства компонентов, которые так или иначе связаны с позиционированием компонентов относительно друг друга, а потом и несколько примеров для реализации типичных интерфейсов программ. Свойства будут рассмотрены в алфавитном порядке, так что при чтении, возможно, придется "прыгать".
Align (выравнивание)
Свойство заставляет компонент менять некоторые из своих размеров и положение при изменении размеров компонента-родителя. Возможные значения:
alNone – значение по умолчанию, положение компонента зависит только от Left, Top, Width, Height.
alBottom – компонент "прижимается" к нижней части компонента-родителя. Занимает всю доступную ширину родителя. Работает только свойство Height. Если есть два компонента, один из которых имеет alBottom (или alTop), а второй alLeft (alRight), то первый компонент займёт максимальную высоту, а второй разместится в оставшейся части.
alTop – компонент "прижимается" к верхней части компонента-родителя. Остальное – аналогично alBottom.
alLeft - компонент "прижимается" к левой части компонента-родителя. Занимает всю доступную высоту родителя. Работает только свойство Width.
alRight - компонент "прижимается" к правой части компонента-родителя. Аналогичен alLeft.
alClient – компонент занимает всё доступное пространство компонента-родителя. Если есть компоненты с другими выравниваниями, то вначале выравниваются они. Нельзя разместить на одном родителе два компонента с этим типом выравнивания.
AlignWithMargins (выравнивать с учетом отступов)
Указывает на то, что при использовании свойства Align, нужно учитывать свойство Margins. О нём - ниже.
Anchors
С английского названия этого свойства переводиться как "якорь". Позволяет закрепить края компонента к краям родителя таким образом, чтобы при изменении размеров родителей расстояние между заданными краями оставалось постоянным. Свойство представляет собой множество (set). В инспекторе объектов редактируется как 4 вложенных свойства типа Boolean. По умолчанию выставлены только akTop и akLeft.
Чтобы понять, как это свойство работает, сделайте такие два эксперимента. Поставьте на форму панель (можно кнопку), сделайте размеры такими, чтобы компонент занимал по площади где-то половину формы и был размещён в центре. Выставьте все четыре подсвойства в True. Запустите программу и изменяйте мышкой размеры формы, понаблюдайте эффект. Также попробуйте выставлять только некоторые подсвойства равными True.
Это свойство появилось с 4, то ли c 5 версии Delphi.
AutoSize (авторазмер)
Если значение свойства - True, то компонент пытается занять минимальный размер, при котором на нём вмещаются все его дочерние компоненты без сдвига оных. В случае, если на компоненте нет ничего, то он может ужаться до нулевых размеров (так поступает панель). Не все компоненты имеют это свойство.
Constraints (ограничивающее условие)
Иногда бывает, что нежелательно, чтобы компонент увеличивал (или уменьшал) свои размеры больше какой-то величины. Поэтому его размеры можно и нужно ограничить. Это свойство имеет четыре подсвойста: MaxHeight, MaxWidth, MinHeight и MinWidth, названия которых сами говорят за себя. Если например, в свойство MaxHeight формы вписать число 400, то увеличить высоту формы больше 400 не получится. Число 0 означает игнорирование данного ограничения. Понятное дело, что MaxHeight >= MinHeight, и аналогично с шириной. Если попытаться нарушить условие, то Delphi поправит за вами, уравняв их. Кстати, при этом наблюдается интересный эффект. Если MaxHeight = MinHeight, то у компонента (формы) нельзя изменить высоту. А ширину – можно. Развернуть в полный экран тоже не получится. Рекомендую поэкспериментировать с этим свойством. Хотя его применение и достаточно ограничено.
Height (высота)
Указывает высоту компонента в пикселях. Игнорируется при некоторых установках свойств Align и Anchors.
Left (слева)
Указывает на расстояние в пикселях от левого края компонента до левого края компонента-родителя (обычно это форма). Игнорируется при некоторых установках свойств Align и Anchors.
Margins (кромка, край; приграничная область)
Это свойство начинает проявлять себя только если AlignWithMargins = True. В таком случае можно указать, на сколько меньше должен занимать компонент при выравнивании. Вокруг компонента как бы создаётся отступ. Посмотрите на рисунок, где для нижней панели все 4 подсвойства выставлены по 10 и сравните с предыдущим рисунком.
Padding (заполнение)
Это свойство чем-то подобно свойству Margins. Только действует для вложенных в данный родительский компонент дочерних компонент. То есть, выставив равным все 4 подсвойства по 10, а для вложенного компонента сделав Align = alClient, получим, что компонент не займёт всё пространство, а останется каемка в 10 пикселей. Смотрим на рисунок.
Естественно, выставлять все 4 подсвойства одинаковыми не обязательно. И как всегда, чтобы увидеть всю прелесть этого свойства, меняем размеры формы мышкой и наблюдаем.
Top (верх)
Указывает на расстояние в пикселях от верхнего края компонента до верхнего края компонента родителя (обычно это форма). Игнорируется при некоторых установках свойств Align и Anchors.
Width (ширина)
Указывает на ширину компонента в пикселях. Игнорируется при некоторых установках свойств Align и Anchors.
Примеры реальных приложений
Попробуем "сымитировать" интерфейс некоторых популярных приложений, чтобы расположение компонентов было одинаковым.
Блокнот
Да, да, тот Блокнот, который есть в Windows.
- Ставим на форму меню (TMainMenu). Заполняем.
- Ставим на форму TStatusBar. Замечаем, что у него автоматически срабатывает Align=alBottom.
- Ставим на форму TMemo. Выставляем Align=alClient.
Осталось только реализовать меню и приложение готово. Запустите и посмотрите, как при изменении размеров наше приложение ведёт себя аналогично Блокноту.
The Bat!
Теперь усложним задачку. Сымитируем интерфейс популярного почтовика. Кстати, он написан на Delphi.
- Ставим на форму меню (TMainMenu), заполняем пунктами по вкусу (нужно создать хотя бы два-три пункта, иначе теряется весь эффект).
- Ставим CoolBar.
- Ставим на CoolBar два тулбар (TToolBar). Замечаем, как они выравниваются по верхней кромке.
- Выбираем верхний тулбар и заполняем свойства Menu = MainMenu1, AutoSize = True, и, если у вас Delphi 2007, то и DrawingStyle = dsGradient.
Теперь у нас два меню, что ж, уберём лишнее – выделим форму и свойство Menu сделаем пустым.
- Ставим на форму ImageList, кликаем дважды по нему и наполняем его иконками.
- Выставим свойство Images у ToolBar2 равным ImageList. Замечаем, как у добавленных кнопок появились картинки. Они все одинаковы, поэтому кликаем по каждой и с помощью свойства ImageIndex выбираем понравившиеся. В конце выставляем свойство AutoSize = True для этого тулбара.
- Для CoolBar также выставляем AutoSize = True. Замечаем, как всё "уляглось".
- Ставим на форму TStatusBar.
- Ставим на форму TreeView, выставляем Align = alLeft. Ширину делаем где-то на треть формы.
- Ставим на форму компонент TSplitter (вкладка Additional). Внимательно - кликайте именно по форме, иначе он может выровняться по самому левому краю формы – в таком случае возьмите и перетащите его на место. Он автоматом выставляет Align = alLeft.
- На оставшееся пространство ставим панель, и выставляем Align = alClient.
- Теперь на панель ставим ListView, выставляем свойства Style = vsReport, Align = alTop. С помощью свойства Columns добавляем колонки.
- Ставим на панель TSplitter. Выставляем Align = alTop. Компонент автоматом примет горизонтальное положение.
- В оставшуюся часть панели ставим компонент TWebBrowser или TRichEdit (Чем вы решите отображать содержимое письма). Выставляем Align = alClient.
Запускаем, наслаждаемся. У меня получилось так:
Особенности – компоненты автоматически подгоняют размер при изменении размеров формы, границы между TreeView, ListView и просмотрщиком писем можно менять при запущенной программе. И самая главная особенность - достаточно профессиональный интерфейс мы получаем стандартными компонентами и без единой строчки кода!
Интересные заметки
1. Если один или несколько компонентов полностью заполняют своего родителя, то выделить мышкой самого родителя невозможно. И для многих это трагедия – они не знают, что делать. Можно, конечно, в инспекторе объектов в выпадающем списке поискать подходящий, но обычно и имени нужного компонента мы не помним. А всё просто. Выделяем любой компонент, который лежит на заданном компоненте, и жмём Esc. И, вуаля, выделен компонент-родитель! Ещё одно нажатие - и выделение уходит к родителю родителя. Это будет продолжаться до тех пор, пока выделение не перейдёт к форме. В примере почтовика, можно, нажав три раза Esc, гарантировано дойти до формы.
2. Если случайно компонент поставили не на того родителя, то перетянуть мышкой его уже нельзя. Удалять и ставить по-новому? НЕТ! На помощь приходит клавиатура. Выделяем нужный компонент (или несколько, просто зажав Shift). Потом жмём Ctrl+X (вырезать). Кликаем по нужному компоненту-родителю и жмём Ctrl+V (вставить). Более того, таким образом можно переносить компоненты между формами и даже проектами! А можно "вставить" не на форму, а в Блокнот. Присмотревшись, можно понять, как в виде текста представлен компонент, и даже подредактировать его. А потом и вставить на другую форму.
3. Если несколько компонентов находятся на форме, то их можно выделить, просто "охватив мышкой". То есть, провести по диагонали так, что бы в полученный прямоугольник попали нужные компоненты. А вот если компоненты находятся на панели, то так уже не получится – мы просто перемещаем панель. Решение простое. Просто нажмите Ctrl на клавиатуре и выделяйте как обычно.
5. В случае наличия на форме большого количества Edit'ов, многие пользователи любят переключаться между ними с помощью Tab. Но как только в своей программе попробуешь сделать это – курсор прыгает между ними, как ему вздумается. Кликаем правой кнопкой, в меню TabOrder выставляем стрелочками нужный порядок. Пусть пользователи радуются.
Заключение
Помните, что красивый и удобный интерфейс вашей программы привлекает пользователя, и он может закрыть глаза на некоторые недоделки или отсутствующую функциональность. Но некоторые люди почему-то считают, что сделав форму разноцветной, с большими кнопками и дивными шрифтами, их программа – верх совершенства. Поверьте, половина пользователей удалит такую программу и соседу закажет. А если вы, исходя из каких-то внутренних убеждений, считаете, что без такой красоты обойтись нельзя, сделайте её хотя бы настраиваемой.
Автор: Вадим К
Статья добавлена: 12 июня 2008
Зарегистрируйтесь/авторизируйтесь,
чтобы оценивать статьи.
Статьи, похожие по тематике
Для вставки ссылки на данную статью на другом сайте используйте следующий HTML-код:
Ссылка для форумов (BBCode):
Поделитесь ссылкой в социальных сетях:
Комментарии читателей к данной статье
Пока нет комментариев к данной статье. Оставьте свой и он будет первым.
TForm1 = class(TForm)
ToolBar1 : TToolBar;
Button1 : TButton;
Label1 : TLabel;
end;
var
Form1 : TForm1;
procedure TJopa.DoDrawText(var Rect : TRect; Flags : Integer);
var
i, dx, n : Longint;
s : string;
begin
Canvas.Font := Font;
s := Text;
dx := Rect.Right;
DrawText(Canvas.Handle, PChar(Text), -1, Rect, DT_CALCRECT);
if s <> "" then
dx := (dx - Rect.Right) div Length(s);
Этот же алгоритм применяешь, но не для букв, а для слов, и все будет так, как ты хочешь.
if Text = "" then Exit;
Canvas.Font := Font;
Delta := Width - Canvas.TextWidth(Text);
SpaceSize := Delta div Length(Text);
кстати, ворд вооще выравнивает строку по ширине, только если за ней следует ещё одна строка. если строки нет (строка последняя или единственная) - то она выравнивается по умолчанию.
procedure TJopa.DoDrawText(var Rect: TRect; Flags: Integer);
var
Delta, I, SpaceSize, LastPos: Integer;
Text: string;
begin
if FIsFirstDraw then //private: FIsNotFirstDraw: Boolean
begin
FIsFirstDraw := not FIsFirstDraw;
Exit;
end;
Text := GetLabelText;
if Text = "" then Exit;
Canvas.Font := Font;
Delta := Width - Canvas.TextWidth(stringreplace(Text," ","",[rfReplaceAll]));
sl:=TStringList.Create;
sl.DelimitedText:=Text;
if Delta > 0
then
if sl.Count=1
then
begin
Canvas.TextOut(width-Canvas.TextWidth(Text), Rect.Top, sl[0]);
end
else
begin
SpaceSize := Delta div (sl.Count-1);
LastPos := Rect.Left;
for I := 0 to sl.Count-1 do
begin
Canvas.TextOut(LastPos, Rect.Top, sl[i]);
LastPos := LastPos + Canvas.TextWidth(sl[i]) + SpaceSize;
end;
end
else
Canvas.TextOut(0, Rect.Top, Text);
interface
uses Windows;
function width_aligned_text_draw(aDC: HDC;
var aRect: TRect;//aRect.Bottom - adjusted to drawn text rect bottom
aClipPartialLine: boolean;//stop on clipped line
aVertSpacing, //add 1/2 of font height (1 - 1,5; 2 - 2)
aIndent: integer;//first line indent
aText: string): integer;//return processed char count
implementation
function _draw_line(aDC: HDC; X, Y, width: integer; aLine: PChar; aLineLength: integer;
aPtsT: PIntegerArray): integer;//return passed chars
var pt_cnt, i, spaces, ext, add, spc: integer;
_size: TSize;
begin
Result:= 0;
if(aPtsT = nil)then exit;
pt_cnt:= aLineLength;
if( GetTextExtentExPointA(aDC, aLine, aLineLength, width, @pt_cnt, @aPtsT[0], _size) and
(pt_cnt > 0)
)then begin
if(pt_cnt < aLineLength)then begin
Result:= pt_cnt - 1;
//offset, not count
if(aLine[pt_cnt] <> " ")then
while((Result >= 0)and(aLine[Result]<>" "))do dec(Result);
spc:= Result + 1;
while((Result >= 0)and(aLine[Result] = " "))do dec(Result);
if(Result >= 0)then begin
spaces:= 0;
ext:= width - aPtsT[Result];
for i:= Result downto 1 do begin
dec(aPtsT[i], aPtsT[i - 1]);//absolute origin to spasing
if(aLine[i] = " ")then inc(spaces);
end;
if(aLine[0] = " ")then inc(spaces);
if(spaces > 0)then begin
add:= ext div spaces;
spaces:= ext mod spaces;//extra alignment points
for i:= 0 to Result do begin
if(aLine[i] = " ")then begin
inc(aPtsT[i], add);
if(spaces > 0)then begin
inc(aPtsT[i]);
dec(spaces);
end;
end;
end;
inc(Result);
ExtTextOut(aDc, X, Y, 0, nil, aLine, Result, @aPtsT[0]);
end else begin
inc(Result);
TextOut(aDc, X, Y, aLine, Result);
end;
Result:= spc;
end else begin
if(aLine[0] <> " ")then begin//all alpfa
Result:= pt_cnt - 1;
ext:= width - aPtsT[Result];
for i:= Result downto 1 do begin
dec(aPtsT[i], aPtsT[i - 1]);//absolute origin to spasing
end;
add:= ext div pt_cnt;
spaces:= ext mod pt_cnt;//extra alignment points
for i:= 0 to Result do begin
inc(aPtsT[i], add);
if(spaces > 0)then begin
inc(aPtsT[i]);
dec(spaces);
end;
end;
inc(Result);
ExtTextOut(aDc, X, Y, 0, nil, aLine, Result, @aPtsT[0]);
end;//else all spaces
end;
if(aLine[pt_cnt] = " ")then begin
Result:= pt_cnt;
while((Result < aLineLength)and(aLine[Result] = " "))do inc(Result);
end
end else begin
TextOut(aDc, X, Y, aLine, aLineLength);
Result:= aLineLength;
end;
end;
end;
function width_aligned_text_draw(aDC: HDC; var aRect: TRect;
aClipPartialLine: boolean;
aVertSpacing, aIndent: integer;
aText: string
): integer;
var pPts: PIntegerArray;
nPts: integer;
function _growPts(cnt: integer): PIntegerArray;
begin
if(nPts < cnt)then begin
if(pPts = nil)then Result:= SysGetMem(cnt)
else Result:= SysReallocMem(pPts, cnt);
if(Result <> nil)then begin
nPts:= cnt;
pPts:= Result;
end;
end else Result:= pPts;
end;
var height, width, vindent, offs, len, llen, _dlen: integer;
_size: TSize;
aln: DWORD;
pc: PChar;
clip_stop, top: integer;
begin
aln:= GetTextAlign(aDC);
SetTextAlign(aDC, TA_LEFT or TA_TOP or TA_NOUPDATECP);
nPts:= 0; pPts:= nil;
GetTextExtentPoint(aDC, "Wy", 2, _size);
height:= (_size.cy * (2 + aVertSpacing)) div 2;
offs:= 0; len:= Length(aText);
aRect:= aRect;
width:= aRect.Right - aRect.Left;
if(aIndent < 0)then aIndent:= 0;
vindent:= 0;
while(aIndent >= width)do begin
dec(aIndent, width);
inc(vindent, height);
end;
Result:= 0;
pc:= PChar(aText);
top:= aRect.Top;
clip_stop:= aRect.Bottom;
if(aClipPartialLine)then dec(clip_stop, height);
while((offs < len)and(top < clip_stop))do begin
llen:= parseLine(pc, len, offs);
if(llen = 0)then inc(top, height)
else if((top + vindent < clip_stop)and (_growPts(llen) <>nil))then begin
inc(top, vindent);
inc(pc, offs); dec(len, offs);
inc(Result, offs);
offs:= 0;
if(aIndent > 0)then begin
_dlen:= _draw_line(aDC, aRect.Left + aIndent, top, width - aIndent, pc, llen, pPts);
end else begin
_dlen:= _draw_line(aDC, aRect.Left, top, width, pc, llen, pPts);
end;
alexey_mas © ( 2007-04-06 14:03 ) [0]
Подскажите как в ворде можно выровнять вставляемые данные.
т.е. вставляется текст
Range1:=WordApplication.ActiveDocument.Paragraphs.Item(1).Range;
Range1.InsertAfter("Приход: "+"500,00");
Range1.InsertAfter("Приход2441: "+"222500,00");
Range1.InsertAfter("Приход123232: "+"3333500,00");
мне нужно выровнять суммы по правому краю, а текст по левому .
Пробовал вписывать пробелы в зависимости от длины формируемой строки - но это не дает желаемого эффекта.
Как можно выровнять?
Таблицу рисовать мне не нужно.
← →Думкин © ( 2007-04-06 14:22 ) [1]
а завести колонки?
← →Виталий Панасенко © ( 2007-04-06 14:37 ) [2]
ParagraphFormat.Alignment := wdAlignParagraphJustify;
> Думкин © (06.04.07 14:22) [1]
> а завести колонки?
Таблицу, а не колонки.. И в ячейках выравнивание нужное.. Саму таблицу сделать невидимой
//-Создаем таблицу для шапки - 3 колонки
Par1 := wdWord9TableBehavior;
Par2 := wdAutoFitFixed;
ActiveDocument.Tables.Add(Selection.Range, 2, 3, Par1, Par2);
//-Делаем ограничения ячейки невидимыми(непечатаемыми)
ActiveDocument.Tables.Item(1).Select;
Selection.Borders.Item(wdBorderTop).LineStyle := wdLineStyleNone;
Selection.Borders.Item(wdBorderLeft).LineStyle := wdLineStyleNone;
Selection.Borders.Item(wdBorderBottom).LineStyle := wdLineStyleNone;
Selection.Borders.Item(wdBorderRight).LineStyle := wdLineStyleNone;
Selection.Borders.Item(wdBorderHorizontal).LineStyle := wdLineStyleNone;
Selection.Borders.Item(wdBorderVertical).LineStyle := wdLineStyleNone;
Selection.Borders(wdBorderLeft).LineStyle := wdLineStyleNone;
Selection.Borders(wdBorderBottom).LineStyle := wdLineStyleNone;
Selection.Borders(wdBorderRight).LineStyle := wdLineStyleNone;
Selection.Borders(wdBorderHorizontal).LineStyle := wdLineStyleNone;
Selection.Borders(wdBorderVertical).LineStyle := wdLineStyleNone;
Selection.Borders(wdBorderDiagonalDown).LineStyle := wdLineStyleNone;
Selection.Borders(wdBorderDiagonalUp).LineStyle := wdLineStyleNone>
//-Заполняем таблицу данными
ActiveDocument.Tables.Item(1).Cell(1,1).Range.Font.Bold := 1;
ActiveDocument.Tables.Item(1).Cell(1,1).Range.Font.Underline := 1;
ActiveDocument.Tables.Item(1).Cell(1,1).Range.Font.Italic := 1;
ActiveDocument.Tables.Item(1).Cell(1,1).Range.Text := "Текст";
homm © ( 2007-04-06 14:39 ) [3]
> [2] Виталий Панасенко © (06.04.07 14:37)
Сложновато.
Не проще табуляцией сделать?
Виталий Панасенко © ( 2007-04-06 15:06 ) [4]
> мне нужно выровнять суммы по правому краю, а текст по левому
я так табуляцией не умею
alexey_mas © ( 2007-04-06 15:41 ) [5]
табуляцией проще бы было, но не понятно как угадать сколько их нужно ставить в каждой строке (у меня текст очень разной длины ) и какой код табуляции ?
← →Виталий Панасенко © ( 2007-04-06 16:28 ) [6]
> alexey_mas © (06.04.07 15:41) [5]
> табуляцией проще бы было, но не понятно как угадать сколько
> их нужно ставить в каждой строке (у меня текст очень разной
> длины ) и какой код табуляции ?
Не угадаешь
alexey_mas © ( 2007-04-06 16:50 ) [7]
> [6] Виталий Панасенко © (06.04.07 16:28)
>
> > alexey_mas © (06.04.07 15:41) [5]
> > табуляцией проще бы было, но не понятно как угадать сколько
>
> > их нужно ставить в каждой строке (у меня текст очень разной
>
> > длины ) и какой код табуляции ?
>
> Не угадаешь
ок , спасибо за пример с таблицей. так получилось
Styx_ ( 2007-04-06 16:51 ) [8]
> как угадать
надо не гадать, а правильно выставить выравнивание для табуляции. Подробности в справке Word.
homm © ( 2007-04-06 21:22 ) [9]
> табуляцией проще бы было, но не понятно как угадать сколько
> их нужно ставить в каждой строке
один.
Виталий Панасенко(дом) ( 2007-04-07 12:17 ) [10]
> homm © (06.04.07 21:22) [9]
>
> > табуляцией проще бы было, но не понятно как угадать сколько
> > их нужно ставить в каждой строке
>
> один.
>
Согласен. Даже никогда не обращал внимания.:-).. Но у таблицы есть преимущество: если текст перед цифрами длинный, то он лихо размещается в предыдущей колонке.. С табуляцией такого, по-моему, не сделаешь.
TStas © ( 2007-04-08 14:38 ) [11]
Если Вы в Москве живете, то в Библио Глобусе продается книжка Корнякова "Программирование документов и проложений. ". Я купил, много полезного узнал. Реально полезная книжка. И про выравнивание там тоже есть.
Выравнивание по центру в TEdit? TEdit не поддерживает выравниваение текста по центру и по правой стороне - лучше использовать компонент TMemo. Вам понадобится запретить пользователю нажимать Enter, Ctrl-Enter и всевозможные комбинации клавиш со стрелками, чтобы избежать появления нескольких сторк в Memo. Этого можно добиться и просматривая содержимое текста в TMemo в поисках кода возврата каретки (13) и перевода строки(10) на событиях TMemo Change и KeyPress. Можно также заменять код возврата каретки на пробел - для того чтобы позволять вставку из буфера обмена многострочного текста в виде одной строки.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
< Пример TEdit с выравниванием по центру © Song
в модификации Vit
>
type
TForm1 = class ( TForm )
procedure FormCreate ( Sender: TObject ) ;
private
< Private declarations >
public
< Public declarations >
end ;
< Обявляем класс нашего едита как потомок от стандартного>
type TMySuperEdit= class ( TCustomEdit )
public
< Внутри класса переопредялем процедуру CreateParams,
т.к. нужный нам стиль можно изменить только на создании или пересоздании
окна >
Procedure CreateParams ( Var Params: TCreateParams ) ; override ;
end ;
var
Form1: TForm1;
implementation
Procedure TMySuperEdit. CreateParams ( Var Params: TCreateParams ) ;
Begin
< Вызываем родительский обработчик, чтобы он сделал все процедуры по созданию объекта класса >
inherited CreateParams ( Params ) ;
< Изменяем стиль >
With Params Do Style:=Style or ES_CENTER;
End ;
procedure TForm1. FormCreate ( Sender: TObject ) ;
begin
< Создаём едит на основе нашего класса и кладём его на форму >
With TMySuperEdit. Create ( Self ) Do
Parent:= Self ;
end ;
End .
Для создания документа Microsoft Word из Delphi нужно создать переменную, ассоциированную с Word. Если Word еще не открыт, его нужно открыть. После этого с ним можно работать примерно как в Бейсике, для изучения которого я в Word-е создаю макросы и изучаю их код.
Работа с текстом
Сначала о самом простом - добавлении в документ Word нужной строки текста. Поместим на форму компоненты WordDocument, WordApplicationи WordParagraphFormat с палитры Servers. Нас интересуют в первую очередь свойство Range компонента WordDocument и свойство Selection компонента WordApplication. Классики утверждают, что они являются ссылкой на объекты Range и Selection. Range представляет из себя, проще говоря, кусок текста, это может быть как весь текст документа, так и любая его часть. Его пределы задаются двумя (или меньше) параметрами типа OleVariant.
Первый наш объект включает в себя весь текст документа, у второго мы ограничили пределы 5-м и 15-м символами, третий представляет из себя весь последующий текст документа, начиная с 5-го символа. Объект имеет несколько полезных методов, например, с его помощью можем добавить текст в документ:
Это мы вставили текст после выделенного Range. Точно также можем вставить текст и перед ним, для этого служит метод InsertBefore(). Текст, заключенный в объекте Range, можем получить так:
Кроме того, с помощью Range можем изменить шрифт в пределах объекта. Пример:
Если хотим отменить выделение жирным шрифтом, присваиваем 0. Аналогично можно сделать шрифт курсивом, подчеркнутым - наберите WordDocument1.Range.Font., и среда сама подскажет, какие могут быть варианты. Методы Select, Cut, Copy и Paste работают как в обычном тексте. С помощью Paste можем на место выбранного Range вставить не только строки, но и рисунок, находящийся в буфере обмена.
С помощью Range можем найти в документе нужную строку. Пусть в тексте содержится слово " picture" . Например, нам на его место надо будет вставить рисунок.
Такая процедура находит и выделяет нужный кусок текста.
Теперь про Selection, представляющий из себя выделенный фрагмент документа. Если выделения нет, это текущая позиция курсора в документе. С его помощью можем вставить что-либо на место выделенного фрагмента, сделать выравнивание, изменить шрифт. Он также имеет методы InsertAfter() и InsertBefore():
Форматирование выделенного текста происходит аналогично Range, например:
Для выравнивания проще воспользоваться компонентом WordParagraphFormat. Сначала только нужно " подключить" его к выделенному фрагменту текста:
Значения его свойства Alignment может принимать значения wdAlignParagraphCenter, wdAlignParagraphLeft, wdAlignParagraphRight, смысл которых очевиден. Имеются и методы Cut, Copy и Paste, которые в пояснениях вряд ли нуждаются:
Убираем выделение с помощью метода Collapse. При этом необходимо указать, в какую сторону сместится курсор, будет ли он до ранее выделенного фрагмента или после:
При этом выделение пропадет, а курсор займет позицию перед фрагментом текста. Если присвоить переменной значение wdCollapseEnd, то курсор переместится назад. Можно просто поставить в скобках " пустышку" :
Тогда свертывание выделения производится по умолчанию, к началу выделенного текста.
Читайте также: