https://git.reactos.org/?p=reactos.git;a=commitdiff;h=dddceeb10d3d1afa41d7ce36cfa0494d00566c76

commit dddceeb10d3d1afa41d7ce36cfa0494d00566c76
Author:     Katayama Hirofumi MZ <katayama.hirofumi...@gmail.com>
AuthorDate: Fri Jan 31 08:21:05 2025 +0900
Commit:     GitHub <nore...@github.com>
CommitDate: Fri Jan 31 08:21:05 2025 +0900

    [SHELL32] Load shell icon size from registry (#7683)
    
    Improve usability. Re-trial of #7679 with different approach.
    JIRA issue: CORE-12905
    - Add ShellSmallIconSize, ShellLargeIconSize, and
      ShellIconBPP global variables in iconcache.cpp.
    - Add SIC_GetMetricsValue, SIC_GetLargeIconSize,
      SIC_GetSmallIconSize, and SIC_GetIconBPP helper
      functions in iconcache.cpp.
    - Load shell icon size from registry key
      "HKEY_CURRENT_USER\\Control Panel\\Desktop\\WindowMetrics".
    - Load icon BPP (bits per pixel) from registry.
    - Fix SIC_Initialize and SIC_LoadIcon functions for icon size.
    - Fix SHGetFileInfoW function for SHGFI_SHELLICONSIZE flag.
---
 dll/win32/shell32/iconcache.cpp       | 124 ++++++++++++++++++----------------
 dll/win32/shell32/wine/shell32_main.c |  37 ++++++----
 dll/win32/shell32/wine/shell32_main.h |   3 +
 3 files changed, 93 insertions(+), 71 deletions(-)

diff --git a/dll/win32/shell32/iconcache.cpp b/dll/win32/shell32/iconcache.cpp
index 9fb41f9389c..392d5fa75ea 100644
--- a/dll/win32/shell32/iconcache.cpp
+++ b/dll/win32/shell32/iconcache.cpp
@@ -1,21 +1,9 @@
 /*
- *    shell icon cache (SIC)
- *
- * Copyright 1998, 1999 Juergen Schmied
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ * PROJECT:     ReactOS shell32
+ * LICENSE:     LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
+ * PURPOSE:     Shell Icon Cache (SIC)
+ * COPYRIGHT:   Copyright 1998, 1999 Juergen Schmied
+ *              Copyright 2025 Katayama Hirofumi MZ 
(katayama.hirofumi...@gmail.com)
  */
 
 #include "precomp.h"
@@ -39,6 +27,9 @@ static HDPA        sic_hdpa = 0;
 
 static HIMAGELIST ShellSmallIconList;
 static HIMAGELIST ShellBigIconList;
+INT ShellSmallIconSize = 0;
+INT ShellLargeIconSize = 0;
+INT ShellIconBPP = 0; // Bits Per Pixel
 
 namespace
 {
@@ -52,6 +43,48 @@ CRITICAL_SECTION_DEBUG critsect_debug =
 CRITICAL_SECTION SHELL32_SicCS = { &critsect_debug, -1, 0, 0, 0, 0 };
 }
 
+// Load metric value from registry
+static INT
+SIC_GetMetricsValue(
+    _In_ PCWSTR pszValueName,
+    _In_ INT nDefaultValue)
+{
+    WCHAR szValue[64];
+    DWORD cbValue = sizeof(szValue);
+    DWORD error = SHGetValueW(HKEY_CURRENT_USER, L"Control 
Panel\\Desktop\\WindowMetrics",
+                              pszValueName, NULL, szValue, &cbValue);
+    if (error)
+        return nDefaultValue;
+    szValue[_countof(szValue) - 1] = UNICODE_NULL; // Avoid buffer overrun
+    return _wtoi(szValue);
+}
+
+static INT
+SIC_GetLargeIconSize(VOID)
+{
+    // NOTE: Shell icon size is always square
+    INT nDefaultSize = GetSystemMetrics(SM_CXICON);
+    INT nIconSize = SIC_GetMetricsValue(L"Shell Icon Size", nDefaultSize);
+    return (nIconSize > 0) ? nIconSize : nDefaultSize;
+}
+
+static INT
+SIC_GetSmallIconSize(VOID)
+{
+    // NOTE: Shell icon size is always square
+    INT nDefaultSize = GetSystemMetrics(SM_CXSMICON);
+    INT nIconSize = SIC_GetMetricsValue(L"Shell Small Icon Size", 
nDefaultSize);
+    return (nIconSize > 0) ? nIconSize : nDefaultSize;
+}
+
+static INT
+SIC_GetIconBPP(VOID) // Bits Per Pixel
+{
+    INT nDefaultBPP = SHGetCurColorRes();
+    INT nIconBPP = SIC_GetMetricsValue(L"Shell Icon BPP", nDefaultBPP);
+    return (nIconBPP > 0) ? nIconBPP : nDefaultBPP;
+}
+
 /*****************************************************************************
  * SIC_CompareEntries
  *
@@ -386,14 +419,15 @@ leave:
  */
 static INT SIC_LoadIcon (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags)
 {
-    HICON hiconLarge=0;
-    HICON hiconSmall=0;
+    HICON hiconLarge = NULL, hiconSmall = NULL;
     UINT ret;
 
-    PrivateExtractIconsW(sSourceFile, dwSourceIndex, 32, 32, &hiconLarge, 
NULL, 1, LR_COPYFROMRESOURCE);
-    PrivateExtractIconsW(sSourceFile, dwSourceIndex, 16, 16, &hiconSmall, 
NULL, 1, LR_COPYFROMRESOURCE);
+    PrivateExtractIconsW(sSourceFile, dwSourceIndex, ShellLargeIconSize, 
ShellLargeIconSize,
+                         &hiconLarge, NULL, 1, LR_COPYFROMRESOURCE);
+    PrivateExtractIconsW(sSourceFile, dwSourceIndex, ShellSmallIconSize, 
ShellSmallIconSize,
+                         &hiconSmall, NULL, 1, LR_COPYFROMRESOURCE);
 
-    if ( !hiconLarge ||  !hiconSmall)
+    if (!hiconLarge || !hiconSmall)
     {
         WARN("failure loading icon %i from %s (%p %p)\n", dwSourceIndex, 
debugstr_w(sSourceFile), hiconLarge, hiconSmall);
         if(hiconLarge) DestroyIcon(hiconLarge);
@@ -481,9 +515,6 @@ INT SIC_GetIconIndex (LPCWSTR sSourceFile, INT 
dwSourceIndex, DWORD dwFlags )
 BOOL SIC_Initialize(void)
 {
     HICON hSm = NULL, hLg = NULL;
-    INT cx_small, cy_small;
-    INT cx_large, cy_large;
-    HDC hDC;
     INT bpp;
     DWORD ilMask;
     BOOL result = FALSE;
@@ -502,16 +533,10 @@ BOOL SIC_Initialize(void)
         return FALSE;
     }
 
-    hDC = CreateICW(L"DISPLAY", NULL, NULL, NULL);
-    if (!hDC)
-    {
-        ERR("Failed to create information context (error %d)\n", 
GetLastError());
-        goto end;
-    }
-
-    bpp = GetDeviceCaps(hDC, BITSPIXEL);
-    DeleteDC(hDC);
+    ShellSmallIconSize = SIC_GetSmallIconSize();
+    ShellLargeIconSize = SIC_GetLargeIconSize();
 
+    bpp = ShellIconBPP = SIC_GetIconBPP(); // Bits Per Pixel
     if (bpp <= 4)
         ilMask = ILC_COLOR4;
     else if (bpp <= 8)
@@ -527,27 +552,14 @@ BOOL SIC_Initialize(void)
 
     ilMask |= ILC_MASK;
 
-    cx_small = GetSystemMetrics(SM_CXSMICON);
-    cy_small = GetSystemMetrics(SM_CYSMICON);
-    cx_large = GetSystemMetrics(SM_CXICON);
-    cy_large = GetSystemMetrics(SM_CYICON);
-
-    ShellSmallIconList = ImageList_Create(cx_small,
-                                          cy_small,
-                                          ilMask,
-                                          100,
-                                          100);
+    ShellSmallIconList = ImageList_Create(ShellSmallIconSize, 
ShellSmallIconSize, ilMask, 100, 100);
     if (!ShellSmallIconList)
     {
         ERR("Failed to create the small icon list.\n");
         goto end;
     }
 
-    ShellBigIconList = ImageList_Create(cx_large,
-                                        cy_large,
-                                        ilMask,
-                                        100,
-                                        100);
+    ShellBigIconList = ImageList_Create(ShellLargeIconSize, 
ShellLargeIconSize, ilMask, 100, 100);
     if (!ShellBigIconList)
     {
         ERR("Failed to create the big icon list.\n");
@@ -555,11 +567,8 @@ BOOL SIC_Initialize(void)
     }
 
     /* Load the document icon, which is used as the default if an icon isn't 
found. */
-    hSm = (HICON)LoadImageW(shell32_hInstance,
-                            MAKEINTRESOURCEW(IDI_SHELL_DOCUMENT),
-                            IMAGE_ICON,
-                            cx_small,
-                            cy_small,
+    hSm = (HICON)LoadImageW(shell32_hInstance, 
MAKEINTRESOURCEW(IDI_SHELL_DOCUMENT),
+                            IMAGE_ICON, ShellSmallIconSize, ShellSmallIconSize,
                             LR_SHARED | LR_DEFAULTCOLOR);
     if (!hSm)
     {
@@ -567,11 +576,8 @@ BOOL SIC_Initialize(void)
         goto end;
     }
 
-    hLg = (HICON)LoadImageW(shell32_hInstance,
-                            MAKEINTRESOURCEW(IDI_SHELL_DOCUMENT),
-                            IMAGE_ICON,
-                            cx_large,
-                            cy_large,
+    hLg = (HICON)LoadImageW(shell32_hInstance, 
MAKEINTRESOURCEW(IDI_SHELL_DOCUMENT),
+                            IMAGE_ICON, ShellLargeIconSize, ShellLargeIconSize,
                             LR_SHARED | LR_DEFAULTCOLOR);
     if (!hLg)
     {
diff --git a/dll/win32/shell32/wine/shell32_main.c 
b/dll/win32/shell32/wine/shell32_main.c
index 04967da66d1..0a24d36e4ec 100644
--- a/dll/win32/shell32/wine/shell32_main.c
+++ b/dll/win32/shell32/wine/shell32_main.c
@@ -607,9 +607,6 @@ DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path,DWORD 
dwFileAttributes,
     if (flags & SHGFI_SELECTED)
         FIXME("set icon to selected, stub\n");
 
-    if (flags & SHGFI_SHELLICONSIZE)
-        FIXME("set icon to shell size, stub\n");
-
     /* get the iconlocation */
     if (SUCCEEDED(hr) && (flags & SHGFI_ICONLOCATION ))
     {
@@ -700,16 +697,32 @@ DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path,DWORD 
dwFileAttributes,
                     else 
                     {
                         UINT ret;
-                        if (flags & SHGFI_SMALLICON)
-                            ret = PrivateExtractIconsW( sTemp,icon_idx,
-                                GetSystemMetrics( SM_CXSMICON ),
-                                GetSystemMetrics( SM_CYSMICON ),
-                                &psfi->hIcon, 0, 1, 0);
+                        INT cxIcon, cyIcon;
+
+                        /* Get icon size */
+                        if (flags & SHGFI_SHELLICONSIZE)
+                        {
+                            if (flags & SHGFI_SMALLICON)
+                                cxIcon = cyIcon = ShellSmallIconSize;
+                            else
+                                cxIcon = cyIcon = ShellLargeIconSize;
+                        }
                         else
-                            ret = PrivateExtractIconsW( sTemp, icon_idx,
-                                GetSystemMetrics( SM_CXICON),
-                                GetSystemMetrics( SM_CYICON),
-                                &psfi->hIcon, 0, 1, 0);
+                        {
+                            if (flags & SHGFI_SMALLICON)
+                            {
+                                cxIcon = GetSystemMetrics(SM_CXSMICON);
+                                cyIcon = GetSystemMetrics(SM_CYSMICON);
+                            }
+                            else
+                            {
+                                cxIcon = GetSystemMetrics(SM_CXICON);
+                                cyIcon = GetSystemMetrics(SM_CYICON);
+                            }
+                        }
+
+                        ret = PrivateExtractIconsW(sTemp, icon_idx, cxIcon, 
cyIcon,
+                                                   &psfi->hIcon, 0, 1, 0);
                         if (ret != 0 && ret != (UINT)-1)
                         {
                             IconNotYetLoaded=FALSE;
diff --git a/dll/win32/shell32/wine/shell32_main.h 
b/dll/win32/shell32/wine/shell32_main.h
index fa5bafd8880..b631c67a5ef 100644
--- a/dll/win32/shell32/wine/shell32_main.h
+++ b/dll/win32/shell32/wine/shell32_main.h
@@ -44,6 +44,9 @@ BOOL SIC_Initialize(void);
 void SIC_Destroy(void) DECLSPEC_HIDDEN;
 BOOL PidlToSicIndex (IShellFolder * sh, LPCITEMIDLIST pidl, BOOL bBigIcon, 
UINT uFlags, int * pIndex) DECLSPEC_HIDDEN;
 INT SIC_GetIconIndex (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags ) 
DECLSPEC_HIDDEN;
+extern INT ShellLargeIconSize;
+extern INT ShellSmallIconSize;
+extern INT ShellIconBPP;
 
 /* Classes Root */
 HRESULT HCR_GetProgIdKeyOfExtension(PCWSTR szExtension, PHKEY phKey, BOOL 
AllowFallback);

Reply via email to