数式をQuickReportで印刷しようとしています。
㎡のような文字は入力できますが、2を3にしたい場合があります。
QRLabelを一文字ずつ並べれば良いかと思っていたのですが、
印刷機によって同じ文字でも文字幅が違うのかズレて、文字が重なったりします。
例えば、QRLabelのCaptionにm^2と入力すれば、㎡と表示できる方法はありますでしょうか?
そのような事ができるコンポーネントも探しています。
宜しくお願いします。
数式であればTMetafileを用意して、そこへ文字を描画し、
TQRImageへ読み込ませるのが一番簡単な方法だと思います。
TMetafileではなくTBitmapでやると、文字をキレイに印刷できないハズです。
上付き、下付き、中央小文字等のできるTQRLabelを継承したコンポ作ったけど、
Canvasに直書きしないと、実現できませんでした。
このこんぽは、ちょっと出しにくいので、グラフとか印刷したいときに
つくった、Metafileを印刷できるQRコンポーネントを暴露します。
QR2で使っているので、QR3以降で使えるか不明。
Scaleは、縮尺(%)で、縦横 50×100のコントロールのとき、
100×200のサイズのCanvasを使うことができる。
大きく書いて、小さく印刷させるためのもの。
細かい図を書くときに使えると思う。
文字は、縮尺を考えて書かないといけないけど、放物線とかが滑らかに描ける。
type
TQRMetafileImage = class(TQRPrintable)
private
FMetaFile: TMetaFile;
FMetaCanvas: TMetafileCanvas;
FScale: Word;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
protected
function GetCanvas: TCanvas;
procedure SetMetaFile(aMetaFile: TMetaFile);
procedure SetScale(aScale: Word);
procedure Paint; override;
procedure Print(OfsX, OfsY : Integer); override;
function GetCanvasSize(aIndex: Integer): Integer;
public
property Canvas: TCanvas read GetCanvas;
published
property Metafile: TMetaFile read FMetaFile write SetMetaFile;
property Scale: Word read FScale write SetScale default 100;
property CanvasHeight: Integer index 1 read GetCanvasSize;
property CanvasWidth : Integer index 2 read GetCanvasSize;
end;
実装部
constructor TQRMetafileImage.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FMetaFile := TMetafile.Create;
FMetaCanvas := nil;
Height := 80;
Width := 80;
FScale := 100;
end;
destructor TQRMetafileImage.Destroy;
begin
if FMetaCanvas <> nil then FreeAndNil(FMetaCanvas);
FMetaFile.Free;
inherited Destroy;
end;
function TQRMetafileImage.GetCanvas: TCanvas;
begin
if FMetaCanvas = nil then begin
FMetaFile.Width := Round(Width * FScale / 100);
FMetaFile.Height := Round(Height * FScale / 100);
FMetaCanvas := TMetafileCanvas.Create(FMetaFile, 0);
end;
Result := FMetaCanvas;
end;
procedure TQRMetafileImage.SetMetaFile(aMetaFile: TMetaFile);
begin
FMetaFile.Assign(aMetaFile);
end;
procedure TQRMetafileImage.SetScale(aScale: Word);
begin
if aScale < 10 then aScale := 10;
if FScale <> aScale then begin
FScale := aScale;
if FMetaCanvas = nil then FreeAndNil(FMetaCanvas);
end;
end;
procedure TQRMetafileImage.Paint;
var
dest :TRect;
begin
if csDesigning in ComponentState then begin
with inherited Canvas do begin
Pen.Style := psDash;
Brush.Style := bsClear;
Rectangle(0, 0, Width, Height);
end;
end;
if Zoom <> 100 then begin
dest.Right := dest.Left + (dest.Right - dest.Left) * Zoom div 100;
dest.Bottom := dest.Top + (dest.Bottom - dest.Top) * Zoom div 100;
end;
inherited Canvas.StretchDraw(dest, FMetaFile);
Inherited Paint;
end;
procedure TQRMetafileImage.Print(OfsX,OfsY : Integer);
var
dest :TRect;
printDC, savedDC: THandle;
begin
if FMetaCanvas <> nil then FreeAndNil(FMetaCanvas);
dest := Rect(QRPrinter.XPos(OfsX + Size.Left),
QRPrinter.YPos(OfsY + Size.Top),
QRPrinter.XPos(OfsX + Size.Width + Size.Left),
QRPrinter.YPos(OfsY + Size.Height + Size.Top));
IntersectClipRect(QRPrinter.Canvas.Handle, dest.Left,
dest.Top, dest.Right, dest.Bottom);
printDC := GetDC(QRPrinter.Canvas.Handle);
savedDC := SaveDC(printDC);
QRPrinter.Canvas.StretchDraw(dest, FMetaFile);
RestoreDC(printDC, savedDC);
SelectClipRgn(QRPrinter.Canvas.Handle, 0);
Transparent := True;
inherited Print(OfsX,OfsY);
end;
function TQRMetafileImage.GetCanvasSize(aIndex: Integer): Integer;
begin
if aIndex = 1 then
Result := Height * FScale Div 100
else
Result := Width * FScale Div 100;
end;
DEKO様ofZ様とても親切な回答ありがとうございます。
TQRLabelでは難しそうなので諦めます。
Metafileと言うのがあるんですね。初心者ですいません。
本来ここに記述すべきでは無いと思いますが、
ofZ様のQRコンポーネントをC++Builder6でも同様に活用するにはどのようにすれば良いのでしょうか?
ご存知の方いらっしゃいましたら、宜しくお願いします。
ツイート | ![]() |