home *** CD-ROM | disk | FTP | other *** search
/ World of Shareware - Software Farm 2 / wosw_2.zip / wosw_2 / CPROG / WBITMAP.ZIP / ICNFILE.C < prev    next >
C/C++ Source or Header  |  1991-10-15  |  7KB  |  273 lines

  1. /*
  2. **    $id: ssvcid icnfile.c 1.0 10/15/91  9:49 am$
  3. **        This file contains the code needed to read in a Windows icon file
  4. **    and generate a valid icon from it.
  5. */
  6. #include    <windows.h>
  7. #include    <malloc.h>
  8. #include    <memory.h>
  9. #include    "bitmaps.h"
  10. #include    "icnfile.h"
  11.  
  12. /*
  13. **    Global variables - used for InfoDisplay()
  14. */
  15. ICONDATA            CurIcon;
  16. ICONFILEHEADER    CurIconFile;
  17.  
  18. /*
  19. ** HICON                                            handle of created icon
  20. ** ReadIconFile(const char *filename);    name of file to load
  21. **
  22. **    This function will read the passed file in, and create a icon
  23. **    whose handle will be returned to the caller.
  24. **
  25. ** Modification History:
  26. ** 09/06/91  LCW  Created
  27. */
  28. HICON
  29. ReadIconFile(const char *filename)
  30. {
  31.     int                file;
  32.     int                i, j;
  33.     int                offset;
  34.     int                rc;
  35.     HICON                hicon = (HICON)NULL;
  36.     HDC                hdc;
  37.     int                iconx, icony, ncolors;
  38.     OFSTRUCT            reopen;
  39.     ICONFILEHEADER    header;
  40.     ICONDATA            icon, best;
  41.     char                *buffer;
  42.     BITMAPINFO        *bmi;
  43.     char                *cp, *cp2;
  44.     char                mask[512];
  45.     char                *iconDIB;
  46.  
  47.     /*
  48.     **    Get some system values
  49.     */
  50.     hdc = GetDC(MainWindow);
  51.     if (hdc == (HDC)NULL)
  52.     {
  53.         ErrorBox("ReadIconFile(): Unable to get a device context");
  54.         return (HICON)NULL;
  55.     }
  56.     iconx = GetSystemMetrics(SM_CXICON);
  57.     icony = GetSystemMetrics(SM_CYICON);
  58.     ncolors = GetDeviceCaps(hdc, NUMCOLORS);
  59.     ReleaseDC(MainWindow, hdc);
  60.  
  61.     /*
  62.     **    Allocate some needed buffers
  63.     */
  64.     buffer = malloc(4712);
  65.     if (buffer == NULL)
  66.     {
  67.         ErrorBox("ReadIconFile(): Unable to allocate memory for icon buffer");
  68.         return (HICON)NULL;
  69.     }
  70.     bmi = (BITMAPINFO *)buffer;
  71.     iconDIB = malloc(4096);
  72.     if (iconDIB == NULL)
  73.     {
  74.         ErrorBox("ReadIconFile(): Unable to allocate memory for icon DIB");
  75.         free(buffer);
  76.         return (HICON)NULL;
  77.     }
  78.  
  79.     file = OpenFile((LPSTR)filename, (LPOFSTRUCT)&reopen, OF_READ | OF_SHARE_DENY_NONE);
  80.  
  81.     if (file >= 0)
  82.     {
  83.         /*
  84.         ** Read in Icon File header
  85.         */
  86.         rc = _lread(file, (char far *)&header, sizeof(header));
  87.         if (rc == sizeof(header) && header.icoReserved == 0
  88.             && header.icoResourceType == 1)
  89.         {
  90.             if (header.icoResourceCount != 0)
  91.             {
  92.                 /*
  93.                 ** Look for the correct Icon by scanning through the directory for
  94.                 ** an extact match.
  95.                 */
  96.                 memset(&best, 0, sizeof(best));
  97.  
  98.                 for (i = rc = 0 ; rc >= 0 && i < header.icoResourceCount ; ++i)
  99.                 {
  100.                     rc = _lread(file, (char far *)&icon, sizeof(ICONDATA));
  101.                     if (rc == sizeof(ICONDATA))
  102.                     {
  103.                         if (icon.width == iconx && icon.height == icony)
  104.                         {
  105.                             if (icon.colorCount == ncolors)
  106.                             {
  107.                                 best = icon;
  108.                                 break;
  109.                             }
  110.                             else if (icon.colorCount > best.colorCount)
  111.                             {
  112.                                 if (icon.colorCount < ncolors)
  113.                                     best = icon;
  114.                             }
  115.                             else
  116.                             {
  117.                                 if (icon.colorCount > ncolors)
  118.                                     best = icon;
  119.                             }
  120.                         }
  121.                     }
  122.                     else
  123.                     {
  124.                         ErrorBox("ReadIconFile(): Error reading icon directory");
  125.                         rc = -1;
  126.                     }
  127.                 }
  128.  
  129.                 if (rc >= 0)
  130.                 {
  131.                     if (best.width != 0)
  132.                     {
  133.                         _llseek(file, best.icoDIBOffset, 0);
  134.                         rc = _lread(file, (LPSTR)buffer, (int)best.icoDIBSize);
  135.                         if (rc == (int)best.icoDIBSize)
  136.                         {
  137.                             offset = sizeof(BITMAPINFO) + sizeof(RGBQUAD) * (best.colorCount - 1);
  138.                             bmi->bmiHeader.biSizeImage -= best.width * best.height / 8;
  139.  
  140.                             if (bmi->bmiHeader.biBitCount == 1)
  141.                             {
  142.                                 /*
  143.                                 ** Invert Icon image - only if monochrome
  144.                                 **        rc  == line width in bytes
  145.                                 **        cp  == pointer to DIB from file
  146.                                 **        cp2 == pointer to proper line in iconDIB
  147.                                 */
  148.                                 rc = best.width / 8 * bmi->bmiHeader.biPlanes
  149.                                     * bmi->bmiHeader.biBitCount;
  150.                                 cp = buffer + offset;
  151.                                 cp2 = iconDIB + (best.height - 1) * rc;
  152.  
  153.                                 for (j = 0 ; j < best.height ; ++j)
  154.                                 {
  155.                                     memcpy(cp2, cp, rc);
  156.                                     cp += rc;
  157.                                     cp2 -= rc;
  158.                                 }
  159.                             }
  160.  
  161.                             /*
  162.                             ** Invert Icon mask
  163.                             **        rc  == line width in bytes
  164.                             **        cp  == pointer to mask DIB from file
  165.                             **        cp2 == pointer to proper line in mask
  166.                             */
  167.                             rc = best.width / 8;
  168.                             cp = buffer + offset + (int)bmi->bmiHeader.biSizeImage;
  169.                             cp2 = mask + (best.height - 1) * rc;
  170.  
  171.                             for (j = 0 ; j < best.height ; ++j)
  172.                             {
  173.                                 memcpy(cp2, cp, rc);
  174.                                 cp += rc;
  175.                                 cp2 -= rc;
  176.                             }
  177.  
  178.                             if (bmi->bmiHeader.biBitCount > 1)
  179.                             {
  180.                                 HBITMAP    hbm;
  181.                                 BITMAP    bm;
  182.  
  183.                                 /*
  184.                                 **    Create the DIB portion of the bitmap
  185.                                 */
  186.                                 bmi->bmiHeader.biHeight = best.height;
  187.                                 bmi->bmiHeader.biWidth = best.width;
  188.  
  189.                                 hbm = CreateDIBitmap(hdc, (BITMAPINFOHEADER FAR *)bmi,
  190.                                     CBM_INIT, (LPSTR)buffer + offset,
  191.                                     (BITMAPINFO FAR *)bmi, DIB_RGB_COLORS);
  192.  
  193.                                 if (hbm != (HBITMAP)NULL)
  194.                                 {
  195.                                     if (GetObject(hbm, sizeof(bm), (LPSTR)&bm)
  196.                                         == sizeof(bm))
  197.                                     {
  198.                                         rc = bm.bmWidthBytes * bm.bmPlanes * bm.bmHeight;
  199.                                         if (GetBitmapBits(hbm, rc, (LPSTR)iconDIB) == rc)
  200.                                         {
  201.                                             bmi->bmiHeader.biPlanes = bm.bmPlanes;
  202.                                             bmi->bmiHeader.biBitCount = bm.bmBitsPixel;
  203.                                         }
  204.                                         else
  205.                                         {
  206.                                             ErrorBox("ReadIconFile(): Error getting bitmap bits");
  207.                                         }
  208.                                     }
  209.                                     else
  210.                                     {
  211.                                         ErrorBox("ReadIconFile(): Error getting bitmap data");
  212.                                     }
  213.                                     DeleteObject(hbm);
  214.                                 }
  215.                                 else
  216.                                 {
  217.                                     ErrorBox("ReadIconFile(): Error creating bitmap");
  218.                                 }
  219.                             }
  220.  
  221.                             /*
  222.                             **    Now to create the icon
  223.                             */
  224.                             hicon = CreateIcon(AppInstance, best.width, best.height,
  225.                                 bmi->bmiHeader.biPlanes, bmi->bmiHeader.biBitCount,
  226.                                 (LPSTR)mask, (LPSTR)iconDIB);
  227.  
  228.                             if (hicon != (HICON)NULL)
  229.                             {
  230.                                 CurIcon = best;
  231.                                 CurIconFile = header;
  232.                             }
  233.                         }
  234.                         else
  235.                         {
  236.                             ErrorBox("ReadIconFile(): Error reading icon data");
  237.                         }
  238.                     }
  239.                 }
  240.             }
  241.             else
  242.             {
  243.                 ErrorBox("ReadIconFile(): Error Icon Count is 0");
  244.             }
  245.         }
  246.         else
  247.         {
  248.             ErrorBox("ReadIconFile(): Error Reading Icon Header");
  249.         }
  250.         _lclose(file);
  251.     }
  252.     else
  253.     {
  254.         ErrorBox("ReadIconFile(): Error Opening Icon File");
  255.     }
  256.  
  257.     /*
  258.     **    Free up allocated memory
  259.     */
  260.     free(buffer);
  261.     free(iconDIB);
  262.  
  263.     return hicon;
  264. }
  265.  
  266. /*
  267. **    Modification History
  268. **    --------------------
  269. **    $lgb$
  270. ** 10/15/91     Larry Widing   Initial version for Win Tech Journal Article.
  271. **    $lge$
  272. */
  273.