home *** CD-ROM | disk | FTP | other *** search
/ Programming Tool Box / SIMS_2.iso / vb_code1 / apmmet / readme.txt < prev    next >
Text File  |  1992-08-19  |  5KB  |  141 lines

  1. If you try to print (or show) .WMF-Files with Visual BASIC, you may 
  2. run into the same problem as I did: I was not able to use some COREL-Draw
  3. Metafiles in Visual BASIC. 
  4. The problem is that .WMF is not .WMF for all files. Some .WMF-Files are
  5. true Windows-Metafiles which can be used without any error, but most
  6. of the Files are in the ALDUS-PLACEABLE-METAFILE-Format (APM).
  7. I found a description about the problem in the new WIN SDK 3.1-Doc.
  8. It is listed below.
  9.  
  10. Several months ago, I wrote a small DLL to use the APM-Files. There was
  11. an article in the Microsoft-Systems-Journal which had included a sample
  12. program.
  13.  
  14. My extensions to that are the following:
  15.  
  16. 1. I use a huge pointer to read the Metafile. Because of that I am
  17.    able to read Metafiles larger than 64 kBytes
  18.  
  19. 2. There is a function CreateMemhDC which creates a compatible Bitmap
  20.    for a given Device-Context in memory (thanks to Charles Petzold's
  21.    'Programming Windows'). I "play  the metafile into that Bitmap".
  22.    The reason to do this is that you can simply copy the created
  23.    Bitmap to your device via BITBLT. The Bitmap in memory has all 
  24.    the properties of the device, so you really 'draw on the device'.
  25.  
  26. 3. The third function (CopyMemToDev) copies the memory Bitmap to the device. 
  27.    Try it with a big .WMF-File. (My example was a file with 196000 Bytes,
  28.    a 20 MHz 386SX needs around 10 seconds to create the Bitmap in memory.
  29.    But you can copy this Bitmap 10 times to the printer in 5 seconds.)
  30.  
  31. 4. ClearMemhDC deletes the created Bitmap.
  32.  
  33.  
  34. Please find the DLL with the source and an example written in VisualBasic
  35. in this arcive. You may use the sources without any royalties.
  36.  
  37. I'm not sure if the DLL handles ALL possible errors. Feel free to
  38. contact me at 100042,47.
  39.  
  40.  
  41. ********************* WINDOWS 3.1 DOC  (courtesy of Microsoft) ************
  42.  
  43. Using Windows Metafile Functions and Aldus Placeable Metafiles
  44.  
  45. Summary
  46.  
  47. Many Windows applications import or export Windows metafiles in a format
  48. known as the Aldus Placeable Metafile (APM) format. In this format, these
  49. metafiles cannot be used with the Windows metafile functions such as
  50. GetMetaFile, CopyMetaFile, PlayMetaFile, and so on. To use these metafiles,
  51. the APM header must be removed from the metafile and the remaining metafile
  52. bits must be written to a newly created metafile.
  53.  
  54. More Information
  55.  
  56. The APM header is 22 bytes in length and is defined as follows:
  57.  
  58.  
  59. typedef struct
  60. {
  61.    DWORD   key;
  62.    HANDLE  hmf;
  63.    RECT    bbox;
  64.    WORD    inch;
  65.    DWORD   reserved;
  66.    WORD    checksum;
  67. } APMFILEHEADER;
  68.  
  69.  
  70. The following code fragment demonstrates how to create a memory-based
  71. Windows metafile from an Aldus Placeable Metafile that will work with the
  72. metafile functions provided by Windows. For more information regarding the
  73. APM format, call the Aldus Developer's Desk at (206) 622-5500 (ask for the
  74. third-party developer's desk).  This number is correct as of 1/31/92.
  75. Please contact Aldus for its latest policy on distribution of information
  76. about the APM format.
  77.  
  78.  
  79. BOOL RenderAPM (fh)
  80. int   fh; // a file handle to the APM metafile is passed in
  81. {
  82.     HANDLE           hData;
  83.     LPSTR            lpData;
  84.     DWORD            OffsetToMeta;
  85.     METAHEADER       mfHeader;
  86.     APMFILEHEADER    APMHeader;
  87.  
  88.     OffsetToMeta = sizeof(APMHeader);
  89.  
  90.     // Seek to beginning of file and read APM header
  91.     _llseek(fh, 0, 0);
  92.     if (!_lread(fh, (LPSTR)&APMHeader, sizeof(APMFILEHEADER)))
  93.        // Error in reading the file
  94.        return(FALSE);
  95.  
  96.    // Return to read metafile header
  97.  
  98.    _llseek(fh, OffsetToMeta, 0);
  99.  
  100.    if (!_lread(fh, (LPSTR)&mfHeader, sizeof(METAHEADER)))
  101.        // Error in reading
  102.        return(FALSE);
  103.  
  104.    // Allocate memory for memory based metafile
  105.  
  106.    if (!(hData = GlobalAlloc(GHND, (mfHeader.mtSize * 2L))))
  107.        return(FALSE);
  108.  
  109.    // Were we successful?
  110.    if (!(lpData = GlobalLock(hData)))
  111.    {
  112.        // Error in allocation
  113.        GlobalFree(hData);
  114.        return(FALSE);
  115.    }
  116.  
  117.    // Read metafile bits
  118.    _llseek(fh, OffsetToMeta, 0);
  119.    if (!_lread(fh, lpData, (mfHeader.mtSize * 2L)))
  120.    {
  121.        // Error in reading
  122.        GlobalUnlock(hData);
  123.        GlobalFree(hData);
  124.        return(FALSE);
  125.    }
  126.  
  127.    // Create the METAFILE with the bits we read in.
  128.  
  129.    if (!(hMF = SetMetaFileBits(hData)))
  130.        return(FALSE);
  131.  
  132.    GlobalUnlock(hData);
  133.  
  134.    // Close the APM file
  135.    _lclose(fh);
  136.  
  137.    // Return success
  138.    return(TRUE);
  139.  
  140. }
  141.