2010. március 29., hétfő
A VCL Component to print labels
Problem/Question/Abstract:
A simple component to print labels
Answer:
A simple VCL componet to print labels.
A few days ago I wrote an article about a class to print labels (3156)
With the help of Mike Heydon we have rewritten the class to convert it to a component and easier to use.
What do we need to print labels ?
The size (height and width) of every label.
The number of labels per row.
The top and left margin.
The kind of measure: pixels,inches or millimetres.
The font to use.
And of course data to fill the labels.
With the next component we can do it very simply, Im going to use a pseudo-code to explain the use of the component TPrtLabels:
begin
PrtLabels.Measurements := plmInches; // plmMillimetres or plmPixels
PrtLabels.Font := FontDialog1.Font; // I get the font from a Font Dialog
PrtLabels.LabelsPerRow := 4; // 4 Label per row
PrtLabels.LabelWidth := 3; // only an example
PrtLabels.LabelHeight := 1.5; // only an example
PrtLabels.LeftMargin := 0; // only an example
PrtLabels.TopMargin := 0; // only an example
PrtLabels.Open; // open the printer
Table.First // Im going to read a customer table
while not Table.Eof do
begin
PrtLabels.Add(["Name", "Street", "City"]); // I fill the content of every label
Table.Next;
end;
PrtLabels.Close; // close the printer and print any label pending on the buffer
PrtLabels.Free;
end;
We need only 3 methods: Open, Add and Close.
The properties that we need are:
Measurements(plmInches, plmMillimetres or plmPixels)
LabelsPerRow
LabelWidth
LabelHeight
LeftMargin
TopMargin
Font
The componet:
unit ULabels2;
{
VCL Component to print labels
Authors:
Mike Heydon
Alejandro Castro
Date: 1/Abr/2002
}
interface
uses SysUtils, Windows, Classes, Graphics, Printers;
type
TPrtLabelMeasures = (plmPixels, plmInches, plmMillimetres);
TPrtLabels = class(TComponent)
private
FFont: TFont;
FMeasurements: TPrtLabelMeasures;
FTopMargin,
FLeftMargin,
FLabelHeight,
FLabelWidth: double; // Selected Measure
FLabelLines,
FLabelsPerRow: word; // ABS Pixels
TopMarginPx,
LeftMarginPx,
LabelHeightPx,
LabelWidthPx: integer;
TabStops: array of word;
DataArr: array of array of string;
CurrLab: word;
procedure SetFont(Value: TFont);
procedure IniDataArr;
procedure FlushBuffer;
procedure SetDataLength(xLabelLines, xLabelsPerRow: Word);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Add(LabLines: array of string);
procedure Close;
procedure Open;
published
property Font: TFont read FFont write SetFont;
property Measurements: TPrtLabelMeasures read FMeasurements write FMeasurements;
property LabelWidth: double read FLabelWidth write FLabelWidth;
property LabelHeight: double read FLabelHeight write FLabelHeight;
property TopMargin: double read FTopMargin write FTopMargin;
property LeftMargin: double read FLeftMargin write FLeftMargin;
property LabelsPerRow: word read FLabelsPerRow write FLabelsPerRow;
// property LabelLines : word read FLabelLines write FLabelLines;
end;
procedure Register;
implementation
const
MMCONV = 25.4;
procedure Register;
begin
RegisterComponents('Mah2001', [TPrtLabels]);
end;
constructor TPrtLabels.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FMeasurements := plmInches;
FLabelHeight := 0.0;
FLabelWidth := 0.0;
FTopMargin := 0.0;
FLeftMargin := 0.0;
FLabelsPerRow := 1;
FLabelLines := 1;
FFont := TFont.Create;
TabStops := nil;
DataArr := nil;
end;
destructor TPrtLabels.Destroy;
begin
FFont.Free;
TabStops := nil;
DataArr := nil;
inherited Destroy;
end;
procedure TPrtLabels.SetFont(Value: TFont);
begin
FFont.Assign(Value);
end;
procedure TPrtLabels.SetDataLength(xLabelLines, xLabelsPerRow: Word);
begin
if (xLabelLines + xLabelsPerRow) > 1 then
SetLength(DataArr, xLabelLines, xLabelsPerRow);
end;
procedure TPrtLabels.Open;
var
PixPerInX, PixPerInY, i: integer;
begin
if (FLabelsPerRow + FLabelLines) > 1 then
begin
SetLength(TabStops, FLabelsPerRow);
SetDataLength(FLabelLines, FLabelsPerRow);
// SetLength(DataArr,FLabelLines,FLabelsPerRow);
Printer.Canvas.Font.Assign(FFont);
Printer.BeginDoc;
PixPerInX := GetDeviceCaps(Printer.Handle, LOGPIXELSX);
PixPerInY := GetDeviceCaps(Printer.Handle, LOGPIXELSY);
case FMeasurements of
plmInches:
begin
LabelWidthPx := trunc(LabelWidth * PixPerInX);
LabelHeightPx := trunc(LabelHeight * PixPerInY);
TopMarginPx := trunc(TopMargin * PixPerInX);
LeftMarginPx := trunc(LeftMargin * PixPerInY);
end;
plmMillimetres:
begin
LabelWidthPx := trunc(LabelWidth * PixPerInX * MMCONV);
LabelHeightPx := trunc(LabelHeight * PixPerInY * MMCONV);
TopMarginPx := trunc(TopMargin * PixPerInX * MMCONV);
LeftMarginPx := trunc(LeftMargin * PixPerInY * MMCONV);
end;
plmPixels:
begin
LabelWidthPx := trunc(LabelWidth);
LabelHeightPx := trunc(LabelHeight);
TopMarginPx := trunc(TopMargin);
LeftMarginPx := trunc(LeftMargin);
end;
end;
for i := 0 to FLabelsPerRow - 1 do
TabStops[i] := LeftMarginPx + (LabelWidthPx * i);
IniDataArr;
end;
end;
procedure TPrtLabels.Close;
begin
if (FLabelsPerRow + FLabelLines) > 1 then
begin
FlushBuffer;
Printer.EndDoc;
TabStops := nil;
DataArr := nil;
end;
end;
procedure TPrtLabels.IniDataArr;
var
i, ii: integer;
begin
CurrLab := 0;
for i := 0 to High(DataArr) do // FLabelLines - 1 do
for ii := 0 to High(DataArr[i]) do //FLabelsPerRow do
DataArr[i, ii] := '';
end;
procedure TPrtLabels.FlushBuffer;
var
i, ii, y, SaveY: integer;
begin
if CurrLab > 0 then
begin
if Printer.Canvas.PenPos.Y = 0 then
Printer.Canvas.MoveTo(0, TopMarginPx);
y := Printer.Canvas.PenPos.Y;
SaveY := y;
for i := 0 to fLabelLines - 1 do
begin
for ii := 0 to fLabelsPerRow - 1 do
begin
Printer.Canvas.TextOut(TabStops[ii], y, DataArr[i, ii]);
end;
inc(y, Printer.Canvas.Textheight('X'));
end;
if (LabelHeightPx + SaveY) + LabelHeightPx > Printer.PageHeight then
Printer.NewPage
else
Printer.Canvas.MoveTo(0, LabelHeightPx + SaveY);
IniDataArr;
end;
end;
procedure TPrtLabels.Add(LabLines: array of string);
var
i: integer;
begin
if Length(LabLines) > FLabelLines then
begin
FLabelLines := Length(LabLines);
SetDataLength(fLabelLines, fLabelsPerRow);
end;
inc(CurrLab);
for i := 0 to high(LabLines) do
if i <= FLabelLines - 1 then
DataArr[i, CurrLab - 1] := LabLines[i];
if CurrLab = FLabelsPerRow then
FlushBuffer;
end;
end.
Component Download: http://www.baltsoft.com/files/dkb/attachment/ULabels2.zip
Feliratkozás:
Megjegyzések küldése (Atom)
Nincsenek megjegyzések:
Megjegyzés küldése