Ignore:
Timestamp:
Nov 24, 2000, 2:19:12 PM (25 years ago)
Author:
sandervl
Message:

KS: Extract icon + icon lookup fixes + changes

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/shell32/iconcache.c

    r4607 r4691  
    1 /* $Id: iconcache.c,v 1.2 2000-11-17 09:57:35 sandervl Exp $ */
     1/* $Id: iconcache.c,v 1.3 2000-11-24 13:19:12 sandervl Exp $ */
    22/*
    33 *      shell icon cache (SIC)
     
    219219}
    220220
     221#ifdef __WIN32OS2__
     222
     223/*************************************************************************/
     224
     225typedef struct
     226{
     227        INT             nStartIndex;
     228        UINT    nIcons;
     229        UINT    cx;
     230        UINT    cy;
     231        UINT    nCurrIndex;
     232        HICON * phIcons;
     233        UINT    nRetrieved;
     234
     235} GETICONSPROCPARAM;
     236
     237static BOOL CALLBACK GetIconsProc( HANDLE  hModule,
     238                                                                   LPCTSTR lpszType,
     239                                                                   LPTSTR  lpszName,
     240                                                                   LONG    lParam )
     241{
     242        GETICONSPROCPARAM* pIcons = (GETICONSPROCPARAM *)lParam;
     243
     244        if ( ( pIcons->nStartIndex == -1 ) && !pIcons->phIcons && !pIcons->nIcons )
     245        {
     246                /* number of icons ( RT_GROUP_ICON resources ) requested. */
     247                pIcons->nRetrieved++;
     248        }
     249        else if ( pIcons->nStartIndex < 0 )
     250        {
     251                /* begins by extracting the icon whose resource identifier
     252                   is equal to  the absolute value of nStartIndex. */
     253
     254                INT iResId = abs( pIcons->nStartIndex );
     255                if ( lpszName < 0x10000 )
     256                {
     257                        if ( (INT)lpszName == iResId )
     258                        {
     259                                /* Found icondir with resid iResId. */
     260                                /* This is the starting index.      */
     261                                pIcons->nStartIndex = pIcons->nCurrIndex;                       
     262                        }                                               
     263                }
     264                else
     265                {
     266                        char buffer[ 8 ];
     267                        sprintf( buffer, "#%u", iResId );               
     268                        if ( strcmp( lpszName, buffer ) == 0 )
     269                        {
     270                                /* Found icondir with resid iResId. */
     271                                /* This is the starting index.      */
     272                                pIcons->nStartIndex = pIcons->nCurrIndex;                       
     273                        }                                               
     274                }
     275        }
     276       
     277        if ( pIcons->nStartIndex >= 0 )
     278        {
     279                /* extract icons by index */   
     280       
     281                if ( pIcons->nCurrIndex >= pIcons->nStartIndex )
     282                {
     283                        HICON hIcon     = LoadImageA( hModule,
     284                                                                          lpszName,
     285                                                                          IMAGE_ICON,
     286                                                                          pIcons->cx,
     287                                                                          pIcons->cy,
     288                                                                          LR_DEFAULTCOLOR );
     289                        *pIcons->phIcons = hIcon;
     290                        if ( hIcon )
     291                                pIcons->nRetrieved++;
     292                               
     293                        pIcons->phIcons++;
     294                }
     295               
     296                if ( pIcons->nCurrIndex
     297                                                == ( pIcons->nStartIndex + pIcons->nIcons - 1 ) )
     298                {
     299                        /* done, stop enumeration */
     300                        return FALSE;
     301                }
     302        }
     303       
     304        /* continue enumeration */
     305        pIcons->nCurrIndex++;
     306        return TRUE;
     307}
     308
     309/*************************************************************************
     310 *
     311 * returns
     312 *      failure: 0
     313 *      success: nr of icons in file, if nIconIndex is -1,
     314 *                       nr of icons successfully extracted, otherwise.
     315 */
     316UINT WINAPI ICO_ExtractIconEx( LPCSTR lpszExeFileName,
     317                                                           HICON * RetPtr,
     318                                                           INT nIconIndex,
     319                                                           UINT n,
     320                                                           UINT cxDesired,
     321                                                           UINT cyDesired )
     322{
     323        UINT nIconCount = 0;
     324        HINSTANCE hInst = 0;
     325
     326        TRACE( "file=%s, index=%d, n=%u\n", lpszExeFileName, nIconIndex, n );
     327
     328#if 0
     329        if ( stricmp( lpszExeFileName, "shell32.dll" ) == 0 )
     330        {
     331                /* Use original renamed dll, if present. It contains all icons. ;-) */
     332                hInst = LoadLibraryExA( "shell32_pe.dll", 0, LOAD_LIBRARY_AS_DATAFILE );
     333        }
     334               
     335        if ( !hInst )
     336#endif 
     337                hInst = LoadLibraryExA( lpszExeFileName, 0, LOAD_LIBRARY_AS_DATAFILE );
     338
     339        if ( hInst )
     340        {
     341                GETICONSPROCPARAM icons = {
     342                                nIconIndex,     n, cxDesired, cyDesired, 0, RetPtr, 0 };
     343               
     344                EnumResourceNamesA(
     345                        hInst, RT_GROUP_ICONA, &GetIconsProc, (LONG)&icons );
     346                       
     347                nIconCount = icons.nRetrieved;
     348
     349                FreeLibrary( hInst );
     350        }
     351        else
     352        {
     353                HFILE           hFile;
     354                OFSTRUCT        ofs;
     355                DWORD           sig;
     356                LPBYTE          pData;
     357                UINT16          iconDirCount = 0,iconCount = 0;
     358                ULONG           uSize;
     359
     360                if( nIconIndex!=-1 && !n )
     361                        return 0;
     362
     363                hFile = OpenFile( lpszExeFileName, &ofs, OF_READ );
     364                                       
     365                if( hFile == HFILE_ERROR )
     366                        return 0;
     367
     368                sig = SHELL_GetResourceTable(hFile,&pData);
     369
     370                if( sig==IMAGE_OS2_SIGNATURE || sig==1 ) /* .ICO file */
     371                {
     372                        /* NE image ( OS/2 1.x / Win 3.x ) / ico file */
     373       
     374                        BYTE                    *pCIDir = 0;
     375                        NE_TYPEINFO             *pTInfo = (NE_TYPEINFO*)(pData + 2);
     376                        NE_NAMEINFO             *pIconStorage = NULL;
     377                        NE_NAMEINFO             *pIconDir = NULL;
     378                        LPicoICONDIR    lpiID = NULL;
     379
     380                        TRACE("-- OS2/icon Signature (0x%08lx)\n", sig);
     381
     382                        if( pData == (BYTE*)-1 )
     383                        {
     384                                pCIDir = ICO_GetIconDirectory(hFile, &lpiID, &uSize);   /* check for .ICO file */
     385                        if( pCIDir )
     386                        {
     387                                iconDirCount = 1; iconCount = lpiID->idCount;
     388                                TRACE("-- icon found %p 0x%08lx 0x%08x 0x%08x\n", pCIDir, uSize, iconDirCount, iconCount);
     389                        }
     390                        }
     391                        else while( pTInfo->type_id && !(pIconStorage && pIconDir) )
     392                        {
     393                                if( pTInfo->type_id == NE_RSCTYPE_GROUP_ICON )  /* find icon directory and icon repository */
     394                        {
     395                                iconDirCount = pTInfo->count;
     396                                pIconDir = ((NE_NAMEINFO*)(pTInfo + 1));
     397                                TRACE("\tfound directory - %i icon families\n", iconDirCount);
     398                        }
     399                        if( pTInfo->type_id == NE_RSCTYPE_ICON )
     400                        {
     401                                iconCount = pTInfo->count;
     402                                pIconStorage = ((NE_NAMEINFO*)(pTInfo + 1));
     403                                TRACE("\ttotal icons - %i\n", iconCount);
     404                        }
     405                        pTInfo = (NE_TYPEINFO *)((char*)(pTInfo+1)+pTInfo->count*sizeof(NE_NAMEINFO));
     406                        }
     407
     408                        if( (pIconStorage && pIconDir) || lpiID )         /* load resources and create icons */
     409                        {
     410                                if( nIconIndex == (UINT16)-1 )
     411                        {
     412                                        /* icon count requested */
     413                                nIconCount = iconDirCount;
     414                        }
     415                        else if( nIconIndex < iconDirCount )
     416                        {
     417                                UINT16   i, icon;
     418                                if( n > iconDirCount - nIconIndex )
     419                                        n = iconDirCount - nIconIndex;
     420
     421                                for( i = nIconIndex; i < nIconIndex + n; i++ )
     422                                {
     423                                        /* .ICO files have only one icon directory */
     424
     425                                        if( lpiID == NULL )     /* *.ico */
     426                                                pCIDir = SHELL_LoadResource( hFile, pIconDir + i, *(WORD*)pData, &uSize );
     427                                               
     428                                        RetPtr[i-nIconIndex] = pLookupIconIdFromDirectoryEx( pCIDir, TRUE,  GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), 0);
     429                                       
     430                                        if ( RetPtr[i-nIconIndex] )
     431                                                nIconCount++;
     432                                               
     433                                        HeapFree(GetProcessHeap(), 0, pCIDir);
     434                                }
     435
     436                                for( icon = nIconIndex; icon < nIconIndex + n; icon++ )
     437                                {
     438                                        pCIDir = NULL;
     439                                        if( lpiID )
     440                                                pCIDir = ICO_LoadIcon( hFile, lpiID->idEntries + RetPtr[icon-nIconIndex], &uSize);
     441                                        else
     442                                        {
     443                                                for( i = 0; i < iconCount; i++ )
     444                                                {
     445                                                        if( pIconStorage[i].id == (RetPtr[icon-nIconIndex] | 0x8000) )
     446                                                        pCIDir = SHELL_LoadResource( hFile, pIconStorage + i,*(WORD*)pData, &uSize );
     447                                                }
     448                                        }
     449                                        if( pCIDir )
     450                                        {
     451                                                RetPtr[icon-nIconIndex] = (HICON) pCreateIconFromResourceEx(pCIDir,uSize,TRUE,0x00030000, cxDesired, cyDesired, LR_DEFAULTCOLOR);
     452                                                if ( RetPtr[icon-nIconIndex] )
     453                                                        nIconCount++;
     454                                        }
     455                                        else
     456                                                RetPtr[icon-nIconIndex] = 0;
     457                                }
     458                        }
     459                        }
     460                        if( lpiID )
     461                        HeapFree( GetProcessHeap(), 0, lpiID);
     462                        else
     463                        HeapFree( GetProcessHeap(), 0, pData);
     464                }
     465                _lclose( hFile);
     466        }
     467        return nIconCount;
     468}
     469
     470#else /* ! __WIN32OS2__ */
     471
    221472/*************************************************************************
    222473 *
     
    469720          goto end_3;           /* sucess */
    470721        }
    471 #ifdef __WIN32OS2__
    472         else
    473     {
    474         if( nIconIndex == -1 )
    475             {
    476                 TRACE( "ICO_ExtractIconEx : iconcount not implemented!\n" );
    477             }
    478         else
    479         {
    480             /* Try to get icon(s) using LoadImageA. This works for
    481                LX images, like Odin's shell32.dll! */
    482             HINSTANCE hInst = LoadLibraryA( lpszExeFileName );
    483             if ( hInst )
    484             {
    485                 INT icon;
    486                     for( icon = nIconIndex; icon < nIconIndex + n; icon++ )
    487                     {
    488                         RetPtr[ icon - nIconIndex ]
    489                             = LoadImageA( hInst,
    490                                       MAKEINTRESOURCEA( icon ),
    491                                           IMAGE_ICON,
    492                                           cxDesired,
    493                                           cyDesired,
    494                                           LR_DEFAULTCOLOR );
    495                     }
    496                 hRet = RetPtr[ 0 ];
    497                 FreeLibrary( hInst );   
    498             }
    499         }
    500     }
    501 #endif
    502722        goto end_1;             /* unknown filetype */
    503723
     
    508728        return hRet;
    509729}
     730
     731#endif /* ! __WIN32OS2__ */
    510732
    511733/********************** THE ICON CACHE ********************************/
     
    696918        pImageList_SetBkColor(ShellBigIconList, GetSysColor(COLOR_WINDOW));
    697919
    698         for (index=1; index<39; index++)
     920        for (index=1; index<46; index++)
    699921        {
    700922          hSm = LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(index), IMAGE_ICON, 16, 16,LR_SHARED);
     
    8551077}
    8561078
     1079#ifdef __WIN32OS2__
     1080
     1081/*************************************************************************
     1082 * ExtractIconEx                        [shell32.189]
     1083 */
     1084UINT WINAPI ExtractIconExAW ( LPCVOID lpszFile, INT nIconIndex, HICON * phiconLarge, HICON * phiconSmall, UINT nIcons )
     1085{       if (SHELL_OsIsUnicode())
     1086          return ExtractIconExW ( lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
     1087        return ExtractIconExA ( lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
     1088}
     1089/*************************************************************************
     1090 * ExtractIconExA                       [shell32.190]
     1091 *
     1092 * PARAMETERS
     1093 *      lpszFile [in]           Pointer to a null-terminated string specifying the name
     1094 *                                              of an executable file, DLL, or icon file from which
     1095 *                                              icons will be extracted.
     1096 *
     1097 *      nIconIndex [in]         Specifies the zero-based index of the first icon to
     1098 *                                              extract. For example, if this value is zero, the
     1099 *                                              function extracts the first icon in the specified file.
     1100 *
     1101 *                                              If this value is -1 and phIconLarge and phiconSmall are
     1102 *                                              both NULL, the function returns the total number of
     1103 *                                              icons in the specified file. If the file is an
     1104 *                                              executable file or DLL, the return value is the number
     1105 *                                              of RT_GROUP_ICON resources. If the file is an .ico file,
     1106 *                                              the return value is 1.
     1107 *
     1108 *                                              Windows 95/98, Windows NT 4.0, and Windows 2000:
     1109 *                                              If this value is a negative number and either
     1110 *                                              phIconLarge     or phiconSmall is not NULL, the function
     1111 *                                              begins by extracting the icon whose resource identifier
     1112 *                                              is equal to     the absolute value of nIconIndex. For
     1113 *                                              example, use -3 to extract the icon whose resource
     1114 *                                              identifier is 3.
     1115 *
     1116 *      phiconLarge [out]       Pointer to an array of icon handles that receives
     1117 *                                              handles to the large icons extracted from the file.
     1118 *                                              If this parameter is NULL, no large icons are extracted
     1119 *                                              from the file.
     1120 *
     1121 *      phiconSmall [out]       Pointer to an array of icon handles that receives
     1122 *                                              handles to the small icons extracted from the file.
     1123 *                                              If this parameter is NULL, no small icons are extracted
     1124 *                                              from the file.
     1125 *
     1126 *      nIcons [in]             Specifies the number of icons to extract from the file.
     1127 *
     1128 * RETURNS
     1129 *      If the nIconIndex parameter is -1, the phiconLarge parameter is NULL, and
     1130 *      the phiconSmall parameter is NULL, then the return value is the number of
     1131 *      icons contained in the specified file. Otherwise, the return value is the
     1132 *      number of icons successfully extracted from the file.
     1133 */
     1134UINT WINAPI ExtractIconExA ( LPCSTR lpszFile, INT nIconIndex, HICON * phiconLarge, HICON * phiconSmall, UINT nIcons )
     1135{       UINT ret=0;
     1136
     1137        TRACE("file=%s idx=%i %p %p num=%i\n", lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons );
     1138
     1139        if ( ( nIconIndex == -1 ) && !phiconLarge && !phiconSmall )     /* Number of icons requested */
     1140          return ICO_ExtractIconEx(lpszFile, NULL, -1, 0, 0, 0  );
     1141
     1142        /* KSO: What, if phiconLarge and phiconSmall are given, and first call
     1143                        to ICO_ExtractIconEx returns a value other than the second one?
     1144         */
     1145        if (phiconLarge)
     1146          ret = ICO_ExtractIconEx(lpszFile, phiconLarge, nIconIndex, nIcons, 32, 32  );
     1147
     1148        if (phiconSmall)
     1149          ret = ICO_ExtractIconEx(lpszFile, phiconSmall, nIconIndex, nIcons, 16, 16  );
     1150
     1151        return ret;
     1152}
     1153/*************************************************************************
     1154 * ExtractIconExW                       [shell32.191]
     1155 */
     1156UINT WINAPI ExtractIconExW ( LPCWSTR lpszFile, INT nIconIndex, HICON * phiconLarge, HICON * phiconSmall, UINT nIcons )
     1157{       LPSTR sFile;
     1158        UINT ret;
     1159
     1160        TRACE("file=%s idx=%i %p %p num=%i\n", debugstr_w(lpszFile), nIconIndex, phiconLarge, phiconSmall, nIcons );
     1161
     1162        sFile = HEAP_strdupWtoA (GetProcessHeap(),0,lpszFile);
     1163        ret = ExtractIconExA ( sFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
     1164        HeapFree(GetProcessHeap(),0,sFile);
     1165        return ret;
     1166}
     1167
     1168#else /* ! __WIN32OS2__ */
     1169
    8571170/*************************************************************************
    8581171 * ExtractIconEx                        [shell32.189]
     
    9131226        return ret;
    9141227}
     1228
     1229#endif /* ! __WIN32OS2__ */
     1230
Note: See TracChangeset for help on using the changeset viewer.