Solved

MetaFileCanvas and reference-device

Posted on 2000-04-18
5
726 Views
Last Modified: 2010-04-04
I'm trying to create a Metafile and scale it in
width and height.
The metafile has MMWidth and MMHeight to scale it,
but I does not work the way I want it to.
The Create-method of the MetafileCanvas, which I need
to write into the metafile, needs a "reference-canvas" from which
it would take the width and height of the Metafile
(if the properties MMWidth and MMHeight are
NOT previously set to own values).
Now in the first example I use 0 as reference-device,
which leads to a metafile width MMWidth set to screen.width
(MMHeight = Screen.Height), although I previously set
the MMWidth and MMHeight-components.


function SaveMetafile(fn:string;wdt,hgt:longint):boolean;
var mtf:tMetafile;
    mtfCanv:tMetaFileCanvas;
begin
  Mtf:=tMetafile.Create;
  Mtf.MMWidth:=wdt;
  Mtf.MMHeight:=hgt;
  Mtf.Width:=wdt;
  Mtf.Height:=hgt;
  MtfCanv:= TMetafileCanvas.Create(mtf, 0);
  // paint on the MtfCanvas, e.g. MtfCanv.Rectangle(0,0,wdt,hgt);
  MtfCanv.Free;
  Mtf.SaveToFile(fn);
  Mtf.Free;
end;


In the second example I use an own reference, but this does not
work because I get a runtime-exception, that the canvas does
not permit painting.

function SaveMetafile(fn:string;wdt,hgt:longint):boolean;
var mtf:tMetafile;
    mtfCanv:tMetaFileCanvas;
    bmp:tBitmap;
begin
  Mtf:=tMetafile.Create;
  Mtf.MMWidth:=wdt;
  Mtf.MMHeight:=hgt;
  Mtf.Width:=wdt;
  Mtf.Height:=hgt;
  bmp:=tBitmap.create;
  bmp.Width:=wdt;
  bmp.Height:=hgt;
  MtfCanv:= TMetafileCanvas.Create(mtf, bmp.Canvas.Handle);
  // paint on the MtfCanvas, e.g. MtfCanv.Rectangle(0,0,wdt,hgt);
  MtfCanv.Free;
  Mtf.SaveToFile(fn);
  bmp.Free;
  Mtf.Free;
end;

So both examples don't work.
How can I get a metafilecanvas scaled to wdt and hgt and a
metafile in file fn, which has the correct size?

Thanks

Gamba
0
Comment
Question by:Gamba
5 Comments
 
LVL 2

Expert Comment

by:PeterLarsen
ID: 2726154
Hi Gamba,

The following sample shows how to create a EnhancedMetafile. It is then possible to use this metafile to either print (to a printer) or to draw on a canvas (print preview).

The sample is not a ready-to-use program, but it shows you how to create a metafile and put different things in it.

I hope you will find something usefull here !!

Good luck
Peter



procedure TFormDiagramPrint.LavChartMetaFile;
var
 MetaCanvas : TMetafileCanvas;
 YMargin, XMargin, AntalLinjer, fortel1, XPos : integer;
 Margin : integer;
 DiagramPos : Trect;
 LegendBredde, LegendHojde : integer;
 NyLegendBredde, NyLegendHojde : integer;
 XProcent, Yprocent : integer;
 LegendPos : Trect;
 Videre : boolean;
 LData : TLegendInfo;
 Teller : integer;
 R1 : trect;
 LinjeHojde : integer;
 Meta2 : TMetafile;
 MetaCanvas2 : TMetafileCanvas;
begin
try
MetaCanvas:=nil;
meta.free;
meta:=nil;
MetaCanvas2:=nil;
Meta2:=nil;
Meta:=UseChart.TeeCreateMetafile(true, rect(0, 0, 640, 480));
MetaCanvas:=TMetafileCanvas.create(Meta, 0);
//
margin:=round((meta.width*(50-SetMargin)/100)/2);
DiagramPos.left:=0+margin;
DiagramPos.Right:=Meta.width-margin;
margin:=round((meta.height*(50-SetMargin)/100)/2);
DiagramPos.Top:=0+margin;
DiagramPos.Bottom:=meta.height-margin;;
//
MetaCanvas.StretchDraw(DiagramPos, Meta);
//write other canvas stuff
//write bottom text
Ymargin:=round((Meta.Height*SetBundMargin/100)/2);
YMargin:=Meta.Height-Ymargin;;
AntalLinjer:=MemoBund.Lines.Count;
MetaCanvas.Font.assign(BundTekstFont);
MetaCanvas.Brush.Style:=bsClear;
Ymargin:=YMargin-(Antallinjer*MetaCanvas.TextHeight('sadJHFDlfsd'));
for fortel1:=0 to AntalLinjer-1 do
begin
 XPos:=round((Meta.width-MetaCanvas.TextWidth(MemoBund.lines[fortel1]))/2);
 MetaCanvas.TextOut(Xpos, YMargin, MemoBund.lines[fortel1]);
 Ymargin:=YMargin+MetaCanvas.TextHeight('sadælfsd');
end;
//
//write legend
if UseLegend<>nil then
begin
 //
 LegendBredde:=uselegend.Width;
 LegendHojde:=uselegend.Height;
 //
 XProcent:=round(LegendXPos/panel5.Width*100);
 YProcent:=round(LegendYPos/panel5.Height*100);
 //
 NyLegendBredde:=round(LegendBredde*LegendSize/100);
 NyLegendHojde:=round(LegendHojde*LegendSize/100);
 //
 LegendPos.left:=round(meta.Width/100*XProcent);
 LegendPos.Right:=round(meta.Width/100*XProcent)+NyLegendBredde;
 LegendPos.Top:=round(meta.Height/100*YProcent);
 LegendPos.Bottom:=round(meta.Height/100*YProcent)+NyLegendHojde;
 //
 Meta2:=tmetafile.create;
 Meta2.Width:=LegendBredde;
 Meta2.Height:=LegendHojde;
 MetaCanvas2:=TMetafileCanvas.create(Meta2, 0);
 MetaCanvas2.Font.assign(LegendFont);
 //
 if MedFarver = true then
  MetaCanvas2.Brush.Color:=clGray
 else
  MetaCanvas2.Brush.Color:=clwhite;
 //
 MetaCanvas2.FillRect(rect(0, 0, LegendBredde, LegendHojde));
 MetaCanvas2.Brush.Color:=clBlack;
 MetaCanvas2.FrameRect(rect(0, 0, LegendBredde, LegendHojde));
 //write legend content
 Videre:=false;
 Teller:=0;
 LinjeHojde:=MetaCanvas2.TextHeight('asdflkjhØÆÅP');
 Repeat
  Ldata:=LegendInfo[Teller];
  if Ldata.InUse=false then
   break;
  //
  MetaCanvas2.Brush.Color:=Ldata.Farve;
  MetaCanvas2.Brush.Style:=bsSolid;
  R1.left:=10;
  R1.right:=20;
  R1.top:=11+(Teller*LinjeHojde);
  R1.Bottom:=9+Linjehojde+(Teller*LinjeHojde);
  MetaCanvas2.FillRect(R1);
  MetaCanvas2.Brush.Color:=clBlack;
  MetaCanvas2.FrameRect(R1);
  //
  MetaCanvas2.Brush.Style:=bsClear;
  MetaCanvas2.TextOut(R1.left+30, R1.top, Ldata.Navn);
  //
  Teller:=teller+1;
 until videre = true;
 //
 MetaCanvas2.Free;
 MetaCanvas.StretchDraw(LegendPos, Meta2);
 Meta2.Free;
end; //end if, write legend
//
MetaCanvas.free;
//
except
 if MetaCanvas<>nil then
  MetaCanvas.free;
 if MetaCanvas2<>nil then
  MetaCanvas2.free;
 if Meta2<>nil then
  Meta2.free;
end; //end try
end;
0
 
LVL 1

Expert Comment

by:Asw
ID: 2726207
Listening.
0
 

Accepted Solution

by:
vanbeek earned 100 total points
ID: 2738398
The native format of the Metafilecanvas are MM_HEIGHT and MM_WIDTH. However the relation between the internal mapping of Metafilecanvas and the outside world is controlled by the mapping modes (MM_TEXT, MM_LOMETRIC, MM_HIMETRIC, MM_LOENGLISH, MM_HIENGLISH, MM_TWIPS, MM_ISOTROPIC and MM_ANISOTROPIC) (see msdn for more information on these mapping modes). Unfortunately I don't think it is possible to draw using MM_ coordinates, hence you will need to scale the Pixel coordinates to MM_ dimensions before drawing.
0
 
LVL 4

Expert Comment

by:Radler
ID: 2743929
Listening...
0
 

Expert Comment

by:vanbeek
ID: 2744208
Gamba,

Here is a code snippet using MetafileCanvas and MM_HIMETRIC. Note that the y-axis definition of MM_HIMETRIC is opposite of that used by Rectangle! I use Clipboard to transport the metafile into MS Word.

// create canvas of size 20 mm by 50 mm
mtf := TMetaFile.Create;
mtf.MMWidth := 2000;
mtf.MMHeight := 5000;
mtfcv := TMetaFileCanvas.Create(mtf, 0);
rect.Top := 0;
rect.Left := 0;
rect.Bottom := -4000; // positive Y is up for HIMETRIC!
   
rect.Right := 1000;
SetMapMode(mtfcv.Handle, MM_HIMETRIC);
mtfcv.Rectangle(rect);
mtfcv.Free;
Clipboard.Clear;
ClipBoard.Assign(mtf);
mtf.Free;


0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now