DELPHI AREA
MESSAGE BOARD
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

How to access metafile records ?
Goto page 1, 2  Next
 
   Reply to topic    DELPHI AREA Forum Index -> Delphi Programming
View previous topic :: View next topic  
Author Message
P_G
Member


Joined: 14 Jun 2004
Posts: 21
Location: Germany

PostPosted: 14/10/04 13:22    Post subject: How to access metafile records ? Reply with quote

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
View user's profile
P_G
Member


Joined: 14 Jun 2004
Posts: 21
Location: Germany

PostPosted: 15/10/04 09:36    Post subject: How to access the records of a metafile Reply with quote

No ideas? Anyone?
Back to top
View user's profile
Stefan
Member


Joined: 27 Sep 2004
Posts: 49
Location: Netherlands

PostPosted: 15/10/04 13:12    Post subject: Reply with quote

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
View user's profile Send e-mail
P_G
Member


Joined: 14 Jun 2004
Posts: 21
Location: Germany

PostPosted: 18/10/04 11:43    Post subject: Metafile records Reply with quote

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
View user's profile
Stefan
Member


Joined: 27 Sep 2004
Posts: 49
Location: Netherlands

PostPosted: 18/10/04 15:16    Post subject: Reply with quote

P_G,

Have a look at:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/metafile_5hkj.asp

for an overview of all possible metafile records and how to parse them...

Cheers,
Stefan
Back to top
View user's profile Send e-mail
P_G
Member


Joined: 14 Jun 2004
Posts: 21
Location: Germany

PostPosted: 19/10/04 10:35    Post subject: Metafile records Reply with quote

Thanks, Stefan

That's exactly what I was looking for.

P_G
Back to top
View user's profile
P_G
Member


Joined: 14 Jun 2004
Posts: 21
Location: Germany

PostPosted: 25/10/04 10:16    Post subject: Reply with quote

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
View user's profile
Stefan
Member


Joined: 27 Sep 2004
Posts: 49
Location: Netherlands

PostPosted: 27/10/04 10:49    Post subject: Reply with quote

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
View user's profile Send e-mail
P_G
Member


Joined: 14 Jun 2004
Posts: 21
Location: Germany

PostPosted: 28/10/04 09:16    Post subject: This drives me nuts ... Reply with quote

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,
Code:
Length(p.apts)
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
View user's profile
P_G
Member


Joined: 14 Jun 2004
Posts: 21
Location: Germany

PostPosted: 28/10/04 09:25    Post subject: Attachment Reply with quote

I hope the attachment works this time...


Hieroglyph.zip
 Description:

Download
 Filename:  Hieroglyph.zip
 Filesize:  1.19 KB
 Downloaded:  42 Time(s)

Back to top
View user's profile
Stefan
Member


Joined: 27 Sep 2004
Posts: 49
Location: Netherlands

PostPosted: 28/10/04 09:41    Post subject: nuts? I love nuts! Reply with quote

P_G,

I've tried to draw your emf to canvas and it works perfectly (see attachment)....?



Nieuw - Bitmapafbeelding.GIF
 Description:
tada... :)
 Filesize:  74.52 KB
 Viewed:  378 Time(s)

Nieuw - Bitmapafbeelding.GIF


Back to top
View user's profile Send e-mail
Kambiz
Administrator


Joined: 07 Mar 2003
Posts: 412
Location: Tehran, Iran

PostPosted: 28/10/04 14:01    Post subject: Reply with quote

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
View user's profile Send e-mail Visit poster's website
Kambiz
Administrator


Joined: 07 Mar 2003
Posts: 412
Location: Tehran, Iran

PostPosted: 28/10/04 14:24    Post subject: Reply with quote

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
View user's profile Send e-mail Visit poster's website
Stefan
Member


Joined: 27 Sep 2004
Posts: 49
Location: Netherlands

PostPosted: 28/10/04 15:39    Post subject: Reply with quote

good to still have you around Kambiz Smile
Back to top
View user's profile Send e-mail
P_G
Member


Joined: 14 Jun 2004
Posts: 21
Location: Germany

PostPosted: 29/10/04 19:16    Post subject: Reply with quote

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
View user's profile
Display posts from previous:   
   Reply to topic    DELPHI AREA Forum Index -> Delphi Programming All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB 2.0.6 © 2001, 2002 phpBB Group