home *** CD-ROM | disk | FTP | other *** search
- /**************************************************************************
- * *
- * 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;
- }
-