home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / pcmagazi / 1991 / 06 / icowrite.c < prev    next >
C/C++ Source or Header  |  1991-01-08  |  4KB  |  135 lines

  1. /*=========================================================================*/
  2. /*                                                                         */
  3. /* ICOWRITE.C                                                              */
  4. /*                                                                         */
  5. /* Responsible for writing the icon out to an external ICO file.           */
  6. /*                                                                         */
  7. /* (C) Copyright 1990, 1991  Marc Adler/Magma Systems  All Rights Reserved */
  8. /*                                                                         */
  9. /*=========================================================================*/
  10.  
  11. #include <stdio.h>
  12. #include <ctype.h>
  13. #include <memory.h>
  14. #include <dos.h>
  15. #include <fcntl.h>
  16. #include <io.h>
  17. #include <sys\types.h>
  18. #include <sys\stat.h>
  19. #include <string.h>
  20. #include <windows.h>
  21. #include "ico.h"
  22.  
  23.  
  24. int ICOWrite(pszFile, hBits)
  25.   char *pszFile;
  26.   HANDLE hBits;
  27. {
  28.   int    fd;
  29.   int    i;
  30.   char   pFilename[65];
  31.   PSTR   pszZeros;
  32.   PSTR   pANDMask;
  33.   int    nTotalBytesPerLine;
  34.   LPSTR  lpBits;
  35.   LPBITMAPINFO lpbmi;
  36.   extern BYTE rgb[16][3];
  37.  
  38.  
  39.   /*
  40.     Open the file for writing. Make sure it has an ICO extension.
  41.   */
  42.   strcpy(pFilename, pszFile);
  43.   if (strchr(pFilename, '.') == NULL)
  44.     strcat(pFilename, ".ico");
  45.   if ((fd = open(pFilename, O_WRONLY | O_BINARY | O_TRUNC | O_CREAT,
  46.                             S_IREAD | S_IWRITE)) < 0)
  47.   {
  48.     MessageBox(hWndMain, "Couldn't open file", NULL, MB_OK);
  49.     return FALSE;
  50.   }
  51.  
  52.  
  53.   /*
  54.     Fill the icon file with 766 bytes of zeros
  55.   */
  56.   pszZeros = (PSTR) LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, 766);
  57.   write(fd, pszZeros, 766);
  58.   LocalFree((HANDLE) pszZeros);
  59.   lseek(fd, 0L, 0);
  60.  
  61.   /*
  62.     Write out the icon file header and directory entry. Then write
  63.     the bitmap header and color information.
  64.   */
  65.   write(fd, (char *) &IconHeader, sizeof(IconHeader));
  66.   write(fd, (char *) &IconDir, sizeof(IconDir));
  67.   lpbmi = (LPBITMAPINFO) GlobalLock(IconInfo.hBitmapInfo);
  68.   lpbmi->bmiHeader.biHeight = IconDir.Height * 2;
  69.   _lwrite(fd, (LPSTR) lpbmi, sizeof(BITMAPINFOHEADER) + 16*sizeof(RGBQUAD));
  70.   GlobalUnlock(IconInfo.hBitmapInfo);
  71.  
  72.  
  73.   /*
  74.     Write the AND mask.
  75.   */
  76.   pANDMask = (PSTR) LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT,
  77.                                         IconDir.Width*IconDir.Height/8);
  78.   if (pANDMask == NULL)
  79.   {
  80.     MessageBox(hWndMain, "Can't allocate AND mask buffer", NULL, MB_OK);
  81.     return FALSE;
  82.   }
  83.   lseek(fd, (long)
  84.         IconDir.icoDIBOffset+IconDir.icoDIBSize-(IconDir.Width*IconDir.Height/8),
  85.         0);
  86.   write(fd, pANDMask, IconDir.Width*IconDir.Height/8);
  87.   /*
  88.     Free the AND mask buffer
  89.   */
  90.   LocalFree((HANDLE) pANDMask);
  91.  
  92.  
  93.   /*
  94.     Figure out the number of bytes per line
  95.   */
  96.   switch (IconDir.ColorCount)
  97.   {
  98.     case 2 : /* 1 byte = 8 pixels */
  99.       nTotalBytesPerLine = IconDir.Width / 8;
  100.       break;
  101.     case 8 : /* 1 byte = 2 pixels??? */
  102.       nTotalBytesPerLine = IconDir.Width / 2;
  103.       break;
  104.     case 16 : /* 1 byte = 2 pixels */
  105.       nTotalBytesPerLine = IconDir.Width / 2;
  106.       break;
  107.   }
  108.  
  109.   /*
  110.     Write out the image
  111.   */
  112.   lseek(fd, (long)
  113.         IconDir.icoDIBOffset + IconDir.icoDIBSize -
  114.         (IconDir.Width * IconDir.Height / 8) -
  115.         (nTotalBytesPerLine * IconDir.Height),
  116.         0);
  117.   if ((lpBits = GlobalLock(hBits)) == NULL)
  118.   {
  119.     MessageBox(hWndMain, "Can't lock the bit buffer", NULL, MB_OK);
  120.   }
  121.   else
  122.   {
  123.     _lwrite(fd, lpBits, (int) (nTotalBytesPerLine * IconDir.Height));
  124.     GlobalUnlock(hBits);
  125.   }
  126.  
  127.  
  128.   /*
  129.     Close the file and clear the "dirty" bit.
  130.   */
  131.   close(fd);
  132.   IconInfo.fFlags &= ~STATE_DIRTY;
  133.   return TRUE;
  134. }
  135.