Skip to content

Commit dddceeb

Browse files
authored
[SHELL32] Load shell icon size from registry (reactos#7683)
Improve usability. Re-trial of reactos#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.
1 parent 909468c commit dddceeb

File tree

3 files changed

+93
-71
lines changed

3 files changed

+93
-71
lines changed

dll/win32/shell32/iconcache.cpp

Lines changed: 65 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,9 @@
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

4028
static HIMAGELIST ShellSmallIconList;
4129
static HIMAGELIST ShellBigIconList;
30+
INT ShellSmallIconSize = 0;
31+
INT ShellLargeIconSize = 0;
32+
INT ShellIconBPP = 0; // Bits Per Pixel
4233

4334
namespace
4435
{
@@ -52,6 +43,48 @@ CRITICAL_SECTION_DEBUG critsect_debug =
5243
CRITICAL_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
*/
387420
static 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 )
481515
BOOL 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
{

dll/win32/shell32/wine/shell32_main.c

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -607,9 +607,6 @@ DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes,
607607
if (flags & SHGFI_SELECTED)
608608
FIXME("set icon to selected, stub\n");
609609

610-
if (flags & SHGFI_SHELLICONSIZE)
611-
FIXME("set icon to shell size, stub\n");
612-
613610
/* get the iconlocation */
614611
if (SUCCEEDED(hr) && (flags & SHGFI_ICONLOCATION ))
615612
{
@@ -700,16 +697,32 @@ DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes,
700697
else
701698
{
702699
UINT ret;
703-
if (flags & SHGFI_SMALLICON)
704-
ret = PrivateExtractIconsW( sTemp,icon_idx,
705-
GetSystemMetrics( SM_CXSMICON ),
706-
GetSystemMetrics( SM_CYSMICON ),
707-
&psfi->hIcon, 0, 1, 0);
700+
INT cxIcon, cyIcon;
701+
702+
/* Get icon size */
703+
if (flags & SHGFI_SHELLICONSIZE)
704+
{
705+
if (flags & SHGFI_SMALLICON)
706+
cxIcon = cyIcon = ShellSmallIconSize;
707+
else
708+
cxIcon = cyIcon = ShellLargeIconSize;
709+
}
708710
else
709-
ret = PrivateExtractIconsW( sTemp, icon_idx,
710-
GetSystemMetrics( SM_CXICON),
711-
GetSystemMetrics( SM_CYICON),
712-
&psfi->hIcon, 0, 1, 0);
711+
{
712+
if (flags & SHGFI_SMALLICON)
713+
{
714+
cxIcon = GetSystemMetrics(SM_CXSMICON);
715+
cyIcon = GetSystemMetrics(SM_CYSMICON);
716+
}
717+
else
718+
{
719+
cxIcon = GetSystemMetrics(SM_CXICON);
720+
cyIcon = GetSystemMetrics(SM_CYICON);
721+
}
722+
}
723+
724+
ret = PrivateExtractIconsW(sTemp, icon_idx, cxIcon, cyIcon,
725+
&psfi->hIcon, 0, 1, 0);
713726
if (ret != 0 && ret != (UINT)-1)
714727
{
715728
IconNotYetLoaded=FALSE;

dll/win32/shell32/wine/shell32_main.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ BOOL SIC_Initialize(void);
4444
void SIC_Destroy(void) DECLSPEC_HIDDEN;
4545
BOOL PidlToSicIndex (IShellFolder * sh, LPCITEMIDLIST pidl, BOOL bBigIcon, UINT uFlags, int * pIndex) DECLSPEC_HIDDEN;
4646
INT SIC_GetIconIndex (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags ) DECLSPEC_HIDDEN;
47+
extern INT ShellLargeIconSize;
48+
extern INT ShellSmallIconSize;
49+
extern INT ShellIconBPP;
4750

4851
/* Classes Root */
4952
HRESULT HCR_GetProgIdKeyOfExtension(PCWSTR szExtension, PHKEY phKey, BOOL AllowFallback);

0 commit comments

Comments
 (0)