| View previous topic :: View next topic |
| Author |
Message |
P_G Member
Joined: 14 Jun 2004 Posts: 21 Location: Germany
|
Posted: 14/10/04 13:22 Post subject: How to access metafile records ? |
|
|
Hello,
Has anyone a code example for accessing the data of a metafiles records? I need to get the drawing operation (polyline, circle etc.) and the coordinates of each record of a given metafile. I think I have to enumerate through the records with enumenhmetafile but I don't know how to get the code working and how to get the data.
Any ideas or examples would be appreciated.
Thanks, P_G
|
|
| Back to top |
|
 |
P_G Member
Joined: 14 Jun 2004 Posts: 21 Location: Germany
|
Posted: 15/10/04 09:36 Post subject: How to access the records of a metafile |
|
|
| No ideas? Anyone?
|
|
| Back to top |
|
 |
Stefan Member
Joined: 27 Sep 2004 Posts: 49 Location: Netherlands
|
Posted: 15/10/04 13:12 Post subject: |
|
|
Something like this should work:
function EnumEnhFunc(DC: HDC; lpHTable: PHandleTable; lpEMFR:
PEnhMetaRecord; nObj: Integer; lpData: LPARAM): BOOL; stdcall;
begin
case lpEMFR^.iType of
EMR_HEADER: Form1.Memo1.Lines.Add('EMR_HEADER:');
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
hEmf: HENHMETAFILE;
rect: TRect;
MetaFile: TMetaFile;
begin
MetaFile := TMetaFile.Create;
MetaFile.LoadFromFile('C:\sample.emf');
rect.Left := 0;
rect.Top := 0;
rect.Right := MetaFile.MMWidth;
rect.Bottom := MetaFile.MMHeight;
EnumEnhMetaFile(nil, MetaFile.Handle, @EnumEnhFunc, nil, rect)
end;
|
|
| Back to top |
|
 |
P_G Member
Joined: 14 Jun 2004 Posts: 21 Location: Germany
|
Posted: 18/10/04 11:43 Post subject: Metafile records |
|
|
Thank you, Stefan
I think I understand the basic concept of EnumEnhMetafile now.
But I'm still struggling with the EnumEnhFunc function of yours.
I changed the line to
EMR_HEADER: Form1.Memo1.Lines.Add(IntToStr(EMR_HEADER));
because EMR_HEADER: Form1.Memo1.Lines.Add('EMR_HEADER:');
delivers a string of course (EMR_HEADER:).
By the way - The result is always 1.
So I still don't know how to extract the drawing instruction and the coordinates of each record.
P_G
|
|
| Back to top |
|
 |
Stefan Member
Joined: 27 Sep 2004 Posts: 49 Location: Netherlands
|
|
| Back to top |
|
 |
P_G Member
Joined: 14 Jun 2004 Posts: 21 Location: Germany
|
Posted: 19/10/04 10:35 Post subject: Metafile records |
|
|
Thanks, Stefan
That's exactly what I was looking for.
P_G
|
|
| Back to top |
|
 |
P_G Member
Joined: 14 Jun 2004 Posts: 21 Location: Germany
|
Posted: 25/10/04 10:16 Post subject: |
|
|
Well, sorry, it's me again...
This code of mine is a little tricky. Now I'm able to access the metafile records and load their values into an array of record. I can get the drawing operation of each record (in the example below I only implemented the Polyline16 but it works fine). But the cpts (size of TPoint array) and the apts (array of TPoint) of each metafile record deliver absolutely wrong values.
Any ideas? This really drives me crazy ...
| Code: | type TSignChunk = record
SignOp : string[5];
Data : Array of TPoint;
end;
var
Form1: TForm1;
SignChunk: TSignChunk;
SignArray: Array of TSignChunk;
implementation
{$R *.dfm}
function MyEnhMetafileProc(DC: HDC; lpHTable: PHandleTable; lpEMFR: pEnhMetaRecord; nObj: Integer; TheForm:TForm1):Integer; stdcall;
var p: PEMRPolyline16;
rec: TENHMetaRecord;
i: Integer;
nb: Integer;
begin
PlayEnhMetafileRecord(dc, lpHTable^, lpEMFR^,nObj);
case lpEMFR^.iType of
EMR_Polyline16 : begin
p := PEMRPolyLine16(@rec);
nb := p.cpts;
SetLength(SignArray, Length(SignArray) + 1);
SignArray[High(SignArray)].SignOp := 'Pl';
SetLength(SignArray[High(SignArray)].Data, nb);
For I := 0 to nb -1 do
begin
SignArray[High(SignArray)].Data[I] := Point(p.apts[I].X, p.apts[I].y);
end;
end;
end;
result := 1;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
MyMetafile: TMetafile;
begin
MyMetafile := TMetafile.Create;
MyMetafile.LoadFromFile('sample.emf');
SignArray := nil;
EnumEnhMetafile(Canvas.Handle, MyMetafile.Handle, @MyEnhMetafileProc, self, rect(0, 0, MyMetafile.Width,MyMetafile.Height));
MyMetafile.Free;
end; |
|
|
| Back to top |
|
 |
Stefan Member
Joined: 27 Sep 2004 Posts: 49 Location: Netherlands
|
Posted: 27/10/04 10:49 Post subject: |
|
|
Hi,
The cpts does not seem to return the right ammount of points (and if it does it will surely overflow the maximum of your dynamic array)
try the following code:
| Code: |
procedure DrawPolyline16 (var rec: TEnhMetaRecord; dc: HDC);
var
p: PEMRPolyline16;
i: integer;
ar: array of TPoint;
begin
p := PEMRPolyline16(@rec);
SetLength(ar, Length(p.apts));
for i := 0 to Length(p.apts)-1 do
ar[i] := Point(p.apts[i].y, p.apts[i].x);
polyline(dc, ar, Length(ar)-1);
end;
function MyEnhMetafileProc(DC: HDC; lpHTable: PHandleTable; lpEMFR: pEnhMetaRecord; nObj: Integer; TheForm:TForm1):Integer; stdcall;
var
p: PEMRPolyline16;
rec: TENHMetaRecord;
i: Integer;
nb: Integer;
begin
PlayEnhMetafileRecord(dc, lpHTable^, lpEMFR^,nObj);
case lpEMFR^.iType of
EMR_Polyline16 : DrawPolyline16(rec, dc);
end;
result := 1;
end;
|
|
|
| Back to top |
|
 |
P_G Member
Joined: 14 Jun 2004 Posts: 21 Location: Germany
|
Posted: 28/10/04 09:16 Post subject: This drives me nuts ... |
|
|
| Stefan wrote: |
The cpts does not seem to return the right ammount of points (and if it does it will surely overflow the maximum of your dynamic array)
|
You're absolutely right, Stefan (I noticed this problem a couple of days ago too). But not only cpts doesn't return the correct number of points, returns always 1 (!). Even if I use something like 20 or so for the iteration of apts, the returned coordinates are absolutely wrong.
It seems as if Microsoft did not document the metafile in a proper way, I'm afraid.
I send you a metafile, but I checked this code with several metafiles as well, and the problem occurs with any of them.
Thank you so far for your interest in this problem and your time of course.
P_G
|
|
| Back to top |
|
 |
P_G Member
Joined: 14 Jun 2004 Posts: 21 Location: Germany
|
Posted: 28/10/04 09:25 Post subject: Attachment |
|
|
I hope the attachment works this time...
| Description: |
|
 Download |
| Filename: |
Hieroglyph.zip |
| Filesize: |
1.19 KB |
| Downloaded: |
42 Time(s) |
|
|
| Back to top |
|
 |
Stefan Member
Joined: 27 Sep 2004 Posts: 49 Location: Netherlands
|
Posted: 28/10/04 09:41 Post subject: nuts? I love nuts! |
|
|
P_G,
I've tried to draw your emf to canvas and it works perfectly (see attachment)....?
| Description: |
|
| Filesize: |
74.52 KB |
| Viewed: |
378 Time(s) |

|
|
|
| Back to top |
|
 |
Kambiz Administrator

Joined: 07 Mar 2003 Posts: 412 Location: Tehran, Iran
|
Posted: 28/10/04 14:01 Post subject: |
|
|
Stefan,
Please change your code as follow to see whether it is working.
| Code: | function MyEnhMetafileProc(DC: HDC; lpHTable: PHandleTable; lpEMFR: pEnhMetaRecord; nObj: Integer; TheForm:TForm1):Integer; stdcall;
var
p: PEMRPolyline16;
rec: TENHMetaRecord;
i: Integer;
nb: Integer;
begin
case lpEMFR^.iType of
EMR_Polyline16 : DrawPolyline16(rec, dc);
else
PlayEnhMetafileRecord(dc, lpHTable^, lpEMFR^,nObj);
end;
result := 1;
end; |
It's PlayEnhMetafileRecord that draws the polyline not your function.
|
|
| Back to top |
|
 |
Kambiz Administrator

Joined: 07 Mar 2003 Posts: 412 Location: Tehran, Iran
|
Posted: 28/10/04 14:24 Post subject: |
|
|
Do you know what? None of you has initialized the rec variable at your codes.
| Code: | procedure DrawPolyline16 (const rec: TEnhMetaRecord; dc: HDC);
var
Count: Integer;
Pt: PSmallPoint;
begin
with PEMRPolyline16(@Rec)^ do
begin
Count := cpts - 1;
Pt := @apts[0];
end;
MoveToEx(dc, Pt.x, Pt.y, nil);
while Count > 0 do
begin
Inc(Pt);
Dec(Count);
LineTo(dc, Pt.x, Pt.y);
end;
end;
function MyEnhMetafileProc(DC: HDC; lpHTable: PHandleTable; lpEMFR: pEnhMetaRecord; nObj: Integer; TheForm:TForm1):Integer; stdcall;
begin
case lpEMFR^.iType of
EMR_Polyline16 : DrawPolyline16(lpEMFR^, dc);
else
PlayEnhMetafileRecord(dc, lpHTable^, lpEMFR^,nObj);
end;
result := 1;
end; |
|
|
| Back to top |
|
 |
Stefan Member
Joined: 27 Sep 2004 Posts: 49 Location: Netherlands
|
Posted: 28/10/04 15:39 Post subject: |
|
|
good to still have you around Kambiz
|
|
| Back to top |
|
 |
P_G Member
Joined: 14 Jun 2004 Posts: 21 Location: Germany
|
Posted: 29/10/04 19:16 Post subject: |
|
|
Uhmm ... Yes ... That's it.
How could I ever doubt in a microsoft documentation ?
This code works perfectly.
Thanks a lot Kambiz and Stefan. You guys are lifesavers. I already had my own tombstone in mind: Died in the attempt to access metafile records...
P_G
|
|
| Back to top |
|
 |
|