Add patch for extra large and jumbo icons.

This commit is contained in:
Michael Müller 2014-08-03 03:33:13 +02:00
parent 281bf873aa
commit 98334f6e19
4 changed files with 388 additions and 0 deletions

View File

@ -18,6 +18,7 @@ Wine-Compholio contains fixes for the following Wine bugs:
* ATL IOCS data should not be stored in GWLP_USERDATA ([Wine Bug #21767](http://bugs.winehq.org/show_bug.cgi?id=21767 "JLC's Internet TV crashes on startup"))
* Add Dynamic DST exceptions for Israel Standard Time ([Wine Bug #36374](http://bugs.winehq.org/show_bug.cgi?id=36374 "Israel timezone handled incorrectly"))
* Add implementation of WTSEnumerateProcessesW ([Wine Bug #29903](http://bugs.winehq.org/show_bug.cgi?id=29903 "Some Microsoft debuggers fail to enumerate processes due to wtsapi32.WTSEnumerateProcessesW() being a stub (Microsoft Visual Studio 2005, DbgCLR from .NET 2.0 SDK)"))
* Add support for extra large and jumbo icon lists in shell32 ([Wine Bug #24721](http://bugs.winehq.org/show_bug.cgi?id=24721 "Explorer++ crashes when choosing to view large icons or extra large icons"))
* Allow special characters in pipe names. ([Wine Bug #28995](http://bugs.winehq.org/show_bug.cgi?id=28995 "Unable to use named pipes with \">\" character in the name"))
* Create AppData\LocalLow directory inside the profile directory ([Wine Bug #22896](http://bugs.winehq.org/show_bug.cgi?id=22896 "Multiple applications and games need support for shell32 FOLDERID_LocalAppDataLow (.NET based Unity Engine games, Java JRE 6 in Vista mode)"))
* Create Saved Games directory inside the profile directory ([Wine Bug #28312](http://bugs.winehq.org/show_bug.cgi?id=28312 "Assassin's Creed Brotherhood v1.03 needs \"Saved Games\" folder"))

View File

@ -28,6 +28,7 @@ PATCHLIST := Miscellaneous.ok \
server-Misc_ACL.ok \
server-Stored_ACLs.ok \
shell32-Default_Folder_ACLs.ok \
shell32-Icons.ok \
shell32-Register_Folders.ok \
shell32-SHCreateSessionKey.ok \
shlwapi-UrlCombine.ok \
@ -504,6 +505,24 @@ shell32-Default_Folder_ACLs.ok:
echo '+ { "shell32-Default_Folder_ACLs", "Erich E. Hoover", "Generate default ACLs for user shell folders. [rev 6]" },'; \
) > shell32-Default_Folder_ACLs.ok
# Patchset shell32-Icons
# |
# | Included patches:
# | * Add support for extra large and jumbo icon lists in shell32. [by Michael Müller]
# |
# | This patchset fixes the following Wine bugs:
# | * [#24721] Explorer++ crashes when choosing to view large icons or extra large icons
# |
# | Modified files:
# | * dlls/shell32/iconcache.c, dlls/shell32/shell32_main.h, dlls/shell32/shellord.c
# |
.INTERMEDIATE: shell32-Icons.ok
shell32-Icons.ok:
$(PATCH) < shell32-Icons/0001-shell32-Add-support-for-extra-large-and-jumbo-icon-l.patch
@( \
echo '+ { "shell32-Icons", "Michael Müller", "Add support for extra large and jumbo icon lists in shell32." },'; \
) > shell32-Icons.ok
# Patchset shell32-Register_Folders
# |
# | Included patches:

View File

@ -0,0 +1,364 @@
From 3db9d42a6ca9547e18ccbcb3b323379e85b206bc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Sun, 3 Aug 2014 02:23:44 +0200
Subject: shell32: Add support for extra large and jumbo icon lists.
---
dlls/shell32/iconcache.c | 198 +++++++++++++++++++++++++++++---------------
dlls/shell32/shell32_main.h | 3 +
dlls/shell32/shellord.c | 28 +++++--
3 files changed, 153 insertions(+), 76 deletions(-)
diff --git a/dlls/shell32/iconcache.c b/dlls/shell32/iconcache.c
index b294908..b9fef10 100644
--- a/dlls/shell32/iconcache.c
+++ b/dlls/shell32/iconcache.c
@@ -62,7 +62,9 @@ typedef struct
static HDPA sic_hdpa;
static INIT_ONCE sic_init_once = INIT_ONCE_STATIC_INIT;
static HIMAGELIST ShellSmallIconList;
-static HIMAGELIST ShellBigIconList;
+static HIMAGELIST ShellLargeIconList;
+static HIMAGELIST ShellExtraLargeIconList;
+static HIMAGELIST ShellJumboIconList;
static CRITICAL_SECTION SHELL32_SicCS;
static CRITICAL_SECTION_DEBUG critsect_debug =
@@ -109,7 +111,7 @@ static int SIC_LoadOverlayIcon(int icon_idx);
* Creates a new icon as a copy of the passed-in icon, overlayed with a
* shortcut image.
*/
-static HICON SIC_OverlayShortcutImage(HICON SourceIcon, BOOL large)
+static HICON SIC_OverlayShortcutImage(HICON SourceIcon, int type)
{ ICONINFO SourceIconInfo, ShortcutIconInfo, TargetIconInfo;
HICON ShortcutIcon, TargetIcon;
BITMAP SourceBitmapInfo, ShortcutBitmapInfo;
@@ -139,10 +141,16 @@ static HICON SIC_OverlayShortcutImage(HICON SourceIcon, BOOL large)
if (s_imgListIdx != -1)
{
- if (large)
- ShortcutIcon = ImageList_GetIcon(ShellBigIconList, s_imgListIdx, ILD_TRANSPARENT);
- else
- ShortcutIcon = ImageList_GetIcon(ShellSmallIconList, s_imgListIdx, ILD_TRANSPARENT);
+ if (type == SHIL_SMALL)
+ ShortcutIcon = ImageList_GetIcon(ShellSmallIconList, s_imgListIdx, ILD_TRANSPARENT);
+ else if (type == SHIL_LARGE)
+ ShortcutIcon = ImageList_GetIcon(ShellLargeIconList, s_imgListIdx, ILD_TRANSPARENT);
+ else if (type == SHIL_EXTRALARGE)
+ ShortcutIcon = ImageList_GetIcon(ShellExtraLargeIconList, s_imgListIdx, ILD_TRANSPARENT);
+ else if (type == SHIL_JUMBO)
+ ShortcutIcon = ImageList_GetIcon(ShellJumboIconList, s_imgListIdx, ILD_TRANSPARENT);
+ else
+ ShortcutIcon = NULL;
} else
ShortcutIcon = NULL;
@@ -258,11 +266,14 @@ fail:
* NOTES
* appends an icon pair to the end of the cache
*/
-static INT SIC_IconAppend (LPCWSTR sSourceFile, INT dwSourceIndex, HICON hSmallIcon, HICON hBigIcon, DWORD dwFlags)
-{ LPSIC_ENTRY lpsice;
- INT ret, index, index1;
+static INT SIC_IconAppend(LPCWSTR sSourceFile, INT dwSourceIndex, HICON hSmallIcon,
+ HICON hLargeIcon, HICON hExtraLargeIcon, HICON hJumboIcon, DWORD dwFlags)
+{
+ LPSIC_ENTRY lpsice;
+ INT ret, index, index1, index2, index3;
WCHAR path[MAX_PATH];
- TRACE("%s %i %p %p\n", debugstr_w(sSourceFile), dwSourceIndex, hSmallIcon ,hBigIcon);
+ TRACE("%s %i %p %p %p %p %d\n", debugstr_w(sSourceFile), dwSourceIndex, hSmallIcon,
+ hLargeIcon, hExtraLargeIcon, hJumboIcon, dwFlags);
lpsice = SHAlloc(sizeof(SIC_ENTRY));
@@ -284,13 +295,14 @@ static INT SIC_IconAppend (LPCWSTR sSourceFile, INT dwSourceIndex, HICON hSmallI
}
else
{
- index = ImageList_AddIcon (ShellSmallIconList, hSmallIcon);
- index1= ImageList_AddIcon (ShellBigIconList, hBigIcon);
+ index = ImageList_AddIcon( ShellSmallIconList, hSmallIcon );
+ index1 = ImageList_AddIcon( ShellLargeIconList, hLargeIcon );
+ index2 = ImageList_AddIcon( ShellExtraLargeIconList, hExtraLargeIcon );
+ index3 = ImageList_AddIcon( ShellJumboIconList, hJumboIcon );
+
+ if (index != index1 || index != index2 || index != index3)
+ FIXME("iconlists out of sync 0x%x 0x%x 0x%x 0x%x\n", index, index1, index2, index3);
- if (index!=index1)
- {
- FIXME("iconlists out of sync 0x%x 0x%x\n", index, index1);
- }
lpsice->dwListIndex = index;
ret = lpsice->dwListIndex;
}
@@ -305,15 +317,22 @@ static INT SIC_IconAppend (LPCWSTR sSourceFile, INT dwSourceIndex, HICON hSmallI
* gets small/big icon by number from a file
*/
static INT SIC_LoadIcon (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags)
-{ HICON hiconLarge=0;
- HICON hiconSmall=0;
- HICON hiconLargeShortcut;
- HICON hiconSmallShortcut;
-
- PrivateExtractIconsW( sSourceFile, dwSourceIndex, 32, 32, &hiconLarge, 0, 1, 0 );
- PrivateExtractIconsW( sSourceFile, dwSourceIndex, 16, 16, &hiconSmall, 0, 1, 0 );
-
- if ( !hiconLarge || !hiconSmall)
+{
+ HICON hiconSmall=0;
+ HICON hiconLarge=0;
+ HICON hiconExtraLarge=0;
+ HICON hiconJumbo=0;
+ HICON hiconSmallShortcut;
+ HICON hiconLargeShortcut;
+ HICON hiconExtraLargeShortcut;
+ HICON hiconJumboShortcut;
+
+ PrivateExtractIconsW( sSourceFile, dwSourceIndex, 16, 16, &hiconSmall, 0, 1, 0 );
+ PrivateExtractIconsW( sSourceFile, dwSourceIndex, 32, 32, &hiconLarge, 0, 1, 0 );
+ PrivateExtractIconsW( sSourceFile, dwSourceIndex, 48, 48, &hiconExtraLarge, 0, 1, 0 );
+ PrivateExtractIconsW( sSourceFile, dwSourceIndex, 256, 256, &hiconJumbo, 0, 1, 0 );
+
+ if ( !hiconSmall || !hiconLarge || !hiconExtraLarge || !hiconJumbo )
{
WARN("failure loading icon %i from %s (%p %p)\n", dwSourceIndex, debugstr_w(sSourceFile), hiconLarge, hiconSmall);
return -1;
@@ -321,38 +340,59 @@ static INT SIC_LoadIcon (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags)
if (0 != (dwFlags & GIL_FORSHORTCUT))
{
- hiconLargeShortcut = SIC_OverlayShortcutImage(hiconLarge, TRUE);
- hiconSmallShortcut = SIC_OverlayShortcutImage(hiconSmall, FALSE);
- if (NULL != hiconLargeShortcut && NULL != hiconSmallShortcut)
- {
- hiconLarge = hiconLargeShortcut;
- hiconSmall = hiconSmallShortcut;
- }
- else
- {
- WARN("Failed to create shortcut overlayed icons\n");
- if (NULL != hiconLargeShortcut) DestroyIcon(hiconLargeShortcut);
- if (NULL != hiconSmallShortcut) DestroyIcon(hiconSmallShortcut);
- dwFlags &= ~ GIL_FORSHORTCUT;
- }
+ hiconSmallShortcut = SIC_OverlayShortcutImage( hiconSmall, SHIL_SMALL );
+ hiconLargeShortcut = SIC_OverlayShortcutImage( hiconLarge, SHIL_LARGE );
+ hiconExtraLargeShortcut = SIC_OverlayShortcutImage( hiconExtraLarge, SHIL_EXTRALARGE );
+ hiconJumboShortcut = SIC_OverlayShortcutImage( hiconJumbo, SHIL_JUMBO );
+
+ if (NULL != hiconLargeShortcut && NULL != hiconSmallShortcut &&
+ NULL != hiconExtraLargeShortcut && NULL != hiconJumboShortcut)
+ {
+ hiconSmall = hiconSmallShortcut;
+ hiconLarge = hiconLargeShortcut;
+ hiconExtraLarge = hiconExtraLargeShortcut;
+ hiconJumbo = hiconJumboShortcut;
+ }
+ else
+ {
+ WARN("Failed to create shortcut overlayed icons\n");
+ if (NULL != hiconSmallShortcut) DestroyIcon(hiconSmallShortcut);
+ if (NULL != hiconLargeShortcut) DestroyIcon(hiconLargeShortcut);
+ if (NULL != hiconExtraLargeShortcut) DestroyIcon(hiconExtraLargeShortcut);
+ if (NULL != hiconJumboShortcut) DestroyIcon(hiconJumboShortcut);
+ dwFlags &= ~ GIL_FORSHORTCUT;
+ }
}
- return SIC_IconAppend (sSourceFile, dwSourceIndex, hiconSmall, hiconLarge, dwFlags);
+ return SIC_IconAppend( sSourceFile, dwSourceIndex, hiconSmall, hiconLarge,
+ hiconExtraLarge, hiconJumbo, dwFlags );
}
/*****************************************************************************
* SIC_Initialize [internal]
*/
static BOOL WINAPI SIC_Initialize( INIT_ONCE *once, void *param, void **context )
{
- HICON hSm, hLg;
- int cx_small, cy_small;
- int cx_large, cy_large;
+ HICON hSm, hLg, hELg, hJb;
+ int cx_small, cy_small;
+ int cx_large, cy_large;
+ int cx_extralarge, cy_extralarge;
+ int cx_jumbo, cy_jumbo;
cx_small = GetSystemMetrics(SM_CXSMICON);
cy_small = GetSystemMetrics(SM_CYSMICON);
cx_large = GetSystemMetrics(SM_CXICON);
cy_large = GetSystemMetrics(SM_CYICON);
+ /*
+ * TODO: according to
+ * http://msdn.microsoft.com/en-us/library/windows/desktop/bb762185(v=vs.85).aspx
+ * the size can be configured, but where is the value defined?
+ */
+ cx_extralarge = 48;
+ cy_extralarge = 48;
+ cx_jumbo = 256;
+ cy_jumbo = 256;
+
TRACE("\n");
sic_hdpa = DPA_Create(16);
@@ -362,28 +402,36 @@ static BOOL WINAPI SIC_Initialize( INIT_ONCE *once, void *param, void **context
return(FALSE);
}
- ShellSmallIconList = ImageList_Create(cx_small,cy_small,ILC_COLOR32|ILC_MASK,0,0x20);
- ShellBigIconList = ImageList_Create(cx_large,cy_large,ILC_COLOR32|ILC_MASK,0,0x20);
+ ShellSmallIconList = ImageList_Create( cx_small,cy_small,ILC_COLOR32|ILC_MASK,0,0x20 );
+ ShellLargeIconList = ImageList_Create( cx_large,cy_large,ILC_COLOR32|ILC_MASK,0,0x20 );
+ ShellExtraLargeIconList = ImageList_Create( cx_extralarge,cy_extralarge,ILC_COLOR32|ILC_MASK,0,0x20 );
+ ShellJumboIconList = ImageList_Create( cx_jumbo,cy_jumbo,ILC_COLOR32|ILC_MASK,0,0x20 );
+
+ ImageList_SetBkColor( ShellSmallIconList, CLR_NONE );
+ ImageList_SetBkColor( ShellLargeIconList, CLR_NONE );
+ ImageList_SetBkColor( ShellExtraLargeIconList, CLR_NONE );
+ ImageList_SetBkColor( ShellJumboIconList, CLR_NONE );
+
+ /* Load the document icon, which is used as the default if an icon isn't found. */
+ hSm = LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(IDI_SHELL_DOCUMENT),
+ IMAGE_ICON, cx_small, cy_small, LR_SHARED);
+ hLg = LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(IDI_SHELL_DOCUMENT),
+ IMAGE_ICON, cx_large, cy_large, LR_SHARED);
+ hELg = LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(IDI_SHELL_DOCUMENT),
+ IMAGE_ICON, cx_extralarge, cy_extralarge, LR_SHARED);
+ hJb = LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(IDI_SHELL_DOCUMENT),
+ IMAGE_ICON, cx_jumbo, cy_jumbo, LR_SHARED);
+ if (!hSm || !hLg || !hELg || !hJb)
+ {
+ FIXME("Failed to load IDI_SHELL_DOCUMENT icon!\n");
+ return FALSE;
+ }
- ImageList_SetBkColor(ShellSmallIconList, CLR_NONE);
- ImageList_SetBkColor(ShellBigIconList, CLR_NONE);
+ SIC_IconAppend( swShell32Name, IDI_SHELL_DOCUMENT-1, hSm, hLg, hELg, hJb, 0 );
+ SIC_IconAppend( swShell32Name, -IDI_SHELL_DOCUMENT, hSm, hLg, hELg, hJb, 0 );
- /* Load the document icon, which is used as the default if an icon isn't found. */
- hSm = LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(IDI_SHELL_DOCUMENT),
- IMAGE_ICON, cx_small, cy_small, LR_SHARED);
- hLg = LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(IDI_SHELL_DOCUMENT),
- IMAGE_ICON, cx_large, cy_large, LR_SHARED);
-
- if (!hSm || !hLg)
- {
- FIXME("Failed to load IDI_SHELL_DOCUMENT icon!\n");
- return FALSE;
- }
-
- SIC_IconAppend (swShell32Name, IDI_SHELL_DOCUMENT-1, hSm, hLg, 0);
- SIC_IconAppend (swShell32Name, -IDI_SHELL_DOCUMENT, hSm, hLg, 0);
-
- TRACE("hIconSmall=%p hIconBig=%p\n",ShellSmallIconList, ShellBigIconList);
+ TRACE("hIconSmall=%p hIconLarge=%p hExtraLargeIcon=%p hJumboIcon=%p\n",
+ ShellSmallIconList, ShellLargeIconList, ShellExtraLargeIconList, ShellJumboIconList);
return TRUE;
}
@@ -407,10 +455,14 @@ void SIC_Destroy(void)
if (sic_hdpa) DPA_DestroyCallback(sic_hdpa, sic_free, NULL );
- if (ShellSmallIconList)
- ImageList_Destroy(ShellSmallIconList);
- if (ShellBigIconList)
- ImageList_Destroy(ShellBigIconList);
+ if (ShellSmallIconList)
+ ImageList_Destroy( ShellSmallIconList );
+ if (ShellLargeIconList)
+ ImageList_Destroy( ShellLargeIconList );
+ if (ShellExtraLargeIconList)
+ ImageList_Destroy( ShellExtraLargeIconList );
+ if (ShellJumboIconList)
+ ImageList_Destroy( ShellJumboIconList );
LeaveCriticalSection(&SHELL32_SicCS);
DeleteCriticalSection(&SHELL32_SicCS);
@@ -527,10 +579,20 @@ BOOL WINAPI Shell_GetImageLists(HIMAGELIST * lpBigList, HIMAGELIST * lpSmallList
{
TRACE("(%p,%p)\n",lpBigList,lpSmallList);
InitOnceExecuteOnce( &sic_init_once, SIC_Initialize, NULL, NULL );
- if (lpBigList) *lpBigList = ShellBigIconList;
+ if (lpBigList) *lpBigList = ShellLargeIconList;
if (lpSmallList) *lpSmallList = ShellSmallIconList;
return TRUE;
}
+
+void SHELL_GetInternalImageLists(HIMAGELIST *lpSmallList, HIMAGELIST *lpLargeList,
+ HIMAGELIST *lpExtraLargeList, HIMAGELIST *lpJumboList)
+{
+ if (lpSmallList) *lpSmallList = ShellSmallIconList;
+ if (lpLargeList) *lpLargeList = ShellLargeIconList;
+ if (lpExtraLargeList) *lpExtraLargeList = ShellExtraLargeIconList;
+ if (lpJumboList) *lpJumboList = ShellJumboIconList;
+}
+
/*************************************************************************
* PidlToSicIndex [INTERNAL]
*
diff --git a/dlls/shell32/shell32_main.h b/dlls/shell32/shell32_main.h
index 954f1e4..e1e77f1 100644
--- a/dlls/shell32/shell32_main.h
+++ b/dlls/shell32/shell32_main.h
@@ -232,4 +232,7 @@ BOOL CreateFolderEnumList(IEnumIDListImpl *list, LPCWSTR lpszPath, DWORD dwFlags
void release_typelib(void) DECLSPEC_HIDDEN;
void release_desktop_folder(void) DECLSPEC_HIDDEN;
+void SHELL_GetInternalImageLists(HIMAGELIST *lpSmallList, HIMAGELIST *lpLargeList,
+ HIMAGELIST *lpExtraLargeList, HIMAGELIST *lpJumboList) DECLSPEC_HIDDEN;
+
#endif
diff --git a/dlls/shell32/shellord.c b/dlls/shell32/shellord.c
index 56c9fe9..e4d4f48 100644
--- a/dlls/shell32/shellord.c
+++ b/dlls/shell32/shellord.c
@@ -2182,20 +2182,32 @@ void WINAPI SHFlushSFCache(void)
*/
HRESULT WINAPI SHGetImageList(int iImageList, REFIID riid, void **ppv)
{
- HIMAGELIST hLarge, hSmall;
+ HIMAGELIST hSmall, hLarge, hExtraLarge, hJumbo;
HIMAGELIST hNew;
HRESULT ret = E_FAIL;
- /* Wine currently only maintains large and small image lists */
- if ((iImageList != SHIL_LARGE) && (iImageList != SHIL_SMALL) && (iImageList != SHIL_SYSSMALL))
+ SHELL_GetInternalImageLists( &hSmall, &hLarge, &hExtraLarge, &hJumbo );
+
+ switch (iImageList)
{
- FIXME("Unsupported image list %i requested\n", iImageList);
- return E_FAIL;
+ case SHIL_SMALL:
+ case SHIL_SYSSMALL:
+ hNew = ImageList_Duplicate( hSmall );
+ break;
+ case SHIL_LARGE:
+ hNew = ImageList_Duplicate( hLarge );
+ break;
+ case SHIL_EXTRALARGE:
+ hNew = ImageList_Duplicate( hExtraLarge );
+ break;
+ case SHIL_JUMBO:
+ hNew = ImageList_Duplicate( hJumbo );
+ break;
+ default:
+ FIXME("Unsupported image list %i requested\n", iImageList);
+ return E_FAIL;
}
- Shell_GetImageLists(&hLarge, &hSmall);
- hNew = ImageList_Duplicate(iImageList == SHIL_LARGE ? hLarge : hSmall);
-
/* Get the interface for the new image list */
if (hNew)
{
--
1.8.3.2

View File

@ -0,0 +1,4 @@
Author: Michael Müller
Subject: Add support for extra large and jumbo icon lists in shell32.
Revision: 1
Fixes: [24721] Add support for extra large and jumbo icon lists in shell32