Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Чтение wmf


Gydvin ©   (2007-08-24 07:43:00) 

Немогу понять где обшибка (( гляньте плз кто небуть

function MFDumpCallBack(H: HDC; HT: PHandletable; MFRec: pEnhMetaRecord; cnt: Integer; Data: Pointer): Integer;
begin
 case MFREC^.iType of   //    AV на этой строке
   EMR_GDICOMMENT:
     begin
{закоментированный код}
     end;
 end;
  result:=1;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 wmf: tmetafile;
 ft: string;
 RShow: trect;
begin
 if opendialog1.Execute and fileexists(opendialog1.FileName) then
 begin
   wmf := tmetafile.Create;
   wmf.LoadFromFile(opendialog1.FileName);
   ft := '';
   EnumEnhMetafile(0, wmf.Handle, @MFDumpCallBack, @FT, RShow);
  // memo1.Text := ft;
   wmf.Free;
 end;
end;


Gydvin   (2007-08-24 11:10:00) [1]


> во-первых, sizeof(rec)) = 4 (размер указателя),

а ну да, конечно.

Так?

var
 stream: tstream;
 rec: tEnhMetaRecord;
 x, a, b: integer;
begin
 stream := tfilestream.Create('my.wmf', fmopenread);
//после прочтения заголовка
 for x := 0 to кол - во записей - 1 do
 begin
   a := stream.Position;
   stream.Read(rec, sizeof(rec));
   b:=(rec.nSize-1)*sizeof(dword);
   stream.Position:=a;
   stream.Read(rec, sizeof(rec)+b);
 end;
 stream.Free;


MBo   (2007-08-24 10:50:00) [2]

>он адекватно пробежит по записям?
нет, конечно.
во-первых, sizeof(rec)) = 4 (размер указателя), но даже и при использовании
SizeOf(TEnhMetaRecord) будет не то,что нужно - размер всегда надо брать из nSize


Gydvin   (2007-08-24 09:51:00) [3]

Тоесть если я создам такой код, он адекватно пробежит по записям?

procedure TForm1.Button3Click(Sender: TObject);
var
 stream: tstream;
 rec: PEnhMetaRecord;
 x: integer;
begin
 stream := tfilestream.Create('my.wmf', fmopenread);
//после прочтения заголовка
 for x := 0 to кол - во записей - 1 do
   stream.Read(rec, sizeof(rec));
 stream.Free;
end;


MBo   (2007-08-24 09:23:00) [4]

emf-файл:
заголовок
запись1
тип
размер данных
данные
запись2
тип
размер данных
данные

память под каждую запись уже выделена.


Gydvin   (2007-08-24 09:13:00) [5]


> >dParm: array[0..0] of DWORD;   {конкретно интересует это,
>  что сие значит. и если не ошибаюсь тут четыре байта}Запись
> переменной длины  nSize


Тоесть dParm: array[0..0] of DWORD это начало первого двойного слова (4 байта) из цепочки длиной указанной в nSize? Несовсем понятно как технически происходит хранение данных в dParm. Или получаем адрес первого слова в памяти, а затем копируем копируем всю цепочку? Тогда вопрос что мешает проге записать, что-либо поверх, так как размеры структуры не указаны явно. Опять предположение, что необходимо жестко выделять память (getmem) и самому прописывать смещение каждой последущей структуры относительно предыдущей. Короче в голове каша.


MBo   (2007-08-24 08:48:00) [6]

>dParm: array[0..0] of DWORD;   {конкретно интересует это, что сие значит. и если не ошибаюсь тут четыре байта}

Запись переменной длины  nSize

>ну и здесь, как можно структуру описанную 12 байтами привести к структуре описанной как минимум 27 (больше не считал) байтами

именно переменная длина позволяет это делать


Gydvin   (2007-08-24 08:35:00) [7]

И еще вопрос, если можно. Так сказать для общего развития. Просьба пояснить происходящие в нижепредставленном рабочем коде процессы.

PEnhMetaRecord = ^TEnhMetaRecord;
tagENHMETARECORD = packed record
   iType: DWORD;
   nSize: DWORD;
   dParm: array[0..0] of DWORD;   {конкретно интересует это, что сие значит. и если не ошибаюсь тут четыре байта}
 end;
TEnhMetaRecord = tagENHMETARECORD;

____________________________________________

tagEMRTEXT = packed record
   ptlReference: TPoint;
   nChars: DWORD;
   offString: DWORD; { Offset to the string}
   fOptions: DWORD;
   rcl: TRect;
   offDx: DWORD;     { Offset to the inter-character spacing array.}
                     { This is always given.}
 end;
 TEMRText = tagEMRTEXT;

tagEMR = packed record
   iType: DWORD;
   nSize: DWORD;
             
 end;
 TEMR = tagEMR;

PEMRExtTextOut = ^TEMRExtTextOut;
tagEMREXTTEXTOUTA = packed record
   emr: TEMR;
   rclBounds: TRect;    
   iGraphicsMode: DWORD;
   exScale: Single;      
   eyScale: Single;      
   emrtext: TEMRText;    
 end;
TEMRExtTextOut = tagEMREXTTEXTOUTA;


.........

function MFDumpCallBack(H: HDC; HT: PHandletable; MFRec: pEnhMetaRecord; cnt: Integer; Data: Pointer): Integer; stdcall;
var
 PS: PChar;
 PW: PWideChar;
begin
 case MFREC^.iType of
   EMR_EXTTEXTOUTW:
     begin
       with PEMREXTTEXTOUT(MFREC)^     {ну и здесь, как можно структуру описанную 12 байтами привести к структуре описанной как минимум 27 (больше не считал) байтами. Возможно, что я ошибаюсь. Просьба пояснить, что тут происходит.}
do
       begin
         PS := PCHAR(MFREC);
         PS := PS + emrtext.offString;
         PW := PWideChar(PS);
         string(Data^) := string(Data^) + WideCharLenToString(PW, emrtext.nChars) + #13#10;
       end;
     end;
 end;


Gydvin   (2007-08-24 07:54:00) [8]


> MBo ©   (24.08.07 07:52) [2]

Ой точно. Спасибо


Gydvin   (2007-08-24 07:53:00) [9]

Нет. Просто AV at address xxxxxxx in module in progect1.exe. read of address 0000000


MBo   (2007-08-24 07:52:00) [10]

в колбэке stdcall явно не хватает


alshtam   (2007-08-24 07:47:00) [11]

а вчем ошибка компилятор не ругается (какая проблема то)


Наверх

Титульная страница Поиск, карта сайта Написать письмо