[PATCH v2 1/6] shell32: Fix the icon sizes of the shell imagelists.
Huw Davies
huw at codeweavers.com
Tue May 2 09:13:13 CDT 2017
Signed-off-by: Huw Davies <huw at codeweavers.com>
---
dlls/shell32/iconcache.c | 42 ++++++++++++++++++++++++++----
dlls/shell32/tests/shelllink.c | 58 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 95 insertions(+), 5 deletions(-)
diff --git a/dlls/shell32/iconcache.c b/dlls/shell32/iconcache.c
index 737f4d5023..59fd8fb104 100644
--- a/dlls/shell32/iconcache.c
+++ b/dlls/shell32/iconcache.c
@@ -73,6 +73,11 @@ static CRITICAL_SECTION_DEBUG critsect_debug =
};
static CRITICAL_SECTION SHELL32_SicCS = { &critsect_debug, -1, 0, 0, 0, 0 };
+
+static const WCHAR WindowMetrics[] = {'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\','D','e','s','k','t','o','p','\\',
+ 'W','i','n','d','o','w','M','e','t','r','i','c','s',0};
+static const WCHAR ShellIconSize[] = {'S','h','e','l','l',' ','I','c','o','n',' ','S','i','z','e',0};
+
/*****************************************************************************
* SIC_CompareEntries
*
@@ -361,6 +366,24 @@ static INT SIC_LoadIcon (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags)
return ret;
}
+static int get_shell_icon_size(void)
+{
+ WCHAR buf[32];
+ DWORD value = 32, size = sizeof(buf), type;
+ HKEY key;
+
+ if (!RegOpenKeyW( HKEY_CURRENT_USER, WindowMetrics, &key ))
+ {
+ if (!RegQueryValueExW( key, ShellIconSize, NULL, &type, (BYTE *)buf, &size ) && type == REG_SZ)
+ {
+ if (size == sizeof(buf)) buf[size / sizeof(WCHAR) - 1] = 0;
+ value = atoiW( buf );
+ }
+ RegCloseKey( key );
+ }
+ return value;
+}
+
/*****************************************************************************
* SIC_Initialize [internal]
*/
@@ -370,12 +393,21 @@ static BOOL WINAPI SIC_Initialize( INIT_ONCE *once, void *param, void **context
int cx_small, cy_small;
int cx_large, cy_large;
- cx_small = GetSystemMetrics(SM_CXSMICON);
- cy_small = GetSystemMetrics(SM_CYSMICON);
- cx_large = GetSystemMetrics(SM_CXICON);
- cy_large = GetSystemMetrics(SM_CYICON);
+ if (!IsProcessDPIAware())
+ {
+ cx_large = cy_large = get_shell_icon_size();
+ cx_small = GetSystemMetrics( SM_CXSMICON );
+ cy_small = GetSystemMetrics( SM_CYSMICON );
+ }
+ else
+ {
+ cx_large = GetSystemMetrics( SM_CXICON );
+ cy_large = GetSystemMetrics( SM_CYICON );
+ cx_small = cx_large / 2;
+ cy_small = cy_large / 2;
+ }
- TRACE("\n");
+ TRACE("large %dx%d small %dx%d\n", cx_large, cy_large, cx_small, cx_small);
sic_hdpa = DPA_Create(16);
diff --git a/dlls/shell32/tests/shelllink.c b/dlls/shell32/tests/shelllink.c
index db15ccd7ed..ad254c8349 100644
--- a/dlls/shell32/tests/shelllink.c
+++ b/dlls/shell32/tests/shelllink.c
@@ -44,6 +44,7 @@ static HRESULT (WINAPI *pSHGetStockIconInfo)(SHSTOCKICONID, UINT, SHSTOCKICONINF
static DWORD (WINAPI *pGetLongPathNameA)(LPCSTR, LPSTR, DWORD);
static DWORD (WINAPI *pGetShortPathNameA)(LPCSTR, LPSTR, DWORD);
static UINT (WINAPI *pSHExtractIconsW)(LPCWSTR, int, int, int, HICON *, UINT *, UINT, UINT);
+static BOOL (WINAPI *pIsProcessDPIAware)(void);
static const GUID _IID_IShellLinkDataList = {
0x45e2b4ae, 0xb1c3, 0x11d0,
@@ -1304,6 +1305,21 @@ todo_wine {
DestroyIcon(hicon);
}
+static int get_shell_icon_size(void)
+{
+ char buf[10];
+ DWORD value = 32, size = sizeof(buf), type;
+ HKEY key;
+
+ if (!RegOpenKeyA( HKEY_CURRENT_USER, "Control Panel\\Desktop\\WindowMetrics", &key ))
+ {
+ if (!RegQueryValueExA( key, "Shell Icon Size", NULL, &type, (BYTE *)buf, &size ) && type == REG_SZ)
+ value = atoi( buf );
+ RegCloseKey( key );
+ }
+ return value;
+}
+
static void test_SHGetImageList(void)
{
HRESULT hr;
@@ -1311,6 +1327,8 @@ static void test_SHGetImageList(void)
BOOL ret;
HIMAGELIST lg, sm;
ULONG start_refs, refs;
+ int i, width, height, expect;
+ BOOL dpi_aware = pIsProcessDPIAware && pIsProcessDPIAware();
hr = SHGetImageList( SHIL_LARGE, &IID_IImageList, (void **)&list );
ok( hr == S_OK, "got %08x\n", hr );
@@ -1340,6 +1358,44 @@ static void test_SHGetImageList(void)
IImageList_Release( list2 );
IImageList_Release( list );
+
+ /* Test the icon sizes */
+ for (i = 0; i <= SHIL_LAST; i++)
+ {
+ hr = SHGetImageList( i, &IID_IImageList, (void **)&list );
+ todo_wine_if(i == SHIL_EXTRALARGE || i == SHIL_JUMBO)
+ ok( hr == S_OK ||
+ broken( i == SHIL_JUMBO && hr == E_INVALIDARG ), /* XP and 2003 */
+ "%d: got %08x\n", i, hr );
+ if (FAILED(hr)) continue;
+ IImageList_GetIconSize( list, &width, &height );
+ switch (i)
+ {
+ case SHIL_LARGE:
+ if (dpi_aware) expect = GetSystemMetrics( SM_CXICON );
+ else expect = get_shell_icon_size();
+ break;
+ case SHIL_SMALL:
+ if (dpi_aware) expect = GetSystemMetrics( SM_CXICON ) / 2;
+ else expect = GetSystemMetrics( SM_CXSMICON );
+ break;
+ case SHIL_EXTRALARGE:
+ expect = (GetSystemMetrics( SM_CXICON ) * 3) / 2;
+ break;
+ case SHIL_SYSSMALL:
+ expect = GetSystemMetrics( SM_CXSMICON );
+ break;
+ case SHIL_JUMBO:
+ expect = 256;
+ break;
+ }
+ todo_wine_if(i == SHIL_SYSSMALL && dpi_aware && expect != GetSystemMetrics( SM_CXICON ) / 2)
+ {
+ ok( width == expect, "%d: got %d expect %d\n", i, width, expect );
+ ok( height == expect, "%d: got %d expect %d\n", i, height, expect );
+ }
+ IImageList_Release( list );
+ }
}
START_TEST(shelllink)
@@ -1347,6 +1403,7 @@ START_TEST(shelllink)
HRESULT r;
HMODULE hmod = GetModuleHandleA("shell32.dll");
HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
+ HMODULE huser32 = GetModuleHandleA("user32.dll");
pILFree = (void *)GetProcAddress(hmod, (LPSTR)155);
pILIsEqual = (void *)GetProcAddress(hmod, (LPSTR)21);
@@ -1356,6 +1413,7 @@ START_TEST(shelllink)
pGetLongPathNameA = (void *)GetProcAddress(hkernel32, "GetLongPathNameA");
pGetShortPathNameA = (void *)GetProcAddress(hkernel32, "GetShortPathNameA");
pSHExtractIconsW = (void *)GetProcAddress(hmod, "SHExtractIconsW");
+ pIsProcessDPIAware = (void *)GetProcAddress(huser32, "IsProcessDPIAware");
r = CoInitialize(NULL);
ok(r == S_OK, "CoInitialize failed (0x%08x)\n", r);
--
2.12.0
More information about the wine-patches
mailing list