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