Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

MetaFileCanvas and reference-device

Posted on 2000-04-18
5
Medium Priority
?
822 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
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 200 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

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
This course is ideal for IT System Administrators working with VMware vSphere and its associated products in their company infrastructure. This course teaches you how to install and maintain this virtualization technology to store data, prevent vuln…
This lesson discusses how to use a Mainform + Subforms in Microsoft Access to find and enter data for payments on orders. The sample data comes from a custom shop that builds and sells movable storage structures that are delivered to your property. …
Suggested Courses

609 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