Форум «Всё о Паскале» _ Delphi _ выравнивание в AdvStringGrid
Автор: Atreides 11.03.2012 14:01
Вопрос - столкнулся с задачей выравнивания в ячейках компонента AdvStringGrid, при этом нужно активировать свойство переноса слов на новые строки (свойство WordWrap:=true;) , чтобы умещались слова в заданную длину столбца и строки были высотой с текст в них.. Получается выравнивать по центру и строки с высотой выровнять, но текст по вертикали не ровняется, как быть? Событие ОнДроу не нашел ((
А сам по себе VAlignment := vtaCenter; работать не будет (при WordWrap выставленном в True). Претензии - разработчикам WinAPI.
Автор: Atreides 11.03.2012 15:59
А если не сложно, можно пример, для любого столбца
Автор: IUnknown 11.03.2012 18:10
Пример чего? Как выровнять текст в ячейке вертикально по центру? Как обычно: сначала DrawText с флагом DT_CALCRECT, это даст тебе в четвертом параметре прямоугольник, в который помещается текст. Разница размеров того прямоугольника, который передается в OnDrawCell и полученного из DrawText - это и есть значение, на которое нужно сдвинуть вывод текста. А потом - второй DrawText, уже без флага CALCRECT, для действительного вывода текста. У меня сейчас не установлен под Дельфи TMS Pack, только под Билдером. Вот так это выглядит на Билдере:
void __fastcall TForm1::asgDrawCell(TObject *Sender, int ACol, int ARow, TRect &Rect, TGridDrawState State) { TAdvStringGrid *grid = dynamic_cast<TAdvStringGrid*>(Sender); String s = grid->Cells[ACol][ARow]; TRect r = Rect;
procedure TfrmRabot.sgRabotDrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState); begin with sgRabot, sgRabot.Canvas do begin FillRect(Rect); SetBkMode(Handle, TRANSPARENT); Rect.Right:=Rect.Right -2; if (ACol = 0) or (ARow = 0) or (ACol >2) then // DT_SINGLELINE DrawText(Handle, Cells[ACol, ARow], -1, Rect, DT_VCENTER OR DT_WORDBREAK OR DT_CENTER) else DrawText(Handle, Cells[ACol, ARow], -1, Rect, DT_VCENTER OR DT_WORDBREAK OR DT_LEFT); end; end;
Косяк так и остался, если флаг DT_SINGLELINE, то все отлично, но нет переноса по строчкам, а вот если DT_WORDBREAK, есть перенос, но нет центровки. Выходит снова упор в косяк WinAPI?
Автор: IUnknown 13.03.2012 12:20
То есть, я понимаю так, что читать то, что написано и изучать приведенный код ты не желаешь? Я ж написал специально:
Цитата
сначала DrawText с флагом DT_CALCRECT, это даст тебе в четвертом параметре прямоугольник, в который помещается текст. <...> А потом - второй DrawText, уже без флага CALCRECT, для действительного вывода текста.
Где у тебя два вызова DrawText? Не вижу, вижу только один, непосредственный вывод текста. Где подсчет смещения отцентрированного текста относительно исходного Rect? Почему дословный перевод Билдеровского кода на Дельфи у меня отработал: (DrawCell - он у всех гридовых компонентов DrawCell, работать будет одинаково на любом гриде), а у тебя
Цитата
снова упор в косяк WinAPI?
? Может, упор в нежелание понимать, что происходит?
Автор: Atreides 15.03.2012 12:06
Дурная голова кривым рукам покоя не дает (( Еще вопрос, как запретить события он клик на всех ячейках кроме первого столбца. И если есть событие OnClick ячейки, то закрасить всю строку. Сделал так, но нажимается везде и везде прокрашивается только ячейка OnClick, при чем любая.
Код
procedure TfrmFrom1.AdvStringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState); const //здесь определяем Ваш цвет. Так же можно использовать цвета по умолчанию. clPaleGreen = TColor($CCFFCC); var grid:TAdvStringGrid; s: string; r :TRect; dx, dy,i: integer;
begin if (gdFocused in State) then begin AdvStringGrid1.Canvas.Brush.color := clPaleGreen end else AdvStringGrid1.Canvas.Brush.Color := clWindow; if (ARow > 0) and (ACol=0)then begin AdvStringGrid1.Canvas.FillRect(Rect); AdvStringGrid1.Canvas.TextOut(Rect.Left, Rect.Top, AdvStringGrid1.Cells[ACol, ARow]); end;
begin grid:=Sender as TAdvStringGrid; s:=grid.Cells[ACol, ARow]; r:=Rect; if ( Arow>=0 ) and ( ACol>=0 ) then begin grid.Canvas.FillRect(Rect); DrawText (grid.Canvas.Handle, s, Length(s), r, DT_CENTER or DT_WORDBREAK or DT_CALCRECT); dx:=((Rect.Right - Rect.Left) - (r.Right - r.Left)) div 2; dy:=((Rect.Bottom - Rect.Top) - (r.Bottom - r.Top)) div 2; offsetRect(r,dx,dy); DrawText (grid.Canvas.Handle, s, Length(s), r, DT_CENTER or DT_WORDBREAK); end else begin grid.Canvas.FillRect(Rect); DrawText (grid.Canvas.Handle, s, Length(s), r, DT_WORDBREAK or DT_CALCRECT); dx:=1; dy:=((Rect.Bottom - Rect.Top) - (r.Bottom - r.Top)) div 2; offsetRect(r, dx, dy); DrawText (grid.Canvas.Handle, s, Length(s), r, DT_WORDBREAK); end; end; end;