shell32: Load icons with the correct size.
Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
b8bf0c2628
commit
a7d79fe445
|
@ -78,6 +78,8 @@ static const WCHAR WindowMetrics[] = {'C','o','n','t','r','o','l',' ','P','a','n
|
|||
'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};
|
||||
|
||||
#define SIC_COMPARE_LISTINDEX 1
|
||||
|
||||
/*****************************************************************************
|
||||
* SIC_CompareEntries
|
||||
*
|
||||
|
@ -94,6 +96,10 @@ static INT CALLBACK SIC_CompareEntries( LPVOID p1, LPVOID p2, LPARAM lparam)
|
|||
* loaded from, their resource index and the fact if they have a shortcut
|
||||
* icon overlay or not.
|
||||
*/
|
||||
|
||||
if (lparam & SIC_COMPARE_LISTINDEX)
|
||||
return e1->dwListIndex != e2->dwListIndex;
|
||||
|
||||
if (e1->dwSourceIndex != e2->dwSourceIndex || /* first the faster one */
|
||||
(e1->dwFlags & GIL_FORSHORTCUT) != (e2->dwFlags & GIL_FORSHORTCUT))
|
||||
return 1;
|
||||
|
@ -104,6 +110,44 @@ static INT CALLBACK SIC_CompareEntries( LPVOID p1, LPVOID p2, LPARAM lparam)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************************
|
||||
* SIC_get_location
|
||||
*
|
||||
* Returns the source file and resource index of an icon with the given imagelist index
|
||||
*/
|
||||
HRESULT SIC_get_location( int list_idx, WCHAR *file, DWORD *size, int *res_idx )
|
||||
{
|
||||
SIC_ENTRY seek, *found;
|
||||
DWORD needed;
|
||||
HRESULT hr = E_INVALIDARG;
|
||||
int dpa_idx;
|
||||
|
||||
seek.dwListIndex = list_idx;
|
||||
|
||||
EnterCriticalSection( &SHELL32_SicCS );
|
||||
|
||||
dpa_idx = DPA_Search( sic_hdpa, &seek, 0, SIC_CompareEntries, SIC_COMPARE_LISTINDEX, 0 );
|
||||
if (dpa_idx != -1)
|
||||
{
|
||||
found = (SIC_ENTRY *)DPA_GetPtr( sic_hdpa, dpa_idx );
|
||||
needed = (strlenW( found->sSourceFile ) + 1) * sizeof(WCHAR);
|
||||
if (needed <= *size)
|
||||
{
|
||||
memcpy( file, found->sSourceFile, needed );
|
||||
*res_idx = found->dwSourceIndex;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*size = needed;
|
||||
hr = E_NOT_SUFFICIENT_BUFFER;
|
||||
}
|
||||
}
|
||||
LeaveCriticalSection( &SHELL32_SicCS );
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
/* declare SIC_LoadOverlayIcon() */
|
||||
static int SIC_LoadOverlayIcon(int icon_idx);
|
||||
|
||||
|
|
|
@ -427,7 +427,6 @@ DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes,
|
|||
IExtractIconW * pei = NULL;
|
||||
LPITEMIDLIST pidlLast = NULL, pidl = NULL;
|
||||
HRESULT hr = S_OK;
|
||||
BOOL IconNotYetLoaded=TRUE;
|
||||
UINT uGilFlags = 0;
|
||||
|
||||
TRACE("%s fattr=0x%x sfi=%p(attr=0x%08x) size=0x%x flags=0x%x\n",
|
||||
|
@ -598,9 +597,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 ))
|
||||
{
|
||||
|
@ -667,17 +663,16 @@ DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes,
|
|||
|
||||
if (flags & SHGFI_USEFILEATTRIBUTES && !(flags & SHGFI_PIDL))
|
||||
{
|
||||
WCHAR sTemp [MAX_PATH];
|
||||
WCHAR * szExt;
|
||||
int icon_idx=0;
|
||||
|
||||
lstrcpynW(sTemp, szFullPath, MAX_PATH);
|
||||
|
||||
if (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
psfi->iIcon = SIC_GetIconIndex(swShell32Name, -IDI_SHELL_FOLDER, 0);
|
||||
else
|
||||
{
|
||||
static const WCHAR p1W[] = {'%','1',0};
|
||||
WCHAR sTemp[MAX_PATH];
|
||||
WCHAR *szExt;
|
||||
int icon_idx = 0;
|
||||
|
||||
lstrcpynW(sTemp, szFullPath, MAX_PATH);
|
||||
|
||||
psfi->iIcon = 0;
|
||||
szExt = PathFindExtensionW(sTemp);
|
||||
|
@ -688,31 +683,9 @@ DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes,
|
|||
if (!lstrcmpW(p1W,sTemp)) /* icon is in the file */
|
||||
strcpyW(sTemp, szFullPath);
|
||||
|
||||
if (flags & SHGFI_SYSICONINDEX)
|
||||
{
|
||||
psfi->iIcon = SIC_GetIconIndex(sTemp,icon_idx,0);
|
||||
if (psfi->iIcon == -1)
|
||||
psfi->iIcon = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT ret;
|
||||
if (flags & SHGFI_SMALLICON)
|
||||
ret = PrivateExtractIconsW( sTemp,icon_idx,
|
||||
GetSystemMetrics( SM_CXSMICON ),
|
||||
GetSystemMetrics( SM_CYSMICON ),
|
||||
&psfi->hIcon, 0, 1, 0);
|
||||
else
|
||||
ret = PrivateExtractIconsW( sTemp, icon_idx,
|
||||
GetSystemMetrics( SM_CXICON),
|
||||
GetSystemMetrics( SM_CYICON),
|
||||
&psfi->hIcon, 0, 1, 0);
|
||||
if (ret != 0 && ret != (UINT)-1)
|
||||
{
|
||||
IconNotYetLoaded=FALSE;
|
||||
psfi->iIcon = icon_idx;
|
||||
}
|
||||
}
|
||||
psfi->iIcon = SIC_GetIconIndex(sTemp, icon_idx, 0);
|
||||
if (psfi->iIcon == -1)
|
||||
psfi->iIcon = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -731,7 +704,37 @@ DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes,
|
|||
}
|
||||
if (ret && (flags & SHGFI_ICON))
|
||||
{
|
||||
hr = IImageList_GetIcon( icon_list, psfi->iIcon, ILD_NORMAL, &psfi->hIcon );
|
||||
if (flags & SHGFI_SHELLICONSIZE)
|
||||
hr = IImageList_GetIcon( icon_list, psfi->iIcon, ILD_NORMAL, &psfi->hIcon );
|
||||
else
|
||||
{
|
||||
int width = GetSystemMetrics( (flags & SHGFI_SMALLICON) ? SM_CXSMICON : SM_CXICON );
|
||||
int height = GetSystemMetrics( (flags & SHGFI_SMALLICON) ? SM_CYSMICON : SM_CYICON );
|
||||
int list_width, list_height;
|
||||
|
||||
IImageList_GetIconSize( icon_list, &list_width, &list_height );
|
||||
if (list_width == width && list_height == height)
|
||||
hr = IImageList_GetIcon( icon_list, psfi->iIcon, ILD_NORMAL, &psfi->hIcon );
|
||||
else /* Use SHIL_SYSSMALL for SHFI_SMALLICONS when we implement it */
|
||||
{
|
||||
WCHAR buf[MAX_PATH], *file = buf;
|
||||
DWORD size = sizeof(buf);
|
||||
int icon_idx;
|
||||
|
||||
while ((hr = SIC_get_location( psfi->iIcon, file, &size, &icon_idx ) == E_NOT_SUFFICIENT_BUFFER))
|
||||
{
|
||||
if (file == buf) file = HeapAlloc( GetProcessHeap(), 0, size );
|
||||
else file = HeapReAlloc( GetProcessHeap(), 0, file, size );
|
||||
if (!file) break;
|
||||
}
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
ret = PrivateExtractIconsW( file, icon_idx, width, height, &psfi->hIcon, 0, 1, 0);
|
||||
if (ret == 0 || ret == (UINT)-1) hr = E_FAIL;
|
||||
}
|
||||
if (file != buf) HeapFree( GetProcessHeap(), 0, file );
|
||||
}
|
||||
}
|
||||
}
|
||||
IImageList_Release( icon_list );
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@ extern CLSID CLSID_ShellImageDataFactory;
|
|||
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;
|
||||
HRESULT SIC_get_location( int list_idx, WCHAR *file, DWORD *size, int *res_idx ) DECLSPEC_HIDDEN;
|
||||
|
||||
/* Classes Root */
|
||||
BOOL HCR_MapTypeToValueW(LPCWSTR szExtension, LPWSTR szFileType, LONG len, BOOL bPrependDot) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -338,11 +338,8 @@ static void check_icon_size( HICON icon, DWORD flags )
|
|||
|
||||
if (flags & SHGFI_SHELLICONSIZE)
|
||||
{
|
||||
todo_wine_if(list_size.cx != metrics_size.cx)
|
||||
{
|
||||
ok( bm.bmWidth == list_size.cx, "got %d expected %d\n", bm.bmWidth, list_size.cx );
|
||||
ok( bm.bmHeight == list_size.cy, "got %d expected %d\n", bm.bmHeight, list_size.cy );
|
||||
}
|
||||
ok( bm.bmWidth == list_size.cx, "got %d expected %d\n", bm.bmWidth, list_size.cx );
|
||||
ok( bm.bmHeight == list_size.cy, "got %d expected %d\n", bm.bmHeight, list_size.cy );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue