How to Convert a Metafile to a PDF Using C++
Knowledge Base :: PDF Creator Pilot 4 Knowledge Base

See Also Example
Collapse All

First, import the PDF Creator Pilot library into your project.

#import "c:\\...\\PDFCreatorPilot.dll" // enter path here
using namespace PDFCreatorPilotLib;

Then initialize a PDFDocument object.

IPDFDocument4* PDF = NULL;

CLSID clsid_PDFCreatorPilot;
CLSIDFromProgID(OLESTR("PDFCreatorPilot.PDFDocument4"), &clsid_PDFCreatorPilot);
::CoCreateInstance(clsid_PDFCreatorPilot, NULL, CLSCTX_ALL, __uuidof(IPDFDocument4), (LPVOID*)&PDF); 
if(PDF == NULL)
{
  ::CoUninitialize();
  return 1;
}

Call the SetLicenseData method and adjust properties as needed.

Load an EMF file so you can access its width, height, and resolution properties. Calculate the scaleFactor. This value is needed to properly draw the EMF file to the PDF page.

long lDPI = 96; // default DPI
ENHMETAHEADER emh;
GetEnhMetaFileHeader(hEmf, sizeof(emh), &emh);
float f_mmPerInch = 25.4f;
double fDPI = f_mmPerInch / (((float)emh.szlMillimeters.cx * 1000.0f) / (emh.szlDevice.cx * 1000.0f));
if (fDPI - (long)fDPI > 0.5)
  lDPI = (long)fDPI + 1;
else
  lDPI = (long)fDPI;
float fHeight = (float)abs(emh.rclFrame.bottom - emh.rclFrame.top) * (float)emh.szlDevice.cy * 10.0f / ((float)emh.szlMillimeters.cy * 1000.0f);
float fWidth = (float)abs(emh.rclFrame.right - emh.rclFrame.left) * (float)emh.szlDevice.cx * 10.0f / ((float)emh.szlMillimeters.cx * 1000.0f);
DeleteEnhMetaFile(hEmf);

// Scale factor based on the resolutions difference
double dScaleFactor = (double)PDF->PageResolution / (double)lDPI;

PDF->PageHeight = (long)(fHeight * dScaleFactor);
PDF->PageWidth = (long)(fWidth * dScaleFactor);

Then to convert the EMF file to a PDF, call the PlayMetaFile method.

PDF->PlayMetaFile(emfFile, 0, 0, dScaleFactor, dScaleFactor);
PDF->SaveToFile("PlayMetafile.pdf", true);

You can find a full example bellow. You may also download a MS Visual Studio project with this example here.

Example

Converting a Metafile to a PDF

C/C++
[copy to clipboard]
#include "stdafx.h"

// set correct path to PDFCreatorPilot.dll in the line bellow
#import "c:\\...\\PDFCreatorPilot.dll"
using namespace PDFCreatorPilotLib;

int _tmain(int argc, _TCHAR* argv[])
{
    ::CoInitialize(NULL);
    // declare PDF Creator Pilot object
    IPDFDocument4* PDF = NULL;

    CLSID clsid_PDFCreatorPilot;
    CLSIDFromProgID(OLESTR("PDFCreatorPilot.PDFDocument4"), &clsid_PDFCreatorPilot);
    ::CoCreateInstance(clsid_PDFCreatorPilot, NULL, CLSCTX_ALL, __uuidof(IPDFDocument4), (LPVOID*)&PDF);        
    if(PDF == NULL)
    {
        ::CoUninitialize();
        return 1;
    }

    PDF->SetLicenseData("demo","demo");

    _TCHAR* emfFile = L"C:\\path\\to\\some.emf";
    HENHMETAFILE hEmf = GetEnhMetaFile(emfFile);
    if (!hEmf)
    {
        ::CoUninitialize();
        return 2;
    }

    long lDPI = 96; // default DPI
    ENHMETAHEADER emh;
    GetEnhMetaFileHeader(hEmf, sizeof(emh), &emh);
    float f_mmPerInch = 25.4f;
    double fDPI = f_mmPerInch / (((float)emh.szlMillimeters.cx * 1000.0f) / (emh.szlDevice.cx * 1000.0f));
    if (fDPI - (long)fDPI > 0.5)
        lDPI = (long)fDPI + 1;
    else
        lDPI = (long)fDPI;
    float fHeight = (float)abs(emh.rclFrame.bottom - emh.rclFrame.top) * (float)emh.szlDevice.cy * 10.0f / ((float)emh.szlMillimeters.cy * 1000.0f);
    float fWidth = (float)abs(emh.rclFrame.right - emh.rclFrame.left) * (float)emh.szlDevice.cx * 10.0f / ((float)emh.szlMillimeters.cx * 1000.0f);
    DeleteEnhMetaFile(hEmf);

    // Scale factor based on the resolutions difference
    double dScaleFactor = (double)PDF->PageResolution / (double)lDPI;

    PDF->PageHeight = (long)(fHeight * dScaleFactor);
    PDF->PageWidth  = (long)(fWidth * dScaleFactor);

    PDF->PlayMetaFile(emfFile, 0, 0, dScaleFactor, dScaleFactor);
    PDF->SaveToFile("PlayMetafile.pdf", true);

    ::CoUninitialize();
    return 0;
}

See Also

Reference