Save Icons
От: NikitaP  
Дата: 24.12.01 23:25
Оценка:
Здраствуйте.

Развлекаю себя написанием специфического редактора ресурсов.
И вот появилась проблема сохранения ресурса иконки ( имя_файла.ico ),
причем без использования библиотеки GDI+.
Буду благодарен за любой совет, предложение, ссылку...

Заранее спасибо.
Re: Save Icons
От: Alex Fedotov США  
Дата: 25.12.01 07:18
Оценка: 83 (7)
Здравствуйте NikitaP, Вы писали:

NP>Развлекаю себя написанием специфического редактора ресурсов.

NP>И вот появилась проблема сохранения ресурса иконки ( имя_файла.ico ),
NP>причем без использования библиотеки GDI+.

// resources are WORD-aligned
#pragma pack(push, 2)

typedef struct _ICONDIRENTRY {
    BYTE            bWidth;
    BYTE            bHeight;
    BYTE            bColorCount;
    BYTE            bReserved;
    WORD            wPlanes;
    WORD            wBitCount;
    DWORD           dwBytesInRes;
    DWORD           dwImageOffset;
} ICONDIRENTRY, * PICONDIRENTRY;

typedef struct _ICONDIR {
    WORD            idReserved;
    WORD            idType;
    WORD            idCount;
    ICONDIRENTRY    idEntries[1];
} ICONDIR, * PICONDIR;

typedef struct _GRPICONDIRENTRY {
    BYTE            bWidth;
    BYTE            bHeight;
    BYTE            bColorCount;
    BYTE            bReserved;
    WORD            wPlanes;
    WORD            wBitCount;
    DWORD           dwBytesInRes;
    WORD            nID;
} GRPICONDIRENTRY, * PGRPICONDIRENTRY;

typedef struct _GRPICONDIR {
    WORD            idReserved;
    WORD            idType;
    WORD            idCount;
    GRPICONDIRENTRY idEntries[1];
} GRPICONDIR, * PGRPICONDIR;

#pragma pack(pop)

//---------------------------------------------------------------------------
// ExtractIconAsFile
//
//  Extracts the specified icon resource as an .ico file.
//
//  Parameters:
//      hModule     - handle of the module containing the resource to extract
//      pszIconId   - icon resource identifier
//      wLangId     - resource language identifier
//      pszFileName - name of the file where to save the extracted icon
//
//  Returns:
//      TRUE, if successful, FALSE - otherwise.
//
BOOL
APIENTRY
ExtractIconAsFile(
    IN HINSTANCE hModule,
    IN PCTSTR pszIconId,
    IN WORD wLangId,
    IN PCTSTR pszFileName
    )
{
    _ASSERTE(pszIconId != NULL);
    _ASSERTE(pszFileName != NULL);

    HRSRC hRsrc;
    HGLOBAL hGlb;
    PGRPICONDIR pGrpIconDir;

    DWORD cbHeader, cbIcon;
    PICONDIR pIconDir = NULL;
    PBYTE pIcon = NULL;

    HANDLE hFile = INVALID_HANDLE_VALUE;

    BOOL bOk = FALSE;
    DWORD dwError = ERROR_SUCCESS;

    __try
    {
        // find the specified icon resource
        hRsrc = FindResourceEx(hModule, RT_GROUP_ICON, pszIconId, wLangId);
        if (hRsrc == NULL)
        {
            dwError = GetLastError();
            __leave;
        }

        hGlb = LoadResource(hModule, hRsrc);
        _ASSERTE(hGlb != NULL);

        pGrpIconDir = (PGRPICONDIR)LockResource(hGlb);
        _ASSERTE(pGrpIconDir != NULL);

        // calculate size of the .ico file
        cbHeader = sizeof(ICONDIR) + 
                   sizeof(ICONDIRENTRY) * pGrpIconDir->idCount;

        cbIcon = cbHeader;
        for (UINT i = 0; i < pGrpIconDir->idCount; i++)
            cbIcon += pGrpIconDir->idEntries[i].dwBytesInRes;

        // allocate memory block for the icon
        pIcon = (PBYTE)LocalAlloc(LMEM_FIXED, cbIcon);
        if (pIcon == NULL)
        {
            dwError = ERROR_NOT_ENOUGH_MEMORY;
            __leave;
        }

        pIconDir = (PICONDIR)pIcon;
        pIcon += cbHeader;

        // copy the header
        pIconDir->idReserved = pGrpIconDir->idReserved;
        pIconDir->idType = pGrpIconDir->idType;
        pIconDir->idCount = pGrpIconDir->idCount;

        // copy images
        for (i = 0; i < pGrpIconDir->idCount; i++)
        {
            PGRPICONDIRENTRY pGrpEntry = pGrpIconDir->idEntries + i;
            PICONDIRENTRY pEntry = pIconDir->idEntries + i;

            pEntry->bWidth = pGrpEntry->bWidth;
            pEntry->bHeight = pGrpEntry->bHeight;
            pEntry->bColorCount = pGrpEntry->bColorCount;
            pEntry->bReserved = pGrpEntry->bReserved;
            pEntry->wPlanes = pGrpEntry->wPlanes;
            pEntry->wBitCount = pGrpEntry->wBitCount;
            pEntry->dwBytesInRes = pGrpEntry->dwBytesInRes;
            pEntry->dwImageOffset = pIcon - (PBYTE)pIconDir;

            hRsrc = FindResourceEx(hModule, RT_ICON,
                                   MAKEINTRESOURCE(pGrpEntry->nID), wLangId);
            if (hRsrc == NULL)
            {
                dwError = GetLastError();
                __leave;
            }

            hGlb = LoadResource(hModule, hRsrc);
            _ASSERTE(hGlb != NULL);
            
            CopyMemory(pIcon, LockResource(hGlb), pEntry->dwBytesInRes);
            pIcon += pEntry->dwBytesInRes;
        }

        // now we have complete in-memory representation of the .ico file
        // pointer to by pIconDir variable

        hFile = CreateFile(pszFileName, GENERIC_WRITE, 0, NULL, 
                           CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
        if (hFile == INVALID_HANDLE_VALUE)
        {
            dwError = GetLastError();
            __leave;
        }

        if (!WriteFile(hFile, pIconDir, cbIcon, &cbIcon, NULL))
        {
            dwError = GetLastError();
            __leave;
        }

        bOk = TRUE;
    }
    __finally
    {
        if (hFile != INVALID_HANDLE_VALUE)
            CloseHandle(hFile);
        if (pIconDir != NULL)
            LocalFree((HLOCAL)pIconDir);
    }

    SetLastError(dwError);
    return bOk;
}


Смотри также:
Icons in Win32
-- Alex Fedotov
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.