11/*
2- * shell icon cache (SIC)
3- *
4- * Copyright 1998, 1999 Juergen Schmied
5- *
6- * This library is free software; you can redistribute it and/or
7- * modify it under the terms of the GNU Lesser General Public
8- * License as published by the Free Software Foundation; either
9- * version 2.1 of the License, or (at your option) any later version.
10- *
11- * This library is distributed in the hope that it will be useful,
12- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14- * Lesser General Public License for more details.
15- *
16- * You should have received a copy of the GNU Lesser General Public
17- * License along with this library; if not, write to the Free Software
18- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
2+ * PROJECT: ReactOS shell32
3+ * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
4+ * PURPOSE: Shell Icon Cache (SIC)
5+ * COPYRIGHT: Copyright 1998, 1999 Juergen Schmied
6+ * Copyright 2025 Katayama Hirofumi MZ ([email protected] ) 197 */
208
219#include " precomp.h"
@@ -39,6 +27,9 @@ static HDPA sic_hdpa = 0;
3927
4028static HIMAGELIST ShellSmallIconList;
4129static HIMAGELIST ShellBigIconList;
30+ INT ShellSmallIconSize = 0 ;
31+ INT ShellLargeIconSize = 0 ;
32+ INT ShellIconBPP = 0 ; // Bits Per Pixel
4233
4334namespace
4435{
@@ -52,6 +43,48 @@ CRITICAL_SECTION_DEBUG critsect_debug =
5243CRITICAL_SECTION SHELL32_SicCS = { &critsect_debug, -1 , 0 , 0 , 0 , 0 };
5344}
5445
46+ // Load metric value from registry
47+ static INT
48+ SIC_GetMetricsValue (
49+ _In_ PCWSTR pszValueName,
50+ _In_ INT nDefaultValue)
51+ {
52+ WCHAR szValue[64 ];
53+ DWORD cbValue = sizeof (szValue);
54+ DWORD error = SHGetValueW (HKEY_CURRENT_USER, L" Control Panel\\ Desktop\\ WindowMetrics" ,
55+ pszValueName, NULL , szValue, &cbValue);
56+ if (error)
57+ return nDefaultValue;
58+ szValue[_countof (szValue) - 1 ] = UNICODE_NULL; // Avoid buffer overrun
59+ return _wtoi (szValue);
60+ }
61+
62+ static INT
63+ SIC_GetLargeIconSize (VOID)
64+ {
65+ // NOTE: Shell icon size is always square
66+ INT nDefaultSize = GetSystemMetrics (SM_CXICON);
67+ INT nIconSize = SIC_GetMetricsValue (L" Shell Icon Size" , nDefaultSize);
68+ return (nIconSize > 0 ) ? nIconSize : nDefaultSize;
69+ }
70+
71+ static INT
72+ SIC_GetSmallIconSize (VOID)
73+ {
74+ // NOTE: Shell icon size is always square
75+ INT nDefaultSize = GetSystemMetrics (SM_CXSMICON);
76+ INT nIconSize = SIC_GetMetricsValue (L" Shell Small Icon Size" , nDefaultSize);
77+ return (nIconSize > 0 ) ? nIconSize : nDefaultSize;
78+ }
79+
80+ static INT
81+ SIC_GetIconBPP (VOID) // Bits Per Pixel
82+ {
83+ INT nDefaultBPP = SHGetCurColorRes ();
84+ INT nIconBPP = SIC_GetMetricsValue (L" Shell Icon BPP" , nDefaultBPP);
85+ return (nIconBPP > 0 ) ? nIconBPP : nDefaultBPP;
86+ }
87+
5588/* ****************************************************************************
5689 * SIC_CompareEntries
5790 *
@@ -386,14 +419,15 @@ static INT SIC_IconAppend (LPCWSTR sSourceFile, INT dwSourceIndex, HICON hSmallI
386419 */
387420static INT SIC_LoadIcon (LPCWSTR sSourceFile , INT dwSourceIndex, DWORD dwFlags)
388421{
389- HICON hiconLarge=0 ;
390- HICON hiconSmall=0 ;
422+ HICON hiconLarge = NULL , hiconSmall = NULL ;
391423 UINT ret;
392424
393- PrivateExtractIconsW (sSourceFile , dwSourceIndex, 32 , 32 , &hiconLarge, NULL , 1 , LR_COPYFROMRESOURCE);
394- PrivateExtractIconsW (sSourceFile , dwSourceIndex, 16 , 16 , &hiconSmall, NULL , 1 , LR_COPYFROMRESOURCE);
425+ PrivateExtractIconsW (sSourceFile , dwSourceIndex, ShellLargeIconSize, ShellLargeIconSize,
426+ &hiconLarge, NULL , 1 , LR_COPYFROMRESOURCE);
427+ PrivateExtractIconsW (sSourceFile , dwSourceIndex, ShellSmallIconSize, ShellSmallIconSize,
428+ &hiconSmall, NULL , 1 , LR_COPYFROMRESOURCE);
395429
396- if ( !hiconLarge || !hiconSmall)
430+ if (!hiconLarge || !hiconSmall)
397431 {
398432 WARN (" failure loading icon %i from %s (%p %p)\n " , dwSourceIndex, debugstr_w (sSourceFile ), hiconLarge, hiconSmall);
399433 if (hiconLarge) DestroyIcon (hiconLarge);
@@ -481,9 +515,6 @@ INT SIC_GetIconIndex (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags )
481515BOOL SIC_Initialize (void )
482516{
483517 HICON hSm = NULL , hLg = NULL ;
484- INT cx_small, cy_small;
485- INT cx_large, cy_large;
486- HDC hDC;
487518 INT bpp;
488519 DWORD ilMask;
489520 BOOL result = FALSE ;
@@ -502,16 +533,10 @@ BOOL SIC_Initialize(void)
502533 return FALSE ;
503534 }
504535
505- hDC = CreateICW (L" DISPLAY" , NULL , NULL , NULL );
506- if (!hDC)
507- {
508- ERR (" Failed to create information context (error %d)\n " , GetLastError ());
509- goto end;
510- }
511-
512- bpp = GetDeviceCaps (hDC, BITSPIXEL);
513- DeleteDC (hDC);
536+ ShellSmallIconSize = SIC_GetSmallIconSize ();
537+ ShellLargeIconSize = SIC_GetLargeIconSize ();
514538
539+ bpp = ShellIconBPP = SIC_GetIconBPP (); // Bits Per Pixel
515540 if (bpp <= 4 )
516541 ilMask = ILC_COLOR4;
517542 else if (bpp <= 8 )
@@ -527,51 +552,32 @@ BOOL SIC_Initialize(void)
527552
528553 ilMask |= ILC_MASK;
529554
530- cx_small = GetSystemMetrics (SM_CXSMICON);
531- cy_small = GetSystemMetrics (SM_CYSMICON);
532- cx_large = GetSystemMetrics (SM_CXICON);
533- cy_large = GetSystemMetrics (SM_CYICON);
534-
535- ShellSmallIconList = ImageList_Create (cx_small,
536- cy_small,
537- ilMask,
538- 100 ,
539- 100 );
555+ ShellSmallIconList = ImageList_Create (ShellSmallIconSize, ShellSmallIconSize, ilMask, 100 , 100 );
540556 if (!ShellSmallIconList)
541557 {
542558 ERR (" Failed to create the small icon list.\n " );
543559 goto end;
544560 }
545561
546- ShellBigIconList = ImageList_Create (cx_large,
547- cy_large,
548- ilMask,
549- 100 ,
550- 100 );
562+ ShellBigIconList = ImageList_Create (ShellLargeIconSize, ShellLargeIconSize, ilMask, 100 , 100 );
551563 if (!ShellBigIconList)
552564 {
553565 ERR (" Failed to create the big icon list.\n " );
554566 goto end;
555567 }
556568
557569 /* Load the document icon, which is used as the default if an icon isn't found. */
558- hSm = (HICON)LoadImageW (shell32_hInstance,
559- MAKEINTRESOURCEW (IDI_SHELL_DOCUMENT),
560- IMAGE_ICON,
561- cx_small,
562- cy_small,
570+ hSm = (HICON)LoadImageW (shell32_hInstance, MAKEINTRESOURCEW (IDI_SHELL_DOCUMENT),
571+ IMAGE_ICON, ShellSmallIconSize, ShellSmallIconSize,
563572 LR_SHARED | LR_DEFAULTCOLOR);
564573 if (!hSm)
565574 {
566575 ERR (" Failed to load small IDI_SHELL_DOCUMENT icon!\n " );
567576 goto end;
568577 }
569578
570- hLg = (HICON)LoadImageW (shell32_hInstance,
571- MAKEINTRESOURCEW (IDI_SHELL_DOCUMENT),
572- IMAGE_ICON,
573- cx_large,
574- cy_large,
579+ hLg = (HICON)LoadImageW (shell32_hInstance, MAKEINTRESOURCEW (IDI_SHELL_DOCUMENT),
580+ IMAGE_ICON, ShellLargeIconSize, ShellLargeIconSize,
575581 LR_SHARED | LR_DEFAULTCOLOR);
576582 if (!hLg)
577583 {
0 commit comments