[Back to WIN-OS2 SWAG index] [Back to Main SWAG index] [Original]

    {
    From: ZWEITZE@ET.TUDelft.NL (Zweitze de Vries)

    >Metafiles made in BP won't import into Word for Windows, while
    >CorelDraw accepts the files. Does anyone know what's causing
    >this problem?

    Yes. There is not one Metafile format, there are three (!)
    (excluding NT formats). The original is meant for internal
    usage, like fast painting. Later this original was saved to
    file to enable graphics exchange. This gave problems,
    because of different mapping modes, and device resolutions.
    Still, MS wanted to encourage exchange, so two new metafile
    formats were developed, metafile to clipboard and the
    placeable metafile (which is saved to file).

    Word only accepts clipboard and placeable metafiles.
    A placeable metafile is an original metafile with a 22 byte
    header, which is called the placeable metafile header.
    This 22 byte record is documented in your online help topic
    'Metafile format'. The record type def is not implemented
    in BP, so you've got to type it yourself. (Or use my copy
    below)

    Hereby I supply my metafile output code. There are two
    entry points, which make the metafile go to clipboard or
    file. In case of file, a common dialog is displayed.

    {*****************************************************************************}
    {*                   Werkgroep Elektrotechnisch Practicum                    *}
    {*                       Faculteit der Elektrotechniek                       *}
    {*                       Technische Universiteit Delft                       *}
    {*****************************************************************************}
    {*                               project : CATE                              *}
    {* program      :  cateshell (werktitel)             date     :  Oct 1994    *}
    {* filename   :  APPCHILD.PAS                     version  :  0.61           *}
    {* author     :  Z.A. de Vries                    compiler :  BPW 7.0        *}
    {* description:  Performs basic MDI child window handling                    *}
    {*****************************************************************************}

    uses
      CommDlg, WinProcs, WinTypes, Objects, OWindows, Strings, Win31;

    {...}

    { Not found in runtime libs, this structure is the header of a so-called
      Placeable metafile. A Placeable metafile is a standard metafile with
      this 22byte header. This header is documented in the online help under
      'Metafile Format' }
    type
      PPlaceableMF = ^TPlaceableMF;
      TPlaceableMF = record
        Key:      LongInt;
        hMF:      THandle;
        BBox:     TRect;
        Inch:     Integer;
        Reserved: LongInt;
        Checksum: Integer;
      end;

    procedure TChildWndBase.MetafileToFile;
    var
      szNewName: PChar;
      szFilter: array [0..100] of Char;
      szExt: array [0..3] of Char;
      pFilter: PChar;
      SaveRec: TOpenFileName;
      wmfFile: PBufStream;
      wmfHeader: TPlaceableMF;
      hMetafile: THandle;
      pMetafile: PMetaHeader;
      ScrnDC: HDC;
    begin
      GetMem(szNewName, fsCompleteName);    { const fsCompleteName = 144 }

      FillChar(szFilter, SizeOf(szFilter), 0);
      StrCopy(szFilter, 'Windows Metafiles (*.WMF)');
      pFilter := StrEnd(szFilter);
      Inc(pFilter);
      pFilter := StrECopy(pFilter, '*.WMF');
      Inc(pFilter);
      pFilter := StrECopy(pFilter, 'All files (*.*)');
      Inc(pFilter);
      StrCopy(pFilter, '*.*');

      StrCopy(szNewName, '*.WMF');
      FillChar(SaveRec, SizeOf(SaveRec), 0);
      with SaveRec
        do begin
          hwndOwner     := Application^.MainWindow^.hWindow;
          lStructSize   := SizeOf(SaveRec);
          lpstrFile     := szNewName;
          nMaxFile      := fsCompleteName;
          Flags         := ofn_NoReadOnlyReturn or ofn_OverwritePrompt or
                           ofn_PathMustExist or ofn_ShowHelp or ofn_HideReadOnly;
          lpstrDefExt   := 'WMF';
          lpstrFilter   := szFilter;
          nFilterIndex  := 1;
        end;

      if GetSaveFileName(SaveRec)
        then begin
          ScrnDC := GetDC(hWindow);
          with wmfHeader
            do begin
              Key := $9AC6CDD7;
              hMF := 0;
              GetClientRect(hWindow, BBox);
              Inch := (GetDeviceCaps(ScrnDC, LogPixelsX) +
                       GetDeviceCaps(ScrnDC, LogPixelsY)) div 2;
              Reserved := 0;
              Checksum := $9AC6 xor $CDD7 xor BBox.Right xor BBox.Bottom xor Inch;
            end;
          ReleaseDC(hWindow, ScrnDC);

          hMetafile := DrawMetafile(nil);

          wmfFile := new(PBufStream, Init(szNewName, stCreate, 2048));
          wmfFile^.Write(wmfHeader, SizeOf(wmfHeader));
          pMetafile := GlobalLock(hMetafile);
          wmfFile^.Write(pMetafile^, pMetafile^.mtSize * 2);
          GlobalUnlock(hMetaFile);
          wmfFile^.Done;

          DeleteMetafile(hMetafile);
        end;

      FreeMem(szNewName, fsCompleteName);
    end;

    procedure TChildWndBase.MetafileToClipboard;
    const
      HiMetricPerInch = 2540;
    var
      hMetafile, hMetafileClipboardHeader: THandle;
      pMetafileClipboardHeader: PMetafilePict;
      rcWindow: TRect;
      RefDC: HDC;
    begin
      if not OpenClipboard(hWindow)
        then Exit;
      EmptyClipboard;

      hMetafile := DrawMetafile(nil);

      hMetafileClipboardHeader :=
              GlobalAlloc(gmem_DDEShare, SizeOf(TMetaFilePict));
      if (hMetafile = 0) or (hMetafileClipboardHeader = 0)
        then begin
          CloseClipboard;
          if hMetafile <> 0
            then GlobalFree(hMetafile);
          if hMetafileClipboardHeader <> 0
            then GlobalFree(hMetafileClipboardHeader);
          Exit;
        end;

      pMetafileClipboardHeader :=
              PMetaFilePict(GlobalLock(hMetafileClipboardHeader));
      with pMetafileClipboardHeader^
        do begin
          mm   := mm_Anisotropic;
          hMF  := hMetafile;
          GetClientRect(hWindow, rcWindow);  { Size is window size }
          with rcWindow
            do begin
              RefDC := GetDC(hWindow);
              xExt := MulDiv(Right - Left, HiMetricPerInch,
                             GetDeviceCaps(RefDC, LogPixelsX));
              yExt := MulDiv(Bottom - Top, HiMetricPerInch,
                             GetDeviceCaps(RefDC, LogPixelsY));
              ReleaseDC(hWindow, RefDC);
            end;
        end;

      GlobalUnlock(hMetafileClipboardHeader);
      SetClipboardData(cf_MetafilePict, hMetafileClipboardHeader);
      CloseClipboard;
    end;

    function TChildWndBase.DrawMetafile(szOutput: PChar): THandle;
    var
      MetaDC      : HDC;
      PaintStruct : TPaintstruct;
    begin
      MetaDC := CreateMetaFile(szOutput);
      SetMapMode(MetaDC, mm_anisotropic);
      SetWindowOrg(MetaDC, 0, 0);

      with PaintStruct
        do begin
          hdc    := MetaDC;
          fErase := false;
          GetClientRect(hWindow, rcPaint);
          with rcPaint
            do begin
                       { Its size is exact the same as the window size }
              SetWindowExt(MetaDC, Right - Left, Bottom - Top);

                       { Setup a clipping rectangle }
              IntersectClipRect(MetaDC, Left, Top, Right, Bottom);

                       { Setup the background color of the metafile
                         which is the same as the window background }
              SelectObject(MetaDC, GetClassWord(hWindow, gcw_hbrBackground));
              PatBlt(MetaDC, Left, Top, Right, Bottom, PatCopy);
              SelectObject(MetaDC, GetStockObject(Hollow_Brush));
            end;
        end;

      DrawContents(MetaDC, PaintStruct);
           { DrawContents does the actual drawing. It is also called by
             my painting and printing handlers. DrawContents assumes it
             is working in MM_TEXT mode, when the output is going to a
             metafile, the actual mapping mode is MM_ANISOTROPIC, but
             resembling MM_TEXT on any device. }

      DrawMetafile := CloseMetaFile(MetaDC);
    end;

[Back to WIN-OS2 SWAG index] [Back to Main SWAG index] [Original]