Author: khornicek Date: Thu Nov 6 23:28:28 2014 New Revision: 65303 URL: http://svn.reactos.org/svn/reactos?rev=65303&view=rev Log: [USER32] - use get_best_icon_file_entry's magic to find the correct icon in ICO_ExtractIconExW - thanks Jérôme! - add cursor files support for PrivateExtractIcon(Ex)
Modified: trunk/reactos/win32ss/user/user32/misc/exticon.c trunk/reactos/win32ss/user/user32/windows/cursoricon_new.c Modified: trunk/reactos/win32ss/user/user32/misc/exticon.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/user32/misc/exticon.c?rev=65303&r1=65302&r2=65303&view=diff ============================================================================== --- trunk/reactos/win32ss/user/user32/misc/exticon.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/user32/misc/exticon.c [iso-8859-1] Thu Nov 6 23:28:28 2014 @@ -43,6 +43,16 @@ TRACE("type = 0x%08x count = 0x%08x\n", entry->idType, entry->idCount); } #endif + +#ifndef WINE +DWORD get_best_icon_file_offset(const LPBYTE dir, + DWORD dwFileSize, + int cxDesired, + int cyDesired, + BOOL bIcon, + DWORD fuLoad, + POINT *ptHotSpot); +#endif /********************************************************************** * find_entry_by_id @@ -99,10 +109,10 @@ if (mz_header->e_magic != IMAGE_DOS_SIGNATURE) { - if (mz_header->e_cblp == 1) /* .ICO file ? */ + if (mz_header->e_cblp == 1 || mz_header->e_cblp == 2) /* .ICO or .CUR file ? */ { *retptr = (LPBYTE)-1; /* ICONHEADER.idType, must be 1 */ - return 1; + return mz_header->e_cblp; } else return 0; /* failed */ @@ -361,36 +371,58 @@ } } #else - if (sig == 1) /* .ICO file */ + if (sig == 1 || sig == 2) /* .ICO or .CUR file */ { TRACE("-- icon Signature (0x%08x)\n", sig); if (pData == (BYTE*)-1) { - INT dataOffset; - LPICONIMAGE entry; - CURSORICONDIR *lpcid = (CURSORICONDIR*)peimage; INT cx[2] = {cx1, cx2}, cy[2] = {cy1, cy2}; INT index; - if (lpcid->idType != 1) - return 0; - for(index = 0; index < 2; index++) { - dataOffset = LookupIconIdFromDirectoryEx(peimage, TRUE, cx[index], cy[index], flags); + DWORD dataOffset; + LPBYTE imageData; + POINT hotSpot; + LPICONIMAGE entry; + + dataOffset = get_best_icon_file_offset(peimage, fsizel, cx[index], cy[index], sig == 1, flags, sig == 1 ? NULL : &hotSpot); if (dataOffset) { HICON icon; - entry = (LPICONIMAGE)(peimage + dataOffset); - icon = CreateIconFromResourceEx(peimage + dataOffset, entry->icHeader.biSizeImage, TRUE, 0x00030000, cx[index], cy[index], flags); + WORD *cursorData = NULL; + + imageData = peimage + dataOffset; + entry = (LPICONIMAGE)(imageData); + + if(sig == 2) + { + /* we need to prepend the bitmap data with hot spots for CreateIconFromResourceEx */ + cursorData = HeapAlloc(GetProcessHeap(), 0, entry->icHeader.biSizeImage + 2 * sizeof(WORD)); + + if(!cursorData) + continue; + + cursorData[0] = hotSpot.x; + cursorData[1] = hotSpot.y; + + memcpy(cursorData + 2, imageData, entry->icHeader.biSizeImage); + + imageData = (LPBYTE)cursorData; + } + + icon = CreateIconFromResourceEx(imageData, entry->icHeader.biSizeImage, sig == 1, 0x00030000, cx[index], cy[index], flags); if (icon) { RetPtr[index] = icon; iconCount = 1; } + + if(cursorData != NULL) + HeapFree(GetProcessHeap(), 0, cursorData); } } Modified: trunk/reactos/win32ss/user/user32/windows/cursoricon_new.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/user32/windows/cursoricon_new.c?rev=65303&r1=65302&r2=65303&view=diff ============================================================================== --- trunk/reactos/win32ss/user/user32/windows/cursoricon_new.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/user32/windows/cursoricon_new.c [iso-8859-1] Thu Nov 6 23:28:28 2014 @@ -436,7 +436,6 @@ #include "poppack.h" -static const CURSORICONFILEDIRENTRY* get_best_icon_file_entry( _In_ const CURSORICONFILEDIR* dir, @@ -521,6 +520,33 @@ /* We found it */ return &dir->idEntries[i-1]; +} + +DWORD +get_best_icon_file_offset( + _In_ const LPBYTE dir, + _In_ DWORD dwFileSize, + _In_ int cxDesired, + _In_ int cyDesired, + _In_ BOOL bIcon, + _In_ DWORD fuLoad, + _Out_ POINT *ptHotSpot +) +{ + const CURSORICONFILEDIRENTRY *entry; + + entry = get_best_icon_file_entry((CURSORICONFILEDIR *) dir, dwFileSize, cxDesired, cyDesired, bIcon, fuLoad); + + if(ptHotSpot) + { + ptHotSpot->x = entry->xHotspot; + ptHotSpot->y = entry->yHotspot; + } + + if(entry) + return entry->dwDIBOffset; + + return 0; }