home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Programming Tool Box
/
SIMS_2.iso
/
vb_code1
/
apmmet
/
apmmeta.c
next >
Wrap
C/C++ Source or Header
|
1992-08-19
|
10KB
|
369 lines
/**************************************************************************
* *
* Library to support APM-Metafiles for VisualBasic *
* *
* Name : APMMETA.C *
* Author : U. Reisewitz CIS 100042,47 *
* created : 01/20/92 *
* *
**************************************************************************/
#include <windows.h>
#include <stdlib.h>
#include <io.h>
typedef struct
{
DWORD dwKey;
HANDLE hMF;
RECT rcBBox;
WORD wInch;
DWORD dwReserved;
WORD wChecksum;
} APMHEADER;
typedef struct
{
HANDLE hMetaMem;
short Left;
short Top;
short Right;
short Bottom;
} METABITMAP;
#define BLSIZE 2048
/**************************************************************************
Declaration of external procedures
**************************************************************************/
/**************************************************************************
Declaration of internal procedures
**************************************************************************/
int far pascal LibMain(HANDLE hModule, WORD wDataSeg, WORD cbHeapSize,
LPSTR lpszCmdLine);
int far pascal LoadAPMetaFile(char far *FileName, APMHEADER far *APMHdr);
int far pascal CreateMemhDC(APMHEADER far *APMHdr, METABITMAP far *MetaBmp,
HANDLE hDC);
int far pascal CopyMemToDev(METABITMAP far *MetaBmp, HANDLE hDC,
int Xorg, int Yorg);
void far pascal ClearMemhDC(METABITMAP far *MetaBmp);
/**************************************************************************
Declaration of global variables
**************************************************************************/
HANDLE hOurInstance;
/**************************************************************************
LibMain - Is called by LibEntry. LibEntry is called by Windows when
the DLL is loaded. It initializes the DLL's heap and then
calls LibMain.
**************************************************************************/
int far pascal LibMain(HANDLE hModule, WORD wDataSeg, WORD cbHeapSize,
LPSTR lpszCmdLine)
{
hOurInstance = hModule;
LocalInit(wDataSeg, 0, cbHeapSize);
return (TRUE);
}
/**************************************************************************
LoadAPMetaFile - Load Windows Metafile. The APM-Metafile will be
opened and copied to a Memory-Metafile. The
APM-Headerstructure is returned to the
calling process.
**************************************************************************/
int far pascal LoadAPMetaFile(char far *FileName, APMHEADER far *APMHdr)
{
GLOBALHANDLE hData;
int fh;
char _huge *hpData;
char _huge *hpDataR;
DWORD dwReadSize;
WORD wSteps, wReadRest, wAktStep;
METAHEADER mfHeader;
int RetVar, i;
WORD TChecksum;
WORD far *pWord;
DWORD FileStat;
// initialize or return value
RetVar = 0;
// open the APM-File
fh = _lopen(FileName, OF_SHARE_DENY_WRITE);
if (fh == -1)
{
RetVar = 1;
goto ExLoadAPMetaFile;
}
// we start at the beginning...
_llseek(fh, 0, 0);
// read the APM-Header
FileStat =_lread(fh, (LPSTR) APMHdr, sizeof(APMHEADER));
if (FileStat < 0)
{
RetVar = 2;
goto ExLoadAPMetaFile;
}
// Test checksum
pWord = (WORD far *) APMHdr;
TChecksum = 0;
for (i = 0; i < 10; i++)
TChecksum ^= pWord[i];
if (TChecksum != APMHdr->wChecksum)
{
RetVar = 3;
goto ExLoadAPMetaFile;
}
// Read windows-metafile-header
_llseek(fh, sizeof(APMHEADER), 0);
FileStat = _lread(fh, (LPSTR) &mfHeader, sizeof(mfHeader));
if (FileStat < 0)
{
RetVar = 4;
goto ExLoadAPMetaFile;
}
// allocate memory for metafile
dwReadSize = mfHeader.mtSize * 2L;
if (! (hData = GlobalAlloc(GHND, dwReadSize)))
{
RetVar = 5;
goto ExLoadAPMetaFile;
}
// we use a huge pointer. because of that we are able to
// support metafiles larger than 64 kBytes
if (! (hpData = (char _huge *) GlobalLock(hData)))
{
GlobalFree(hData);
RetVar = 6;
goto ExLoadAPMetaFile;
}
// if you have WINDOWS 3.1, you may use the block with the
// remarks. it uses the new _hread-function, which is able
// to read more than 64 kBytes at once
if (dwReadSize > 65536L)
{
wSteps = (WORD) (dwReadSize / BLSIZE);
wReadRest = (WORD) (dwReadSize % BLSIZE);
}
else
{
wSteps = 0;
wReadRest = (WORD) dwReadSize;
}
hpDataR = hpData;
_llseek(fh, sizeof(APMHEADER), 0);
for (wAktStep = 0; wAktStep < wSteps; wAktStep++)
{
FileStat = _lread(fh, hpDataR, BLSIZE);
if (FileStat < 0)
{
GlobalUnlock(hData);
GlobalFree(hData);
RetVar = 7;
goto ExLoadAPMetaFile;
}
hpDataR += BLSIZE;
}
FileStat = _lread(fh, hpDataR, wReadRest);
if (FileStat < 0)
{
GlobalUnlock(hData);
GlobalFree(hData);
RetVar = 8;
goto ExLoadAPMetaFile;
}
// FileStat = _hread(fh, hpData, dwReadSize);
// if ((FileStat == -1L) || (FileStat != dwReadSize))
// {
// GlobalUnlock(hData);
// GlobalFree(hData);
// RetVar = 8;
// goto ExLoadAPMetaFile;
// }
// close the file, we don't need it any more
FileStat = _lclose(fh);
fh = 0;
if (FileStat != 0L)
{
GlobalUnlock(hData);
RetVar = 9;
goto ExLoadAPMetaFile;
}
GlobalUnlock(hData);
// now we create a windows metafile out of our memoryblock
if (! (APMHdr->hMF = SetMetaFileBits(hData)))
{
RetVar = 10;
goto ExLoadAPMetaFile;
}
ExLoadAPMetaFile:
if (fh != 0) // something was wrong
_lclose(fh);
return (RetVar);
}
/**************************************************************************
CreateMemhDC - creates a device-compatible bitmap from a
given metafile. The bitmap-information is
returned in a METABITMAP-structure.
**************************************************************************/
int far pascal CreateMemhDC(APMHEADER far *APMHdr, METABITMAP far *MetaBmp,
HANDLE hDC)
{
long PixPerInchX, PixPerInchY, PixelsX, PixelsY;
HBITMAP hBitMap;
int RetVar = 0;
// if the device doesn't support BITBLT, we can stop here
RetVar = GetDeviceCaps(hDC, RASTERCAPS);
if ((RetVar & RC_BITBLT) == 0)
{
RetVar = 1;
goto ExCreateMemhDC;
}
PixPerInchX = GetDeviceCaps(hDC, LOGPIXELSX);
PixPerInchY = GetDeviceCaps(hDC, LOGPIXELSY);
// size the metafile to its original size
MetaBmp->Left = 0;
MetaBmp->Right = (short) (PixPerInchX *
abs(APMHdr->rcBBox.right - APMHdr->rcBBox.left) /
APMHdr->wInch);
MetaBmp->Top = 0;
MetaBmp->Bottom = (short) (PixPerInchY *
abs(APMHdr->rcBBox.bottom - APMHdr->rcBBox.top) /
APMHdr->wInch);
MetaBmp->hMetaMem = CreateCompatibleDC(hDC);
// now create a bitmap that is compatible with the device
// we want to use
hBitMap = CreateCompatibleBitmap(hDC, MetaBmp->Right, MetaBmp->Bottom);
SelectObject(MetaBmp->hMetaMem, hBitMap);
RetVar = PatBlt(MetaBmp->hMetaMem, 0, 0,
MetaBmp->Right, MetaBmp->Bottom, WHITENESS);
SetMapMode(MetaBmp->hMetaMem, MM_ANISOTROPIC);
// play the metafile "into the device context"
// after that, we have a bitmap which can be transferred
// to the printer as many times as we like with a
// simple BITBLT-command
SaveDC(MetaBmp->hMetaMem);
SetViewportOrg(MetaBmp->hMetaMem, 0, 0);
SetViewportExt(MetaBmp->hMetaMem, MetaBmp->Right, MetaBmp->Bottom);
RetVar = PlayMetaFile(MetaBmp->hMetaMem, APMHdr->hMF);
RestoreDC(MetaBmp->hMetaMem, -1);
// we don`t need the metafile any more
RetVar = DeleteMetaFile(APMHdr->hMF);
RetVar = 0;
ExCreateMemhDC:
return(RetVar);
}
/**************************************************************************
CopyMemToDev - copies the content of a device-compatible bitmap
to the physical device.
**************************************************************************/
int far pascal CopyMemToDev(METABITMAP far *MetaBmp, HANDLE hDC,
int Xorg, int Yorg)
{
int RetVar;
SetMapMode(hDC, GetMapMode(MetaBmp->hMetaMem));
// it's unbelievable, that's really all!!!
RetVar = BitBlt(hDC, Xorg, Yorg,
MetaBmp->Right, MetaBmp->Bottom,
MetaBmp->hMetaMem, 0, 0, SRCCOPY);
return(RetVar);
}
/**************************************************************************
ClearMemhDC - deletes a device-compatible bitmap.
**************************************************************************/
void far pascal ClearMemhDC(METABITMAP far *MetaBmp)
{
// garbage collection
DeleteDC(MetaBmp->hMetaMem);
return;
}