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/e…
==============================================================================
--- 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/window…
==============================================================================
--- 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;
}