I have read your interesting article regarding parsing EMF files with GDI+.
I tried to follow your guidlines, but somehow my callback function is not triggered.
You can see my code below.
// emf2gdi.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
using namespace std;
#include <windows.h>
#include <gdiplus.h>
using namespace Gdiplus;
using namespace System;
#pragma comment (lib, "gdiplus.lib")
#using <mscorlib.dll>
#using <System.dll>
#using <System.Windows.Forms.dll>
#using <System.Drawing.dll>
using namespace System::Windows::Forms;
using namespace System;
using namespace System::Drawing;
using namespace System::Drawing::Imaging;
using namespace System::Drawing::Text;
//using namespace System::Drawing::Drawing2D;
//using namespace System::Runtime::ConstrainedExecution;
//using namespace System::Globalization;
//using namespace System::Runtime::Versioning;
/*static bool CALLBACK EnumMetaCB(Gdiplus::EmfPlusRecordType recordType, int flags, int dataSize, IntPtr data, System::Drawing::Imaging::PlayRecordCallback^ callbackData) {
string str = " ";
cout << "At EnumMetaCB\n";
// Play only EmfPlusRecordType.FillEllipse records
if (recordType == Gdiplus::EmfPlusRecordTypeFillEllipse
|| recordType == Gdiplus::EmfPlusRecordTypeFillRects
|| recordType == Gdiplus::EmfPlusRecordTypeDrawEllipse
|| recordType == Gdiplus::EmfPlusRecordTypeDrawRects) {
str = "Record type:" + recordType.ToString() +
", Flags:" + flags.ToString() +
", Data :" + data.ToString();
MessageBox.Show(str);
}
return true;
}*/
class EMF2GDI {
public:
static BOOL CALLBACK metaCallback(Gdiplus::EmfPlusRecordType recordType, unsigned int flags, unsigned int dataSize, const unsigned char* pStr, void* callbackData) {
cout << "In callback function...\n";
// Play only EmfPlusRecordTypeFillEllipse records.
if (recordType == EmfPlusRecordTypeFillEllipse) {
// Explicitly cast callbackData as a metafile pointer, and use it to call
// the PlayRecord method.
//pThis->m_pMetafile->PlayRecord(recordType, flags, dataSize, pStr);
static_cast < Gdiplus::Metafile* > (callbackData)->PlayRecord(recordType, flags, dataSize, pStr);
}
return TRUE;
}
VOID EnumerateMetaFile_Click() {
//HDC hdc = CreateCompatibleDC(NULL);
//Gdiplus::Graphics graphics(hdc);
// Create a Metafile object from an existing disk metafile.
// This constructor creates a Metafile::Metafile object for playback
Status status;
Gdiplus::Metafile* pMeta = new Gdiplus::Metafile(L"C:\\ProgramData\\Temp\\2015-03-02.11.20.52.45-00003.EMF");
//use the meta as an argument to the constructor to open for reading
Gdiplus::Graphics g(pMeta);
Gdiplus::MetafileHeader* header = new Gdiplus::MetafileHeader();
status = pMeta->GetMetafileHeader(L"C:\\ProgramData\\Temp\\2015-03-02.11.20.52.45-00003.EMF", header);
BOOL isEmf = header->IsEmf();
BOOL isDual = header->IsEmfPlusDual();
BOOL isPlusOnly = header->IsEmfPlusOnly();
//HENHMETAFILE hEmf = pMeta->GetHENHMETAFILE();
//Gdiplus::Metafile* playbackMeta = new Gdiplus::Metafile(hEmf, TRUE);
//pView->m_pMetafile = playbackMeta;
EMF2GDI* pView = new EMF2GDI();
Gdiplus::Point* point = new Gdiplus::Point(0, 0);
////Gdiplus::Point* pointArray = new Gdiplus::Point[1];
////pointArray[0] = new Gdiplus::Point(0, 0)
Gdiplus::EnumerateMetafileProc* enumMetaCB = new Gdiplus::EnumerateMetafileProc(&metaCallback);
////graphics.EnumerateMetafile(curMetafile, point, 1, EMF2GDI::EnumMetaCB);
g.EnumerateMetafile(pMeta, *point, metaCallback, pMeta);
// Draw pMeta as an image.
//graphics.DrawImage(pMeta, Point(0, 150));
delete pMeta;
}
};
int _tmain(int argc, _TCHAR* argv[]) {
//initialize GDI plus
cout << "Initializing GDI...\n";
//Initializw gdi plus
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
EMF2GDI emf2gdi;
emf2gdi.EnumerateMetaFile_Click();
//Shut down GdiPlus
GdiplusShutdown(gdiplusToken);
//Adding a return 0 to main will close the console app
//return 0;
}