Советы по Delphi

         

Выравнивание колонок StringGrid V


Pavel Stont предлагает свой вариант TStringGrid'а с выравниванием строк:

    {
Код компонента для Delphi на основе стандартного TStringGrid.

Компонет позволяет переносить текст в TStringGrid.

В качестве исходного текста был использован компонент TWrapGrid.
Автор Luis J. de la Rosa.
E-mail: delarosa@ix.netcom.com
Вы свободны в использовании, распространении и улучшении кода.
Пожалуйста шлите любые комментарии и пожелания на адрес delarosa@ix.netcom.com.



Далее были внесены изменения в исходный код, а именно добавлены методы вывода
текста:
1. atLeft - Вывод текста по левой границе;
2. atCenter - Вывод текста по центру ячейки (по горизонтали);
3. atRight - Вывод текста по правой границе;
4. atWrapTop - Вывод и перенос текста по словам относительно верхней границы
ячейки;
5. atWrapCenter - Вывод и перенос текста по словам относительно центра ячейки
(по вертикали);
6. atWrapBottom - Вывод и перенос текста по словам относительно нижней границы
ячейки;

Вносил изменения и тестировал в Delphi 3/4/5:
Автор Pavel Stont.
E-mail: pavel_stont@mail.ru.
Никаких ограничений на использование, распростанение и улучшение кода не налогаются.
Буду очень признателен, если о всех замеченных неполадках сообщите по e-mail.

Для использования:
Выберите в Delphi пункты меню 'Options' - 'Install Components'.
Нажмите 'Add'.
Найдите и выберите файл с именем 'NewStringGrid.pas'.
Нажмите 'OK'.
После этого вы увидете компонент во вкладке "Other" палитры компонентов
Delphi.
После этого вы можете использовать компонент вместо стандартного TStringGrid.

Успехов!

Несколько дополнительных замечаний по коду:
1. Методы Create и DrawCell были перекрыты.
2. Введены два новых свойства, а именно AlignText и AlignCaption соответсвенно методы
выравнивания текста в ячейках данных (обычно - белого цвета) и в фиксированных ячейках
(обычно - серого цвета).
3. Свойство Center - центрация текста по горизонтали независимо от метода.
}

unit NewStringGrid;

interface

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Grids;
type
TAlignText=(atLeft,atCenter,atRight,atWrapTop,atWrapCenter,atWrapBottom);
type
TNewStringGrid = class(TStringGrid) private { Private declarations } FAlignText: TAlignText; FAlignCaption: TAlignText; FCenter: Boolean; procedure SetAlignText(Value: TAlignText); procedure SetAlignCaption(Value: TAlignText); procedure SetCenter(Value: Boolean); protected { Protected declarations } procedure DrawCell(ACol, ARow : Longint; ARect : TRect; AState : TGridDrawState); override; public { Public declarations } constructor Create(AOwner : TComponent); override; published { Published declarations } property AlignText: TAlignText read FAlignText write SetAlignText; property AlignCaption: TAlignText read FAlignCaption write SetAlignCaption; property Center: Boolean read FCenter write SetCenter; end;
procedure Register;

implementation

procedure Register
;
begin
RegisterComponents('Other', [TNewStringGrid]); end;

{ TNewStringGrid }

constructor TNewStringGrid.Create(AOwner: TComponent);
begin
{ Создаем TStringGrid } inherited Create(AOwner); { Задаем начальные параметры компонента } AlignText:=atLeft; AlignCaption:=atCenter; Center:=False; DefaultColWidth:=80; DefaultRowHeight:=18; Height:=100; Width:=408; { Заставляем компонент перерисовываться нашей процедурой по умолчанию DrawCell } DefaultDrawing:=FALSE; end;

{ Процедура DrawCell осуществляет перенос текста в ячейке }
procedure TNewStringGrid.DrawCell(ACol, ARow: Integer; ARect: TRect;
AState: TGridDrawState); var
CountI,                    { Счетчик } CountWord: Integer;        { Счетчик } Sentence,                  { Выводимый текст } CurWord: String;           { Текущее выводимое слово } SpacePos,                  { Позиция первого пробела } CurXDef,                   { X-координата 'курсора' по умолчанию } CurYDef,                   { Y-координата 'курсора' по умолчанию } CurX,                      { Х-координата 'курсора' } CurY: Integer;             { Y-координата 'курсора' } EndOfSentence: Boolean;    { Величина, указывающая на заполненность ячейки } Alig: TAlignText;          { Тип выравнивания текста } ColPen: TColor;            { Цвет карандаша по умолчанию } MassWord: Array [0..255] Of String; MassCurX,MassCurY: Array [0..255] Of Integer; LengthText: Integer;       { Длина текущей строки } MassCurYDef: Integer; MeanCurY: Integer;
procedure VisualCanvas; begin { Прорисовываем ячейку и придаем ей 3D-вид } With Canvas Do Begin { Запоминаем цвет пера для последующего вывода текста } ColPen:=Pen.Color; If gdFixed in AState Then Begin Pen.Color:=clWhite; MoveTo(ARect.Left,ARect.Top); LineTo(ARect.Left,ARect.Bottom); MoveTo(ARect.Left,ARect.Top); LineTo(ARect.Right,ARect.Top); Pen.Color:=clBlack; MoveTo(ARect.Left,ARect.Bottom); LineTo(ARect.Right,ARect.Bottom); MoveTo(ARect.Right,ARect.Top); LineTo(ARect.Right,ARect.Bottom); End; { Восстанавливаем цвет пера } Pen.Color:=ColPen; End; end;
procedure VisualBox; begin { Инициализируем шрифт, чтобы он был управляющим шрифтом } Canvas.Font:=Font; With Canvas Do Begin { Если это фиксированная ячейка, тогда используем фиксированный цвет } If gdFixed in AState Then Begin Pen.Color:=FixedColor; Brush.Color:=FixedColor; End { в противном случае используем нормальный цвет } Else Begin Pen.Color:=Color; Brush.Color:=Color; End; { Рисуем подложку цветом ячейки } Rectangle(ARect.Left,ARect.Top,ARect.Right,ARect.Bottom); End; end;
procedure VisualText(Alig: TAlignText); begin Case Alig Of atLeft:       Begin With Canvas Do { выводим текст } TextOut(CurX,CurY,Sentence); VisualCanvas; End; atRight:      Begin With Canvas Do { выводим текст } TextOut(ARect.Right-TextWidth(Sentence)-2,CurY,Sentence); VisualCanvas; End; atCenter:     Begin With Canvas Do { выводим текст } TextOut(ARect.Left+((ARect.Right-ARect.Left-TextWidth(Sentence)) div 2),CurY,Sentence); VisualCanvas; End; atWrapTop:    Begin { для каждого слова ячейки } EndOfSentence:=FALSE; CountI:=0; While CountI<=SpacePos Do Begin MassWord[CountI]:=''; CountI:=CountI+1; End; CountI:=0; CountWord:=CurY; While (not EndOfSentence) Do Begin { для получения следующего слова ищем пробел } SpacePos:=Pos(' ',Sentence); If SpacePos>0 Then Begin { получаем текущее слово плюс пробел } CurWord:=Copy(Sentence,0,SpacePos); { получаем остальную часть предложения } Sentence:=Copy(Sentence,SpacePos+1,Length(Sentence)-SpacePos); End Else Begin { это - последнее слово в предложении } EndOfSentence:=TRUE; CurWord:=Sentence; End; With Canvas Do Begin { если текст выходит за границы ячейки } LengthText:=TextWidth(CurWord)+CurX+2; If LengthText>ARect.Right Then Begin { переносим на следующую строку } CurY:=CurY+TextHeight(CurWord); CurX:=CurXDef+2; End; If CountWord<>CurY Then CountI:=CountI+1; MassWord[CountI]:=MassWord[CountI]+CurWord; { увеличиваем X-координату курсора } CurX:=CurX+TextWidth(CurWord); CountWord:=CurY; End; End; With Canvas Do Begin CountWord:=0; CurY:=CurYDef+2; CurX:=CurXDef+2; While CountWord<=CountI Do Begin Case Center Of True:  Begin CurWord:=MassWord[CountWord]; If Copy(CurWord,Length(CurWord)-1,1)=' ' Then MassWord[CountWord]:=Copy(CurWord,0,Length(CurWord)-1); MassCurX[CountWord]:=ARect.Left+((ARect.Right-ARect.Left-TextWidth(MassWord[CountWord])) div 2); MassWord[CountWord]:=CurWord; End; False: MassCurX[CountWord]:=CurX; End; MassCurY[CountWord]:=CurY; { выводим слово } TextOut(MassCurX[CountWord],MassCurY[CountWord],MassWord[CountWord]); CurY:=CurY+TextHeight(MassWord[CountWord]); CountWord:=CountWord+1; End; End; VisualCanvas; End; atWrapCenter: Begin { для каждого слова ячейки } EndOfSentence:=FALSE; CountI:=0; While CountI<=SpacePos Do Begin MassWord[CountI]:=''; CountI:=CountI+1; End; CountI:=0; CountWord:=CurY; While (not EndOfSentence) Do Begin { для получения следующего слова ищем пробел } SpacePos:=Pos(' ',Sentence); If SpacePos>0 Then Begin { получаем текущее слово плюс пробел } CurWord:=Copy(Sentence,0,SpacePos); { получаем остальную часть предложения } Sentence:=Copy(Sentence,SpacePos+1,Length(Sentence)-SpacePos); End Else Begin { это - последнее слово в предложении } EndOfSentence:=TRUE; CurWord:=Sentence; End; With Canvas Do Begin { если текст выходит за границы ячейки } LengthText:=TextWidth(CurWord)+CurX+2; If LengthText>ARect.Right Then Begin { переносим на следующую строку } CurY:=CurY+TextHeight(CurWord); CurX:=CurXDef+2; End; If CountWord<>CurY Then CountI:=CountI+1; MassWord[CountI]:=MassWord[CountI]+CurWord; { увеличиваем X-координату курсора } CurX:=CurX+TextWidth(CurWord); CountWord:=CurY; End; End; With Canvas Do Begin CountWord:=0; CurX:=CurXDef+2; While CountWord<=CountI Do Begin Case Center Of True:  Begin CurWord:=MassWord[CountWord]; If Copy(CurWord,Length(CurWord)-1,1)=' ' Then MassWord[CountWord]:=Copy(CurWord,0,Length(CurWord)-1); MassCurX[CountWord]:=ARect.Left+((ARect.Right-ARect.Left-TextWidth(MassWord[CountWord])) div 2); MassWord[CountWord]:=CurWord; End; False: MassCurX[CountWord]:=CurX; End; MassCurY[CountWord]:=TextHeight(MassWord[CountWord]); CountWord:=CountWord+1; End; CountWord:=0; MassCurYDef:=0; While CountWord<=CountI Do Begin MassCurYDef:=MassCurYDef+MassCurY[CountWord]; CountWord:=CountWord+1; End; MassCurYDef:=(ARect.Bottom-ARect.Top-MassCurYDef) div 2; CountWord:=0; MeanCurY:=0; While CountWord<=CountI Do Begin MassCurY[CountWord]:=ARect.Top+MeanCurY+MassCurYDef; MeanCurY:=MeanCurY+TextHeight(MassWord[CountWord]); CountWord:=CountWord+1; End; CountWord:=-1; While CountWord<=CountI Do Begin CountWord:=CountWord+1; If MassCurY[CountWord]<(ARect.Top+2) Then Continue; { выводим слово } TextOut(MassCurX[CountWord],MassCurY[CountWord],MassWord[CountWord]); End; End; VisualCanvas; End; atWrapBottom: Begin { для каждого слова ячейки } EndOfSentence:=FALSE; CountI:=0; While CountI<=SpacePos Do Begin MassWord[CountI]:=''; CountI:=CountI+1; End; CountI:=0; CountWord:=CurY; While (not EndOfSentence) Do Begin { для получения следующего слова ищем пробел } SpacePos:=Pos(' ',Sentence); If SpacePos>0 Then Begin { получаем текущее слово плюс пробел } CurWord:=Copy(Sentence,0,SpacePos); { получаем остальную часть предложения } Sentence:=Copy(Sentence,SpacePos+1,Length(Sentence)-SpacePos); End Else Begin { это - последнее слово в предложении } EndOfSentence:=TRUE; CurWord:=Sentence; End; With Canvas Do Begin { если текст выходит за границы ячейки } LengthText:=TextWidth(CurWord)+CurX+2; If LengthText>ARect.Right Then Begin { переносим на следующую строку } CurY:=CurY+TextHeight(CurWord); CurX:=CurXDef+2; End; If CountWord<>CurY Then CountI:=CountI+1; MassWord[CountI]:=MassWord[CountI]+CurWord; { увеличиваем X-координату курсора } CurX:=CurX+TextWidth(CurWord); CountWord:=CurY; End; End; With Canvas Do Begin CountWord:=0; CurX:=CurXDef+2; While CountWord<=CountI Do Begin Case Center Of True:  Begin CurWord:=MassWord[CountWord]; If Copy(CurWord,Length(CurWord)-1,1)=' ' Then MassWord[CountWord]:=Copy(CurWord,0,Length(CurWord)-1); MassCurX[CountWord]:=ARect.Left+((ARect.Right-ARect.Left-TextWidth(MassWord[CountWord])) div 2); MassWord[CountWord]:=CurWord; End; False: MassCurX[CountWord]:=CurX; End; MassCurY[CountWord]:=TextHeight(MassWord[CountWord]); CountWord:=CountWord+1; End; CountWord:=0; MassCurYDef:=0; While CountWord<=CountI Do Begin MassCurYDef:=MassCurYDef+MassCurY[CountWord]; CountWord:=CountWord+1; End; MassCurYDef:=ARect.Bottom-MassCurYDef-2; CountWord:=0; MeanCurY:=-MassCurY[CountWord]; While CountWord<=CountI Do Begin MeanCurY:=MeanCurY+MassCurY[CountWord]; MassCurY[CountWord]:=MassCurYDef+MeanCurY; CountWord:=CountWord+1; End; CountWord:=-1; While CountWord<=CountI Do Begin CountWord:=CountWord+1; If MassCurY[CountWord]<(ARect.Top+2) Then Continue; { выводим слово } TextOut(MassCurX[CountWord],MassCurY[CountWord],MassWord[CountWord]); End; End; VisualCanvas; End; End; end;
begin
VisualBox; VisualCanvas; { Начинаем рисование с верхнего левого угла ячейки }
CurXDef:=ARect.Left; CurYDef:=ARect.Top; CurX:=CurXDef+2; CurY:=CurYDef+2; { Здесь мы получаем содержание ячейки }
Sentence:=Cells[ACol,ARow]; { Если ячейка пуста выходим из процедуры }
If Sentence='' Then Exit; { Проверяем длину строки (не более 256 символов) }
If Length(Sentence)>256 Then Begin MessageBox(0,'Число символов не должно быть более 256.','Ошибка в таблице',mb_OK); Cells[ACol,ARow]:=''; Exit; End; { Узнаем сколько в предложении слов и задаем размерность массивов }
SpacePos:=Pos(' ',Sentence); { Узнаем тип выравнивания текста }
If gdFixed in AState Then Alig:=AlignCaption Else Alig:=AlignText; VisualText(Alig); end;

procedure TNewStringGrid.SetAlignCaption(Value: TAlignText);
begin
If
Value<>FAlignCaption Then FAlignCaption:=Value; end;

procedure TNewStringGrid.SetAlignText(Value: TAlignText);
begin
If
Value<>FAlignText Then FAlignText:=Value; end;

procedure TNewStringGrid.SetCenter(Value: Boolean);
begin
If
Value<>FCenter Then FCenter:=Value; end;

end.

[001796]



Содержание раздела