WMF Display
You will need a form with a button, an open dialog and a filelist box (which can be invisible) unit w2eU1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, FileCtrl; type TForm1 = class(TForm) Button1: TButton; OpenDialog1: TOpenDialog; FileListBox1: TFileListBox; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.DFM} {$A-} {This is essential to get the correct sizes for the different integers} type arect = record left : smallint; top : smallint; right : smallint; bottom : smallint; end; apmfileheader = record key : longint; hmf : smallint; bbox : arect; inch : smallint; reserved : longint; checksum : smallint; end; metaheader = record mttype : smallint; mtheadersize : smallint; mtversion : smallint; mtsize : longint; mtnoobjects : smallint; mtmaxrecord : longint; mtnoparameters : smallint; end; procedure TForm1.Button1Click(Sender: TObject); var ahdr : apmfileheader; sta : tmemorystream; mhdr : metaheader; mfpic : metafilepict; llen : longint; mfh, mdatah, hemf : thandle; lpmdata : pointer; drect : trect; resb : boolean; i, x, y, x1, y1, wwidth : integer; sa, spath : string; emhd : tenhmetaheader; t, l, b, r , ret : longint;
begin opendialog1.Filter := 'WMF files ( *.wmf)|*.wmf'; opendialog1.InitialDir := 'MyPath'; resb := opendialog1.execute; if resb = false then exit; sa := opendialog1.FileName; //reduce this to just the path spath := extractfilepath(sa); //update the filelistbox filelistbox1.Directory := spath; filelistbox1.mask := '*.wmf'; filelistbox1.update; //wwidth is the size of the square where the metafile is to be displayed wwidth := 200; //pixels //set the form into text (pixel) mode setmapmode(form1.canvas.handle,MM_text); //process all the files in the list box one by one for i := 0 to filelistbox1.items.count -1 do begin //clear the display area form1.canvas.Rectangle(0,0,wwidth,wwidth); //get the metafile to be displayed sa := form1.FileListBox1.Items.Strings[i]; //create stream and load with metafile sta := tmemorystream.create; sta.LoadFromFile(sa); sta.position := 0;
//read the Aldus header sta.read(ahdr, sizeof(ahdr)); //read the metaheader sta.read(mhdr, sizeof(mhdr)); //move past the Aldus header to start of metaheader sta.position := sizeof(ahdr); //get length of metafile and allocate memory for it llen := mhdr.mtsize * 2; mdatah := globalalloc(GMEM_SHARE,llen); lpmdata := globallock(mdatah); //read the metafile into memory sta.read(lpmdata^,llen); //stream finished with now sta.free; //make a w31 metafile mfh := setmetafilebitsex(llen,lpmdata); //get the sizes from the Aldus header x := 2540 * (ahdr.bbox.right-ahdr.bbox.left) div ahdr.inch; y := 2540 * (ahdr.bbox.bottom-ahdr.bbox.top) div ahdr.inch; //scale sizes depending on aspect ratio to fit display area if x >= y then begin x1 := wwidth; y1 := (wwidth * y) div x; end else begin x1 := (wwidth * x) div y; y1 := wwidth; end; //if x>y //set up the metafilepict, x1 and y1 are not the obvious values, x and y are mfpic.mm := mm_text; mfpic.xext := x1; mfpic.yext := y1; mfpic.hmf := mfh; //create enhanced metafile hemf := setwinmetafilebits(llen,lpmdata,0,mfpic); //free stuff globalunlock(mdatah); globalfree(mdatah); //get some picture dimensions ret := getenhmetafileheader(hemf,sizeof(emhd),@emhd); t := emhd.rclframe.top; b := emhd.rclframe.bottom; l := emhd.rclbounds.left; r := emhd.rclbounds.right; //sort out the picture orientation otherwise // maybe some will be upside down and some mirrored if abs(t) < abs(b) then begin drect.top := 0; drect.bottom := y1; end else begin drect.top := y1; drect.bottom := 0; end; //if abs(t) if abs(l) < abs(r) then begin drect.left := 0; drect.right := x1; end else begin drect.left := x1; drect.right := 0; end; //if abs(l) //display the metafile resb := playenhmetafile(form1.canvas.handle,hemf,drect); //free stuff deletemetafile(mfh); deleteenhmetafile(hemf); end; //for i end; //button1 end.
last updated 18/06/2008