|
宣言 |
レポートデザイナーで作成されるレポートファイルのレコード体設計情報です。
読み込み順序は下記の宣言降順となります。
詳しくは同梱のサンプルコードをご覧ください。
|
type
TPrintData = record
Name :String;
KeyName :String;
mmLeft :Extended;
mmTop :Extended;
mmWidth :Extended;
mmHeight :Extended;
FontName :String;
FontStyle :TFontStyles;
FontSize :Integer;
FontColor :TColor;
Alignment :Integer;
Shape :TShapeType;
PenStyle :TPenStyle;
PenWidth :Integer;
PenColor :TColor;
BrushStyle :TBrushStyle;
BrushColor :TColor;
CornerRound :Integer;
Orientation :Integer;
CellWidth :Extended;
CellHeight :Extended;
SendWidth :Extended;
SendHeight :Extended;
BlockCol :Integer;
BlockRow :Integer;
Lock :Boolean;
end;
var
ItemList:array of TPrintData;
ItemRange :Integer;
PaleteModified :Boolean;
BGMetaFile :TMetaFile;
|
ストリームファイルの読み込み手続き(procedure) |
レポートデザイナーで作成されたrptファイルは以下のルーチンで読みだせます。
下記、手続きをそのまま使って宣言してください。
ストリームの勉強にもなります。
ただし、印刷に使わない項目もあるのでメモリを節約したい場合は、工夫してください。
|
var
BGMetaFile:Tmetafile;
procedure Form.OnShow(Sender:Object);
begin
BGMetaFile := TMetaFile.Create;
end;
procedure LoadStream;
var
FS:TFileStream;
cnt:Integer;
Len:Byte;
Bool:Boolean;
Exte:Extended;
Inte:Integer;
StrMem:PChar;
begin
FS := TFileStream.Create(OpenDialog.FileName,fmOpenRead);
try
FS.Position := 0;
FS.Read(ItemRange,SizeOf(Integer));
SetLength(ItemList,ItemRange);
for cnt := 0 to ItemRange - 1 do
begin
FS.Read(Len,SizeOf(Len));
StrMem := StrAlloc(Len);
FS.Read(StrMem^,Len);
ItemList[cnt].Name := StrMem;
FS.Read(Len,SizeOf(Len));
StrMem := StrAlloc(Len);
FS.Read(StrMem^,Len);
ItemList[cnt].KeyName := StrMem;
FS.Read(Exte,SizeOf(Extended));
ItemList[cnt].mmLeft := Exte;
FS.Read(Exte,SizeOf(Extended));
ItemList[cnt].mmTop := Exte;
FS.Read(Exte,SizeOf(Extended));
ItemList[cnt].mmWidth := Exte;
FS.Read(Exte,SizeOf(Extended));
ItemList[cnt].mmHeight := Exte;
FS.Read(Len,SizeOf(Len));
StrMem := StrAlloc(Len);
FS.Read(StrMem^,Len);
ItemList[cnt].FontName := StrMem;
FS.Read(Inte,SizeOf(Integer));
Len := Inte;
ItemList[cnt].FontStyle := TFontStyles(Len);
FS.Read(Inte,SizeOf(Integer));
ItemList[cnt].FontSize := Inte;
FS.Read(Inte,SizeOf(Integer));
ItemList[cnt].FontColor := TColor(Inte);
FS.Read(Inte,SizeOf(Integer));
ItemList[cnt].Alignment := Inte;
FS.Read(Inte,SizeOf(Integer));
ItemList[cnt].Shape := TShapeType(Inte);
FS.Read(Inte,SizeOf(Integer));
ItemList[cnt].PenStyle := TPenStyle(Inte);
FS.Read(Inte,SizeOf(Integer));
ItemList[cnt].PenWidth := Inte;
FS.Read(Inte,SizeOf(Integer));
ItemList[cnt].PenColor := TColor(Inte);
FS.Read(Inte,SizeOf(Integer));
ItemList[cnt].BrushStyle := TBrushStyle(Inte);
FS.Read(Inte,SizeOf(Integer));
ItemList[cnt].BrushColor := TColor(Inte);
FS.Read(Inte,SizeOf(Integer));
ItemList[cnt].CornerRound := Inte;
FS.Read(Inte,SizeOf(Integer));
ItemList[cnt].Orientation := Inte;
FS.Read(Exte,SizeOf(Extended));
ItemList[cnt].CellWidth := Exte;
FS.Read(Exte,SizeOf(Extended));
ItemList[cnt].CellHeight := Exte;
FS.Read(Exte,SizeOf(Extended));
ItemList[cnt].SendWidth := Exte;
FS.Read(Exte,SizeOf(Extended));
ItemList[cnt].SendHeight := Exte;
FS.Read(Inte,SizeOf(Integer));
ItemList[cnt].BlockCol := Inte;
FS.Read(Inte,SizeOf(Integer));
ItemList[cnt].BlockRow := Inte;
FS.Read(Bool,SizeOf(Boolean));
ItemList[cnt].Lock := Bool;
end;
FS.Read(Bool,SizeOf(Boolean));
if Bool = False then
BGMetaFile.LoadFromStream(FS);
FS.Free;
except
FS.Free;
ShowMessage('読み込みに失敗しました。');
end;
end;
|
※Nameは、印刷に必要ありません。
※Lockは、印刷に必要ありません。 |
印刷サンプルコード |
ここから先は、自由にコーディングしてもらってかまいませんが、一応自分なりにフォーマットがあるんで紹介します。
あまり美しくないかもしれませんが、参考にしてください。 |
var
dpiX,dpiY,PaperPixelX,PaperPixelY,OffsetX,OffsetY:Integer;
cnt,CopyCnt:integer;
ItemT,ItemL,ItemB,ItemR:integer;//
DotX,DotY:Extended;
LastPage,SplitLine:Integer;
StartLine,LastLine:Integer;
begin
if PrinterDialog.Execute then
begin
BGMetafile := TMetaFile.Create;
LoadStream;
OffsetX := GetDeviceCaps(Printer.Handle, PHYSICALOFFSETX);
OffsetY := GetDeviceCaps(Printer.Handle, PHYSICALOFFSETY);
SplitLine := ItemList[0].BlockCol * ItemList[0].BlockRow;
LastPage := (StringGrid.RowCount - 1) div SplitLine + 1;
try
Printer.BeginDoc;
try
if PrinterDialog.Collate then
for CopyCnt := 1 to PrinterDialog.Copies do
begin
for cnt := PrinterDialog.FromPage to PrinterDialog.ToPage
do
begin
StartLine := (cnt
- 1) * SplitLine + 1;
If LastPage := cnt then
LastLine := (cnt - 1) * SplitLine + 1
else
LastLine := SplitLine * cnt;
Printer.Canvas.Draw(-OffsetX,-OffsetY,GetPrintMetaFile(cnt,LastPage,StartLine,LastLine));
if cnt < frmMain.dlgPrinter.ToPage then
Printer.NewPage;
end;
if CopyCnt < PrinterDialog.Copies then
Printer.NewPage;
end
else
//
for cnt := PrinterDialog.FromPage to PrinterDialog.ToPage
do
begin
for CopyCnt := 1 to PrinterDialog.Copies do
begin
StartLine := (cnt - 1) * SplitLine + 1;
If LastPage := cnt then
LastLine := (cnt - 1) * SplitLine + 1
else
LastLine := SplitLine * cnt;
Printer.Canvas.Draw(-OffsetX,-OffsetY,GetPrintMetaFile(cnt,LastPage,StartLine,LastLine));
if CopyCnt < PrinterDialog.Copies then
Printer.NewPage;
end;
if cnt < PrinterDialog.ToPage then
Printer.NewPage;
end;
except
Printer.Abort;
raise;
end;
Printer.EndDoc;
finally
BGMetaFile.Free;
end;
end;
|
プレビューサンプルコード |
|
type TOptionFormCreate = function(hWnd:THandle;mmX,mmY,Page:Integer;PrintList:TMemoryStream):WordBool;
stdcall;
var
PreviewCreate:TOptionFormCreate;
GetModule:HMODULE;
MS:TMemoryStream;
CurrentPage,LastPage,SplitLine:Integer;
begin
BGMetafile := TMetaFile.Create;
LoadStream;
GetModule := LoadLibrary('PrintUtility.dll');
MS := TMemoryStream.Create;
MS.Position := 0;
CurrentPage := 1;
SplitLine := 1;
LastPage := 1;
GetPrintMetaFile(CurrentPage,LastPage,SplitLine,1).SaveToStream(MS);
MS.Position := 0;
if GetModule <> 0 then
try
if (GetProcAddress(GetModule,'PreviewCreate') <> Nil)
and (FindWindow(Nil,'印刷プレビュー') = 0) then
begin
@PreviewCreate := GetProcAddress(GetModule,'PreviewCreate');
PreviewCreate(Application.Handle,Round(ItemList[0].mmWidth),Round(ItemList[0].mmHeight),LastPage,MS);
end;
finally
MS.Free;
BGMetaFile.Free;
end
else
Exit;
end;
////////////////////////////////////////////////////////////////////////////////////////////////////////
var
PreviewCreate:TOptionFormCreate;
GetModule:HMODULE;
MS:TMemoryStream;
cnt,LastPage,SplitLine:Integer;
begin
BGMetafile := TMetaFile.Create;
LoadStream;
//DLL取得
GetModule := LoadLibrary('PrintUtility.dll');
MS := TMemoryStream.Create;
MS.Position := 0;
SplitLine := ItemList[0].BlockCol * ItemList[0].BlockRow;
LastPage := 10;
for cnt := 1 to LastPage do
begin
GetPrintMetaFile(cnt,LastPage,SplitLine,0).SaveToStream(MS);
end;
MS.Position := 0;
if GetModule <> 0 then
try
if (GetProcAddress(GetModule,'PreviewCreate') <> Nil)
and (FindWindow(Nil,'印刷プレビュー') = 0) then
begin
@PreviewCreate := GetProcAddress(GetModule,'PreviewCreate');
PreviewCreate(Application.Handle,Round(ItemList[0].mmWidth),Round(ItemList[0].mmHeight),LastPage,MS);
end;
finally
MS.Free;
BGMetaFile.Free;
end
else
Exit;
end;
|
メタファイル生成コード(親) |
Takeは、まずメタファイルに印刷情報をすべてメタファイルに書き出してから、プレビューや印刷するときに印刷用キャンバスにDrawしています。
下のコードは、配列0で設定した共通回数のループを行う場合のコードです。
もし、アイテムのそれぞれに別のループ回数があるようなら下のコードでは対応できません。
GetPrintMetaFile(NowPage,Lastpage,StartLine,LastLine:Integer):TMetafile; |
NowPage |
ノンブルを描画したり、ループ中の内容を計算するため |
LastPage |
PageとLastPageを比べて最後にトータル計算を記述できるから |
StartLine |
ループの最初の入力行 |
LastLine |
ループの最後の入力行 |
TMetaFile |
仕上がったメタファイルをお返しします。 |
※Modeの引数はあくまで複数のレポートを同一処理内で行う場合の仕分けようですから、いらない場合は削除して使ってください。
TakeはGetPrintMetafaile内で単ページ作成と複数リストページを行うのでModeのような引数が必要でした。
|
function GetPrintMetaFile(Page,LastPage,StartLine,LastLine:Integer):TMetaFile;
function GetPrintMetaFile(Page,LastPage,StartLine,LastLine:Integer):TMetaFile;
var
MergeMF:TMetaFile;
DC:HDC;
dpiX,dpiY:Integer;//ドットパーインチ
DotX,DotY:Extended;//1mmあたりのドット数
cnt,cntRow,cntCol:Integer;//
ItemT,ItemL,ItemB,ItemR:integer;//矩形範囲ベース
FieldRect:TRect;//矩形範囲
ExportText:String;//出力文字
StartLine,LastLine:Integer;//
MC:TMetaFileCanvas;
begin
MergeMF := TMetaFile.Create;
DC := GetDC(0);//デバイスコンテキスト取得
MergeMF.Inch := 0;
dpiX := GetDeviceCaps(DC, LOGPIXELSX);
dpiY := GetDeviceCaps(DC, LOGPIXELSY);
DotX := dpiX / 25.4;
DotY := dpiY / 25.4;
MergeMF.Height := Round(ItemList[0].mmHeight * DotY);
MergeMF.Width := Round(ItemList[0].mmWidth * DotX);
MC := TMetafileCanvas.Create(MergeMF, 0);
with MC do
try
if BGMetaFile.PaletteModified = false then
Draw(0,0,,BGMetaFile);
for cnt := 1 to ItemRange - 1 do//プリント配列に対してキー読み出しループ
beginif ItemList[cnt].KeyName
= 'IMAGE' then
DrawImageProportional(MC,cnt,1,1,Image.Picture.Graphic.Width,Image.Picture.Graphic.Height,DotX,DotY,Image.Picture);for cnt := StartLine to LastLine do
beginif ItemList[0].Orientation = 0 thenbegin
cntRow := cnt mod ItemList[0].BlockRow;
cntCol := cnt div ItemList[0].BlockRow + 1;
end
elsebegin
cntRow := cnt div ItemList[0].BlockCol;
cntCol := cnt mod ItemList[0].BlockCol + 1;
end;if ItemList[cnt].KeyName
= 'ZIP' thenWriteText(MC,cnt,cntCol,cntRow,DotX,DotY,frmItemInfo.lblLot.Caption);
if ItemList[cnt].KeyName
= 'MEMO' then
WriteMemo(MC,cnt,cntCol,cntRow,DotX,DotY,Memo.Text);
end;
finally
Free;
Result := MergeMF;
end;
end;
|
メタファイル生成コード(子) |
文字列やメモ形式、画像などの描画を仕分けて描画させます。 |
procedure WriteText(MetaCanvas:TMetafileCanvas;Line,Col,Row:Integer;DotX,DotY:Extended;ExportStr:String);
procedure WriteMemo(MetaCanvas:TMetafileCanvas;Line,Col,Row:Integer;DotX,DotY:Extended;ExportStr:String);
procedure DrawImageProportional(MetaCanvas:TMetafileCanvas;Line,Col,Row,iWidth,iHeight:Integer;DotX,DotY:Extended;ExportImg:TPicture);
procedure WriteText(MetaCanvas:TMetafileCanvas;Line,Col,Row:Integer;DotX,DotY:Extended;ExportStr:String);
var
FieldRect:TRect;
ItemT,ItemL,ItemB,ItemR:integer;
begin
with MetaCanvas do
begin
ItemT := Round((ItemList[Line].SendHeight * (Row - 1) + ItemList[Line].mmTop)
* DotY);
ItemB := Round((ItemList[Line].SendHeight * (Row - 1) + ItemList[Line].CellHeight
+ ItemList[Line].mmTop) * DotY);
ItemL := Round((ItemList[Line].SendWidth * (Col - 1) + ItemList[Line].mmLeft)
* DotX);
ItemR := Round((ItemList[Line].SendWidth * (Col - 1) + ItemList[Line].CellWidth
+ ItemList[Line].mmLeft) * DotX);
FieldRect := Rect(ItemL,ItemT,ItemR,ItemB);
Pen.Style := ItemList[Line].PenStyle;
Pen.Color := ItemList[Line].PenColor;
Pen.Width := ItemList[Line].PenWidth;
Brush.Style := ItemList[Line].BrushStyle;
Brush.Color := ItemList[Line].BrushColor;
case ItemList[Line].Shape of
stRectAngle:Rectangle(FieldRect);
stEllipse:Ellipse(FieldRect);
stRoundRect:RoundRect(ItemL,ItemT,ItemR,ItemB,ItemList[Line].CornerRound,ItemList[Line].CornerRound);
else
Brush.Style := bsClear;
end;
Font.Name := ItemList[Line].FontName;
Font.Style:= ItemList[Line].FontStyle;
Font.Color:= ItemList[Line].FontColor;
Font.Size := ItemList[Line].FontSize;
case ItemList[Line].Alignment of
0:DrawTextEX(Handle,PChar(ExportStr),Length(PChar(ExportStr)),FieldRect,DT_SINGLELINE
+ DT_VCENTER + DT_LEFT,Nil);
1:DrawTextEX(Handle,PChar(ExportStr),Length(PChar(ExportStr)),FieldRect,DT_SINGLELINE
+ DT_VCENTER + DT_CENTER,Nil);
2:DrawTextEX(Handle,PChar(ExportStr),Length(PChar(ExportStr)),FieldRect,DT_SINGLELINE
+ DT_VCENTER + DT_RIGHT,Nil);
end;
end;
end;
procedure WriteMemo(MetaCanvas:TMetafileCanvas;Line,Col,Row:Integer;DotX,DotY:Extended;ExportStr:String);
var
FieldRect:TRect
ItemT,ItemL,ItemB,ItemR:integer;
begin
with MetaCanvas do
begin
ItemT := Round((ItemList[Line].SendHeight * (Row - 1) + ItemList[Line].mmTop)
* DotY);
ItemB := Round((ItemList[Line].SendHeight * (Row - 1) + ItemList[Line].CellHeight
+ ItemList[Line].mmTop) * DotY);
ItemL := Round((ItemList[Line].SendWidth * (Col - 1) + ItemList[Line].mmLeft)
* DotX);
ItemR := Round((ItemList[Line].SendWidth * (Col - 1) + ItemList[Line].CellWidth
+ ItemList[Line].mmLeft) * DotX);
FieldRect := Rect(ItemL,ItemT,ItemR,ItemB);
Pen.Style := ItemList[Line].PenStyle;
Pen.Color := ItemList[Line].PenColor;
Pen.Width := ItemList[Line].PenWidth;
Brush.Style := ItemList[Line].BrushStyle;
Brush.Color := ItemList[Line].BrushColor;
case ItemList[Line].Shape of
stRectAngle:Rectangle(FieldRect);
stEllipse:Ellipse(FieldRect);
stRoundRect:RoundRect(ItemL,ItemT,ItemR,ItemB,ItemList[Line].CornerRound,ItemList[Line].CornerRound);
else
Brush.Style := bsClear;
end;
Font.Name := ItemList[Line].FontName;
Font.Style:= ItemList[Line].FontStyle;
Font.Color:= ItemList[Line].FontColor;
Font.Size := ItemList[Line].FontSize;
DrawTextEx(Handle, PChar(ExportStr), -1,FieldRect,DT_LEFT or
DT_WORDBREAK,nil);
end;
end;
procedure DrawImageProportional(MetaCanvas:TMetafileCanvas;Line,Col,Row,iWidth,iHeight:Integer;DotX,DotY:Extended;ExportImg:TPicture);
var
FieldRect:TRect;
ItemT,ItemL,ItemB,ItemR:integer;
Ratio,RatioX,RatioY:Extended;
CenterX,CenterY:Integer;
begin
with MetaCanvas do
begin
RatioX := iWidth / (ItemList[Line].CellWidth * DotX);//800
RatioY := iHeight / (ItemList[Line].CellHeight * DotY);//600
if RatioX > RatioY then
Ratio := RatioX
else
Ratio := RatioY;
CenterX := Round((ItemList[Line].mmLeft + (ItemList[Line].CellWidth
/ 2)) * DotX);
CenterY := Round((ItemList[Line].mmTop + (ItemList[Line].CellHeight
/ 2)) * DotY);
ItemT := CenterY - Round(iHeight / 2 / Ratio);
ItemB := CenterY + Round(iHeight / 2 / Ratio);
ItemL := CenterX - Round(iWidth / 2 / Ratio);
ItemR := CenterX + Round(iWidth / 2 / Ratio);
FieldRect := Rect(ItemL,ItemT,ItemR,ItemB);
MetaCanvas.StretchDraw(FieldRect,ExportImg.Graphic);
end;
end;
|
自身のソフトからの移植なんで、コンポーネント名称の書き換えに不備があるかもしれません。
ご了承ください。 |
|