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;
 }
     
     


Reply via email to