Metafile scaling - how do I get real size?

Here's a weird one.  In VB5, when you import and print a WMF, the thing prints original size (of course you'd have to use VB which takes the fun away.<g>)

In Delphi (2), the size is shrunk by a huge amount.  It looks like it is taking the pixel resolution?  I can stretch it to fit the page, but I want to keep the original's size so I can write on the graphic form.


var
   Wmf1: TMetaFile;
   r: TRect;
begin
     Wmf1 := TMetaFile.Create;
     Wmf1.LoadFromFile('D:\BACKUP\DELPHI\FormPrint\7501.wmf');
     // Wmf1.Inch := 1440;
     // In Pixels for some reason.  96 pixels per inch
     if PrintDialog1.Execute then begin;
        Printer.BeginDoc;                               { begin to send print job to printer }
        Printer.NewPage;
        r:=Printer.Canvas.ClipRect;
        Printer.Canvas.Draw(0,0,Wmf1);
        // Printer.Canvas.StretchDraw(Printer.Canvas.ClipRect, Wmf1);
        Printer.EndDoc;
sfbAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

mirek071497Commented:
Do you try Wmf1.Width and Height after Loading from file ?
0
sfbAuthor Commented:
Yes Mirek.  I tried looking at it through debug - I don't have the exact value with me, but it was a height of around 900 to just over 1000.  At 96 pixels per inch, it appears as though the WMF is about right for screen display.  Roughly 6.5 times smaller than what is needed for a 600dpi printer.

0
mirek071497Commented:
In Delphi2 and 3 You can Use GetEnhMetafileHeader the last value in this header is szlMillimeters which specifies the resolution of the reference device, in millimeters The previus value szlDevice specifies the resolution of the reference device, in pixels.

This can help you ?


0
C++ 11 Fundamentals

This course will introduce you to C++ 11 and teach you about syntax fundamentals.

StevenBCommented:
 StretchDrawing a Metafile like this will result in a small image because as you say the pixel resolution of the printer is very high. The solution I use is to take the X and Y resolutions of the printer and then calculate the actual size of the rectangle that the metafile should be drawn into in printer units. The pixel units in a metafile correspond to 1/100 mm so the conversion is very simple.
  I'm in a hurry right now so I'll leave this as an answer. If you think I'm on the right track then leave a message, and I'll post up the code to do all this.

  Steven.

0
sfbAuthor Commented:
Hi Steven,

I think you're on the right track, but I want to clarify a few points.  1) The stretchdraw is commented out - the 'straight' draw produces the small image.  2) I don't want to stretch the image to fit available space ... I want to convert it back to original size.

The metafile is a form - complete with text in certain point sizes.  I want to fill in the blanks within my print routine - so I need the metafile in it's exact size and proportion to hit the blank spaces correctly.

I figured there was an easy way to get the printer resolution and perform a stretch based on the conversion factor of the original wmf.

If that's what you have, post away!!!

Thanks,

Scott
0
StevenBCommented:
 It is pretty simple, I'll post it on Monday, cause I've got some examples at work.

Steven.
0
StevenBCommented:
Hi Scott,

  Try this:

  Make a new application, add a button and link it to this method (you'll have to add Printers to the Uses also):


procedure TForm1.Button1Click(Sender: TObject);
var
  ADevice,ADriver,APort : ARRAY [0..255] of Char;
  DeviceHandle : THandle;
  DevMode : PDeviceMode;
  DPIx,DPIy : Integer;
  XSc,YSc : Double;
  XSize,YSize : Integer;
  AMetaMMWidth,AMetaMMHeight : Integer;
  Printer : TPrinter;
  AMetafile : TMetafile;
  AnOpenDialog : TOpenDialog;
begin
  try
    AMetaFile := TMetafile.Create;
    Printer := TPrinter.Create;
    AnOpenDialog := TOpenDialog.Create(Self);
    If AnOpenDialog.Execute then begin

      Printer.GetPrinter(ADevice,ADriver,APort,DeviceHandle); // Initialise everything
      AMetafile.LoadFromFile(AnOpenDialog.FileName);

      If DeviceHandle = 0 then begin
        Printer.PrinterIndex := Printer.PrinterIndex;
        Printer.GetPrinter(ADevice,ADriver,APort,DeviceHandle);
      end;
      If DeviceHandle = 0 then
        Raise Exception.Create('Could Not Initialize Printer')
      else
        DevMode := GlobalLock(DeviceHandle);

      with DevMode^ do begin
        dmFields := dmFields or DM_PRINTQUALITY; // Calculate scaling in dots per inch
        DPIx := dmPrintQuality;
        dmFields := dmFields or DM_YRESOLUTION;
        DPIy := dmYResolution;
      end;

      XSc := DPIx/2540; // Convert to dots per hundredth of mm
      YSc := DPIy/2540;

      AMetaMMWidth := round(AMetaFile.Width/(Screen.PixelsPerInch/2540)); // Calculate size of metafile in 100ths mm
      AMetaMMHeight := round(AMetaFile.Width/(Screen.PixelsPerInch/2540));
      {Using AMetafile.MMWidth should have the same effect, however it seems to screw up too often}

      XSize := round(AMetaMMWidth*XSc); // Calculate sizes in printer units
      YSize := round(AMetaMMHeight*YSc);


      Printer.BeginDoc; // draw to the Printer Canvas
      try
        Printer.Canvas.StretchDraw(Rect(0,0,XSize,YSize),AMetaFile);
      finally
        Printer.EndDoc;
      end;
    end;
  finally
    Printer.Free;
    AMetaFile.Free;
    AnOpenDialog.Free;
  end;

end;



  Hopefully this should do what you're after. If it does then the code should be pretty obvious to translate to your application. If you've any more questions then fire away.

  Steven.
0
StevenBCommented:
 I assure you that this code was indented with much more skill prior to pressing the submit button.

  Steven.
0
StevenBCommented:
 Hello Scott,

  Are you still out there? Perhaps you'll notice an answer.

  Steven.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
sfbAuthor Commented:
Sorry for the delay.  I put the code in and ran it as is - I kept getting GPF type errors, and there was a slight problem because the height calculation was using AMetaFile.Width.

All the guts are there though!

Thanks,

Scott
0
StevenBCommented:
 Oops, your right. Sorry about that, That'll teach me to only test the thing on square images. Have the faults stopped? What was causing them?

  Steven.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.