Форум: "Основная";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.04.18;
Скачать: [xml.tar.bz2];




Вниз

Отдельный Font для каждой ячейки StringGrid и т.д. 


eSKey   (2002-04-03 17:58) [0]

Помогите, плз, как правильно сделать возможность задания фонта для каждой отдельной ячейки stringgrid"a?
И еще - как выводить ее на печать - т.е ввиде таблицы, и правильно размещая на странице.



Song   (2002-04-03 18:00) [1]


> как правильно сделать возможность задания фонта для каждой
> отдельной ячейки stringgrid"a

Обрабатывайте onDrawCell и для смены шрифта используйте Canvas.Font


> И еще - как выводить ее на печать - т.е ввиде таблицы, и
> правильно размещая на странице.


Здесь нужно "ручками" выводить таблицу на канву принтера.



eSKey   (2002-04-03 19:03) [2]



> Обрабатывайте onDrawCell и для смены шрифта используйте
> Canvas.Font

А смена фонта канваса не будет генерировать событие на перерисовку? Я пробовал сперва в onDrawCell менять фонт самого грида - начинается кошмар Ж=(


> Здесь нужно "ручками" выводить таблицу на канву принтера.

Т.е - рисовать сетку, а потом текст - тоже, рассчитывая его кординаты? Да еще постраничное деление учитывать - ужас. А нет случайно готового компонента для печати таблиц?, - задача-то распространенная.



Song   (2002-04-03 23:14) [3]

2eSKey (03.04.02 19:03)
Поэтому ужас и происходил, т.к. вы меняли глобальное свойство font. Вы лучше делайте как Вам советуют. Canvas в этом случае будет распространяться на ту клетку, для которой событие onDrawCell возникает.
А что касается печати, да, Вы правы, так и надо делать, все эти "ужасные" операции. И компоненты есть - специальные гриды, где есть метод Print, посмотрите в кладовке. Но программисты пишут такие процедуры и для стандартного TStringGrid. Такой вопрос задаётся в форуме с периодичностью раз в две недели обычно, поэтому поищите, Вы найдёте e-mail тех людейа, у которых есть процедурка для распечатки грида. У меня тоже где-то была, если я найду, я дам Вам знать.



Fantasist   (2002-04-04 01:28) [4]

Хм... Интересно... Ведь Grid ресуется на DC формы, что, разве нельзя перерисовать то же самое на DC принтера?



Song   (2002-04-04 08:44) [5]

И на DC можно. Я делал через BitBlt. Тут способов уйма. Но все они трудоёмкие.



Леха   (2002-04-04 10:17) [6]

В принципе можно и копировать но возникают две проблеммы:
Что делать если таблица не влезает на один лист?
эта проблемма в принципе решаема
Шрифт размера 16 и шрифт размера 8 растянутый в два раза выглядят по разному

А вобще я печатью таблиц давно не занимаюсь проще скинуть в word или excel и пусть пользователь сам подправит что нужно и распечатает и ему удобней и мне меньше возни ;-)



Fantasist   (2002-04-04 10:39) [7]

>А вобще я печатью таблиц давно не занимаюсь проще скинуть в >word или excel и пусть пользователь сам подправит что нужно и >распечатает и ему удобней и мне меньше возни ;-)

Классное решение! :)
Дейстаительно, почему бы не сделать типа кнопку "Отчет" по которой создавать с помощью OLE какой-нибудь ExcelSheet и показвать его пользователю. И пусть что хочет то с ним и делает. Единственно что - тормознуто это маленько.



eSKey   (2002-04-04 11:33) [8]

Спасибо всем за помощь.
Конечно, пересылать в эксель и правда куда привлекательней, я бы и сам рад так сделать, но нужно учитывать возможность отсутствия у юзера мс-оффиса (это его право ;). Так что нужна собственная печать.



KSergey   (2002-04-04 14:01) [9]

По-моему, можно вполне взять какой-нибудь репортильник (тот же QReport очнь сойдет для таких дел) - и генерить отчет динамически по месту. Мне кажется, что так будет проще: и тебе на страницы худо-бедно разобъется, и ячейки отрисуются ну и т.д.



eSKey   (2002-04-05 14:01) [10]

Мастера! ерунда какая-то выходит.
Если в onDrawCell просто изменяю StrGrid.Canvas.Font - ничего не изменяется. Если сам вывожу текст через .Canvas.textrect - получается что мой вывод накладывается на собственный вывод Grid"а. Это при StrGrid.DefaultDrawing:=True, а если он False, тогда есессно не прорисовываются fixed-cells. Разъясните, плз подробно, для начинающего!

И еще вопрос по канвасу - он представляет собой _все_ возможное поле рисования того-же Grid или только его видимую в окне часть - т.е возможно ли сравнительно простое копирование Grid.Canvas на канвас принтера?



Song   (2002-04-05 14:35) [11]

2eSKey (05.04.02 14:01)
Естесно, нужно ставить StrGrid.DefaultDrawing:=False
И выводить самому сетку и надпись.
Разве трудно:
сетка: Rectangle
текст: TextOut
И зафиксинные ячейки не забудьте также рисовать сами.



reonid   (2002-04-05 14:39) [12]

Печать стринггрида:

Printer.BeginDoc;
K := Printer.Canvas.Font.PixelsPerInch / Canvas.Font.PixelsPerInch;
PrintStringGrid(StrGrid,
K, // Коэффициент
200, //отступ от края листа в пихелах по Х
200, // --"-- по Y
Printer.PageHeight - 200 // нижний предел
);
Printer.EndDoc;


{--------------------------------------------------------------}
unit GrdPrnEx;

interface

uses
Windows, Classes, Graphics, Grids, Printers, SysUtils;

procedure PrintStringGrid(Grid: TStringGrid; Scale: Double; dX, dY, Yfloor: Integer);

function DrawStringGridEx(Grid: TStringGrid; Scale: Double; FromRow, dX, dY,
Yfloor: Integer; ACanvas: TCanvas): Integer;
// возвращает номер строки, которая не поместилась до Y = Yfloor

// Недоработки:
// не проверяет, вылезает ли общая длина таблицы за пределы страницы
// Слишком длинное слово обрежется

implementation

procedure PrintStringGrid(Grid: TStringGrid; Scale: Double; dX, dY, Yfloor: Integer);
var NextRow: Integer;
begin
//Printer.BeginDoc;

if not Printer.Printing then raise Exception.Create("function PrintStringGrid must be called between Printer.BeginDoc and Printer.EndDoc");

NextRow := 0;
repeat
NextRow := DrawStringGridEx(Grid, Scale, NextRow, dX, dY, Yfloor, Printer.Canvas);
if NextRow <> -1 then Printer.NewPage;
until NextRow = -1;

//Printer.EndDoc;
end;

function DrawStringGridEx(Grid: TStringGrid; Scale: Double; FromRow, dX, dY,
Yfloor: Integer; ACanvas: TCanvas): Integer;
// возвращает номер строки, которая не поместилась до Y = Yfloor
var
i, j, d, TotalPrevH, TotalPrevW, CellH, CellW: Integer;
R: TRect;
s: string;

function ScaleRect(R: TRect): TRect;
begin
Result.Left := dX + Round(R.Left*Scale);
Result.Right := dX + Round((R.Right)*Scale);
Result.Top := dY + Round(R.Top*Scale);
Result.Bottom := dY + Round((R.Bottom)*Scale);
end;

procedure CorrectCellHeight(ARow: Integer); // вычисление правильной высоты ячейки
// с учетом многострочного текста
// Текст рабивается только по словам
// слишком длинное слово обрубается
var
i, H: Integer;
R: TRect;
s: string;
begin
s := ":)"; // ?
CellH := DrawText(Grid.Canvas.Handle, PChar(s), Length(s), R,
DT_LEFT or DT_TOP or DT_WORDBREAK or DT_CALCRECT) + 4;
for i := 0 to Grid.ColCount-1 do
begin
R := Rect(0, 0, Grid.ColWidths[i], CellH);
InflateRect(R, -2, -2);
s := Grid.Cells[i, ARow];
H := DrawText(Grid.Canvas.Handle, PChar(s), Length(s), R,
DT_LEFT or DT_TOP or DT_WORDBREAK or DT_CALCRECT or DT_NOPREFIX); // Вычисление ширины и высоты текста
if CellH < H + 4 then CellH := H + 4;
// if CellW < R.Right - R.Left then Слишком длинное слово - не помещается в одну строку;
end;
end;

begin
Result := -1; // все строки уместились между dY и Yfloor
if (FromRow < 0)or(FromRow >= Grid.RowCount) then Exit;

d := Round(2*Scale);

ACanvas.Brush.Style := bsClear;
ACanvas.Font := Grid.Font;
ACanvas.Font.Height := Round(Grid.Font.Height*Scale);

TotalPrevH := 0;

for j := 0 to Grid.RowCount-1 do
begin
if (j >= Grid.FixedRows) and (j < FromRow) then Continue;
// Fixed Rows рисуются на каждой странице

TotalPrevW := 0;
CellH := Grid.RowHeights[j];
CorrectCellHeight(j);

if dY + Round( (TotalPrevH + CellH)*Scale) > YFloor then
begin
Result := j; // j-я строка не помещается в заданный диапазон
Exit;
end;

for i := 0 to Grid.ColCount-1 do
begin
CellW := Grid.ColWidths[i];

R := Rect(TotalPrevW, TotalPrevH, TotalPrevW + CellW, TotalPrevH + CellH);
R := ScaleRect(R);

if (i < Grid.FixedCols)or(j < Grid.FixedRows) then ACanvas.Pen.Width := 3
else ACanvas.Pen.Width := 1;

ACanvas.Rectangle(R.Left, R.Top, R.Right+1, R.Bottom+1);
InflateRect(R, -d, -d);

s := Grid.Cells[i, j];
DrawText(ACanvas.Handle, PChar(s), Length(s), R,
DT_LEFT or DT_TOP or DT_WORDBREAK or DT_NOPREFIX);

TotalPrevW := TotalPrevW + CellW;
end;

TotalPrevH := TotalPrevH + CellH;
end;
end;

end.



eSKey   (2002-04-05 14:59) [13]


> reonid

Спасибо, буду разбираться! Копирайты ставить? :)


> Song


> И зафиксинные ячейки не забудьте также рисовать сами.

Но они же с "З-д эффектом"! Т.е. я не знаю как его рисовать самому - ведь простой заливкой не обойдешься. Или есть специальная готовая функция?



Song   (2002-04-05 15:13) [14]

2Просто нарисуйте кнопку (TButton) соотвествующих размеров без Caption"а



reonid   (2002-04-05 15:20) [15]

3D: Есть специальная функция

DrawEdge(Canvas.Handle, Rect, {BDR_RAISEDINNER or}BDR_RAISEDOUTER, BF_RECT);



vrRaven   (2002-04-07 19:28) [16]

На первый вопрос:

У меня есть компонент: CStringGrid - он и цвет фона умеет задавать и шрифт...

Пиши mailto:vr-raven@yandex.ru - вышлю(в конференцию я заглядываю редко)




Форум: "Основная";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.04.18;
Скачать: [xml.tar.bz2];




Наверх





Память: 0.76 MB
Время: 0.023 c
4-57924           alexey1               2002-02-13 04:43  2002.04.18  
open/save dialogs


7-57908           harisma               2001-10-31 16:02  2002.04.18  
ИК порт и работа с ним


1-57729           Evgenyk               2002-04-08 15:49  2002.04.18  
Как убрать Rectangle в ComboBox?


3-57659           kronprince            2002-03-28 22:34  2002.04.18  
Скорость работы TClientDataSet при фильтрации ?


1-57675           Gamar                 2002-04-07 14:34  2002.04.18  
Шрифты!!!