https://git.reactos.org/?p=reactos.git;a=commitdiff;h=dddceeb10d3d1afa41d7c…
commit dddceeb10d3d1afa41d7ce36cfa0494d00566c76
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Fri Jan 31 08:21:05 2025 +0900
Commit: GitHub <noreply(a)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.mz(a)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);