The metafiles generated by Objective Grid are not read by some applications including Word 6. Why does this happen?
These applications expect the .wmf file to have a placeable header. The code for adding this header is as below
///.h file
typedef struct tagOLDRECT
{
short left;
short top;
short right;
short bottom;
} OLDRECT;
typedef struct {
DWORD key;
WORD hmf;
OLDRECT bbox;
WORD inch;
DWORD reserved;
WORD checksum;
}ALDUSMFHEADER;
///.cpp file
#define ALDUSSIZE 22
#define METASIZE 18
BOOL CServ3View::WriteMetaFileAsPlaceable( HMETAFILE hMetaFile, LPCTSTR lpstrOutFileName )
{
HANDLE hOutFile;
ALDUSMFHEADER APMFileHeader;
METAHEADER mh;
// Fill out the placeable header
APMFileHeader.key = APMHEADER_KEY;
APMFileHeader.hmf = NULL;
APMFileHeader.inch = 1000;
APMFileHeader.reserved = 0;
APMFileHeader.bbox.left = 0;//nXOrg;
APMFileHeader.bbox.top = 0;//nYOrg;
APMFileHeader.bbox.right = 500;
APMFileHeader.bbox.bottom = 500;
APMFileHeader.checksum = CalculateAPMCheckSum( APMFileHeader );
// Get the bits
int nSize = GetMetaFileBitsEx( hMetaFile, NULL, NULL);
char* pBuffer = new char[nSize];
char* pOldBuffer = pBuffer;
ASSERT(GetMetaFileBitsEx( hMetaFile, nSize, pBuffer));
// Open the file
hOutFile = CreateFile(
lpstrOutFileName, // pointer to name of the file
GENERIC_WRITE, // access (read-write) mode
0, // share mode
NULL, // pointer to security descriptor
CREATE_ALWAYS, // how to create
FILE_ATTRIBUTE_NORMAL, // file attributes
NULL // handle to file with attributes to copy
);
if(!hOutFile)
return FALSE;
DWORD dwNumBytes;
// Write the header
if (!WriteFile(
(HANDLE)hOutFile, // handle to file to write to
(void*) &APMFileHeader, // pointer to data to write to file
ALDUSSIZE, // number of bytes to write
&dwNumBytes, // pointer to number of bytes written
NULL // pointer to structure needed for overlapped I/O
))
{
CloseHandle( (HANDLE)hOutFile );
AfxMessageBox(_T("1 write fails"));
return FALSE;
}
// Write the header
memcpy((void*)&mh, (const void *) pBuffer, sizeof(METAHEADER));
if (!WriteFile(
(HANDLE)hOutFile, // handle to file to write to
(void*) &mh, // pointer to data to write to file
sizeof( mh ), // number of bytes to write
&dwNumBytes, // pointer to number of bytes written
NULL // pointer to structure needed for overlapped I/O
))
{
CloseHandle( (HANDLE)hOutFile );
AfxMessageBox(_T("1 write fails"));
return FALSE;
}
pBuffer +=METASIZE;
// Write the bits
if (!WriteFile(
(HANDLE)hOutFile, // handle to file to write to
(void*) pBuffer, // pointer to data to write to file
nSize-METASIZE, // number of bytes to write
&dwNumBytes, // pointer to number of bytes written
NULL // pointer to structure needed for overlapped I/O
))
{
CloseHandle( (HANDLE)hOutFile );
AfxMessageBox(_T("2 write fails"));
return FALSE;
}
// Close the file
CloseHandle( (HANDLE)hOutFile );
// clean up
delete pOldBuffer;
return TRUE;
}
WORD CServ3View::CalculateAPMCheckSum( ALDUSMFHEADER apmfh )
{
LPWORD lpWord;
WORD wResult, i;
// Start with the first word
wResult = *(lpWord = (LPWORD)(&apmfh));
// XOR in each of the other 9 words
for(i=1;i<=9;i++)
{
wResult ^= lpWord[i];
}
return wResult;
}