2 * shell icon cache (SIC)
4 * Copyright 1998, 1999 Juergen Schmied
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "wine/port.h"
26 #include <sys/types.h>
38 #include "wine/debug.h"
44 #include "shell32_main.h"
45 #include "undocshell.h"
48 WINE_DEFAULT_DEBUG_CHANNEL(shell);
50 /********************** THE ICON CACHE ********************************/
52 #define INVALID_INDEX -1
56 LPWSTR sSourceFile; /* file (not path!) containing the icon */
57 DWORD dwSourceIndex; /* index within the file, if it is a resoure ID it will be negated */
58 DWORD dwListIndex; /* index within the iconlist */
59 DWORD dwFlags; /* GIL_* flags */
61 } SIC_ENTRY, * LPSIC_ENTRY;
63 static HDPA sic_hdpa = 0;
65 static CRITICAL_SECTION SHELL32_SicCS;
66 static CRITICAL_SECTION_DEBUG critsect_debug =
69 { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
70 0, 0, { 0, (DWORD)(__FILE__ ": SHELL32_SicCS") }
72 static CRITICAL_SECTION SHELL32_SicCS = { &critsect_debug, -1, 0, 0, 0, 0 };
74 /*****************************************************************************
78 * Callback for DPA_Search
80 static INT CALLBACK SIC_CompareEntries( LPVOID p1, LPVOID p2, LPARAM lparam)
81 { TRACE("%p %p %8lx\n", p1, p2, lparam);
83 if (((LPSIC_ENTRY)p1)->dwSourceIndex != ((LPSIC_ENTRY)p2)->dwSourceIndex ||
84 ((LPSIC_ENTRY)p1)->dwFlags != ((LPSIC_ENTRY)p2)->dwFlags) /* first the faster one*/
87 if (strcmpiW(((LPSIC_ENTRY)p1)->sSourceFile,((LPSIC_ENTRY)p2)->sSourceFile))
93 /*****************************************************************************
94 * SIC_OverlayShortcutImage [internal]
97 * Creates a new icon as a copy of the passed-in icon, overlayed with a
100 static HICON SIC_OverlayShortcutImage(HICON SourceIcon)
101 { ICONINFO SourceIconInfo, ShortcutIconInfo, TargetIconInfo;
102 HICON ShortcutIcon, TargetIcon;
103 BITMAP SourceBitmapInfo, ShortcutBitmapInfo;
108 HBITMAP OldSourceBitmap = NULL,
109 OldShortcutBitmap = NULL,
110 OldTargetBitmap = NULL;
112 /* Get information about the source icon and shortcut overlay */
113 if (! GetIconInfo(SourceIcon, &SourceIconInfo)
114 || 0 == GetObjectW(SourceIconInfo.hbmColor, sizeof(BITMAP), &SourceBitmapInfo))
118 ShortcutIcon = LoadImageW(shell32_hInstance, MAKEINTRESOURCEW(IDI_SHELL_SHORTCUT),
119 IMAGE_ICON, SourceBitmapInfo.bmWidth, SourceBitmapInfo.bmWidth,
121 if (NULL == ShortcutIcon
122 || ! GetIconInfo(ShortcutIcon, &ShortcutIconInfo)
123 || 0 == GetObjectW(ShortcutIconInfo.hbmColor, sizeof(BITMAP), &ShortcutBitmapInfo))
128 TargetIconInfo = SourceIconInfo;
129 TargetIconInfo.hbmMask = NULL;
130 TargetIconInfo.hbmColor = NULL;
132 /* Setup the source, shortcut and target masks */
133 SourceDC = CreateCompatibleDC(NULL);
134 if (NULL == SourceDC) goto fail;
135 OldSourceBitmap = SelectObject(SourceDC, SourceIconInfo.hbmMask);
136 if (NULL == OldSourceBitmap) goto fail;
138 ShortcutDC = CreateCompatibleDC(NULL);
139 if (NULL == ShortcutDC) goto fail;
140 OldShortcutBitmap = SelectObject(ShortcutDC, ShortcutIconInfo.hbmMask);
141 if (NULL == OldShortcutBitmap) goto fail;
143 TargetDC = CreateCompatibleDC(NULL);
144 if (NULL == TargetDC) goto fail;
145 TargetIconInfo.hbmMask = CreateCompatibleBitmap(TargetDC, SourceBitmapInfo.bmWidth,
146 SourceBitmapInfo.bmHeight);
147 if (NULL == TargetIconInfo.hbmMask) goto fail;
148 ScreenDC = GetDC(NULL);
149 if (NULL == ScreenDC) goto fail;
150 TargetIconInfo.hbmColor = CreateCompatibleBitmap(ScreenDC, SourceBitmapInfo.bmWidth,
151 SourceBitmapInfo.bmHeight);
152 ReleaseDC(NULL, ScreenDC);
153 if (NULL == TargetIconInfo.hbmColor) goto fail;
154 OldTargetBitmap = SelectObject(TargetDC, TargetIconInfo.hbmMask);
155 if (NULL == OldTargetBitmap) goto fail;
157 /* Create the target mask by ANDing the source and shortcut masks */
158 if (! BitBlt(TargetDC, 0, 0, SourceBitmapInfo.bmWidth, SourceBitmapInfo.bmHeight,
159 SourceDC, 0, 0, SRCCOPY) ||
160 ! BitBlt(TargetDC, 0, SourceBitmapInfo.bmHeight - ShortcutBitmapInfo.bmHeight,
161 ShortcutBitmapInfo.bmWidth, ShortcutBitmapInfo.bmHeight,
162 ShortcutDC, 0, 0, SRCAND))
167 /* Setup the source and target xor bitmap */
168 if (NULL == SelectObject(SourceDC, SourceIconInfo.hbmColor) ||
169 NULL == SelectObject(TargetDC, TargetIconInfo.hbmColor))
174 /* Copy the source xor bitmap to the target and clear out part of it by using
176 if (! BitBlt(TargetDC, 0, 0, SourceBitmapInfo.bmWidth, SourceBitmapInfo.bmHeight,
177 SourceDC, 0, 0, SRCCOPY) ||
178 ! BitBlt(TargetDC, 0, SourceBitmapInfo.bmHeight - ShortcutBitmapInfo.bmHeight,
179 ShortcutBitmapInfo.bmWidth, ShortcutBitmapInfo.bmHeight,
180 ShortcutDC, 0, 0, SRCAND))
185 if (NULL == SelectObject(ShortcutDC, ShortcutIconInfo.hbmColor)) goto fail;
187 /* Now put in the shortcut xor mask */
188 if (! BitBlt(TargetDC, 0, SourceBitmapInfo.bmHeight - ShortcutBitmapInfo.bmHeight,
189 ShortcutBitmapInfo.bmWidth, ShortcutBitmapInfo.bmHeight,
190 ShortcutDC, 0, 0, SRCINVERT))
195 /* Clean up, we're not goto'ing to 'fail' after this so we can be lazy and not set
197 SelectObject(TargetDC, OldTargetBitmap);
198 DeleteObject(TargetDC);
199 SelectObject(ShortcutDC, OldShortcutBitmap);
200 DeleteObject(ShortcutDC);
201 SelectObject(SourceDC, OldSourceBitmap);
202 DeleteObject(SourceDC);
204 /* Create the icon using the bitmaps prepared earlier */
205 TargetIcon = CreateIconIndirect(&TargetIconInfo);
207 /* CreateIconIndirect copies the bitmaps, so we can release our bitmaps now */
208 DeleteObject(TargetIconInfo.hbmColor);
209 DeleteObject(TargetIconInfo.hbmMask);
214 /* Clean up scratch resources we created */
215 if (NULL != OldTargetBitmap) SelectObject(TargetDC, OldTargetBitmap);
216 if (NULL != TargetIconInfo.hbmColor) DeleteObject(TargetIconInfo.hbmColor);
217 if (NULL != TargetIconInfo.hbmMask) DeleteObject(TargetIconInfo.hbmMask);
218 if (NULL != TargetDC) DeleteObject(TargetDC);
219 if (NULL != OldShortcutBitmap) SelectObject(ShortcutDC, OldShortcutBitmap);
220 if (NULL != ShortcutDC) DeleteObject(ShortcutDC);
221 if (NULL != OldSourceBitmap) SelectObject(SourceDC, OldSourceBitmap);
222 if (NULL != SourceDC) DeleteObject(SourceDC);
227 /*****************************************************************************
228 * SIC_IconAppend [internal]
231 * appends an icon pair to the end of the cache
233 static INT SIC_IconAppend (LPCWSTR sSourceFile, INT dwSourceIndex, HICON hSmallIcon, HICON hBigIcon, DWORD dwFlags)
234 { LPSIC_ENTRY lpsice;
235 INT ret, index, index1;
236 WCHAR path[MAX_PATH];
237 TRACE("%s %i %p %p\n", debugstr_w(sSourceFile), dwSourceIndex, hSmallIcon ,hBigIcon);
239 lpsice = (LPSIC_ENTRY) SHAlloc (sizeof (SIC_ENTRY));
241 GetFullPathNameW(sSourceFile, MAX_PATH, path, NULL);
242 lpsice->sSourceFile = HeapAlloc( GetProcessHeap(), 0, (strlenW(path)+1)*sizeof(WCHAR) );
243 strcpyW( lpsice->sSourceFile, path );
245 lpsice->dwSourceIndex = dwSourceIndex;
246 lpsice->dwFlags = dwFlags;
248 EnterCriticalSection(&SHELL32_SicCS);
250 index = DPA_InsertPtr(sic_hdpa, 0x7fff, lpsice);
251 if ( INVALID_INDEX == index )
253 HeapFree(GetProcessHeap(), 0, lpsice->sSourceFile);
259 index = ImageList_AddIcon (ShellSmallIconList, hSmallIcon);
260 index1= ImageList_AddIcon (ShellBigIconList, hBigIcon);
264 FIXME("iconlists out of sync 0x%x 0x%x\n", index, index1);
266 lpsice->dwListIndex = index;
267 ret = lpsice->dwListIndex;
270 LeaveCriticalSection(&SHELL32_SicCS);
273 /****************************************************************************
274 * SIC_LoadIcon [internal]
277 * gets small/big icon by number from a file
279 static INT SIC_LoadIcon (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags)
280 { HICON hiconLarge=0;
282 HICON hiconLargeShortcut;
283 HICON hiconSmallShortcut;
285 PrivateExtractIconsW( sSourceFile, dwSourceIndex, 32, 32, &hiconLarge, 0, 1, 0 );
286 PrivateExtractIconsW( sSourceFile, dwSourceIndex, 16, 16, &hiconSmall, 0, 1, 0 );
288 if ( !hiconLarge || !hiconSmall)
290 WARN("failure loading icon %i from %s (%p %p)\n", dwSourceIndex, debugstr_w(sSourceFile), hiconLarge, hiconSmall);
294 if (0 != (dwFlags & GIL_FORSHORTCUT))
296 hiconLargeShortcut = SIC_OverlayShortcutImage(hiconLarge);
297 hiconSmallShortcut = SIC_OverlayShortcutImage(hiconSmall);
298 if (NULL != hiconLargeShortcut && NULL != hiconSmallShortcut)
300 hiconLarge = hiconLargeShortcut;
301 hiconSmall = hiconSmallShortcut;
305 WARN("Failed to create shortcut overlayed icons\n");
306 if (NULL != hiconLargeShortcut) DestroyIcon(hiconLargeShortcut);
307 if (NULL != hiconSmallShortcut) DestroyIcon(hiconSmallShortcut);
308 dwFlags &= ~ GIL_FORSHORTCUT;
312 return SIC_IconAppend (sSourceFile, dwSourceIndex, hiconSmall, hiconLarge, dwFlags);
314 /*****************************************************************************
315 * SIC_GetIconIndex [internal]
318 * sSourceFile [IN] filename of file containing the icon
319 * index [IN] index/resID (negated) in this file
322 * look in the cache for a proper icon. if not available the icon is taken
323 * from the file and cached
325 INT SIC_GetIconIndex (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags )
328 INT ret, index = INVALID_INDEX;
329 WCHAR path[MAX_PATH];
331 TRACE("%s %i\n", debugstr_w(sSourceFile), dwSourceIndex);
333 GetFullPathNameW(sSourceFile, MAX_PATH, path, NULL);
334 sice.sSourceFile = path;
335 sice.dwSourceIndex = dwSourceIndex;
336 sice.dwFlags = dwFlags;
338 EnterCriticalSection(&SHELL32_SicCS);
340 if (NULL != DPA_GetPtr (sic_hdpa, 0))
342 /* search linear from position 0*/
343 index = DPA_Search (sic_hdpa, &sice, 0, SIC_CompareEntries, 0, 0);
346 if ( INVALID_INDEX == index )
348 ret = SIC_LoadIcon (sSourceFile, dwSourceIndex, dwFlags);
353 ret = ((LPSIC_ENTRY)DPA_GetPtr(sic_hdpa, index))->dwListIndex;
356 LeaveCriticalSection(&SHELL32_SicCS);
359 /*****************************************************************************
360 * SIC_Initialize [internal]
363 * hack to load the resources from the shell32.dll under a different dll name
364 * will be removed when the resource-compiler is ready
366 BOOL SIC_Initialize(void)
370 int cx_small, cy_small;
371 int cx_large, cy_large;
373 cx_small = GetSystemMetrics(SM_CXSMICON);
374 cy_small = GetSystemMetrics(SM_CYSMICON);
375 cx_large = GetSystemMetrics(SM_CXICON);
376 cy_large = GetSystemMetrics(SM_CYICON);
380 if (sic_hdpa) /* already initialized?*/
383 sic_hdpa = DPA_Create(16);
390 ShellSmallIconList = ImageList_Create(16,16,ILC_COLOR32|ILC_MASK,0,0x20);
391 ShellBigIconList = ImageList_Create(32,32,ILC_COLOR32|ILC_MASK,0,0x20);
393 ImageList_SetBkColor(ShellSmallIconList, CLR_NONE);
394 ImageList_SetBkColor(ShellBigIconList, CLR_NONE);
396 for (index=1; index<39; index++)
398 hSm = (HICON)LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(index), IMAGE_ICON, cx_small, cy_small, LR_SHARED);
399 hLg = (HICON)LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(index), IMAGE_ICON, cx_large, cy_large, LR_SHARED);
403 hSm = LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(1), IMAGE_ICON, cx_small, cy_small, LR_SHARED);
404 hLg = LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(1), IMAGE_ICON, cx_large, cy_large, LR_SHARED);
406 SIC_IconAppend (swShell32Name, index - 1, hSm, hLg, 0);
407 SIC_IconAppend (swShell32Name, -index, hSm, hLg, 0);
410 TRACE("hIconSmall=%p hIconBig=%p\n",ShellSmallIconList, ShellBigIconList);
414 /*************************************************************************
419 static INT CALLBACK sic_free( LPVOID ptr, LPVOID lparam )
421 HeapFree(GetProcessHeap(), 0, ((LPSIC_ENTRY)ptr)->sSourceFile);
426 void SIC_Destroy(void)
430 EnterCriticalSection(&SHELL32_SicCS);
432 if (sic_hdpa) DPA_DestroyCallback(sic_hdpa, sic_free, NULL );
435 ImageList_Destroy(ShellSmallIconList);
436 ShellSmallIconList = 0;
437 ImageList_Destroy(ShellBigIconList);
438 ShellBigIconList = 0;
440 LeaveCriticalSection(&SHELL32_SicCS);
441 DeleteCriticalSection(&SHELL32_SicCS);
444 /*************************************************************************
445 * Shell_GetImageList [SHELL32.71]
448 * imglist[1|2] [OUT] pointer which receives imagelist handles
451 BOOL WINAPI Shell_GetImageList(HIMAGELIST * lpBigList, HIMAGELIST * lpSmallList)
452 { TRACE("(%p,%p)\n",lpBigList,lpSmallList);
454 { *lpBigList = ShellBigIconList;
457 { *lpSmallList = ShellSmallIconList;
462 /*************************************************************************
463 * PidlToSicIndex [INTERNAL]
466 * sh [IN] IShellFolder
470 * pIndex [OUT] index within the SIC
473 BOOL PidlToSicIndex (
481 WCHAR szIconFile[MAX_PATH]; /* file containing the icon */
482 char szTemp[MAX_PATH];
483 INT iSourceIndex; /* index or resID(negated) in this file */
487 int iShortcutDefaultIndex = INVALID_INDEX;
489 TRACE("sf=%p pidl=%p %s\n", sh, pidl, bBigIcon?"Big":"Small");
491 if (SUCCEEDED (IShellFolder_GetUIObjectOf(sh, 0, 1, &pidl, &IID_IExtractIconW, 0, (void **)&ei)))
493 if (_ILGetExtension(pidl, szTemp, MAX_PATH) &&
494 HCR_MapTypeToValueA(szTemp, szTemp, MAX_PATH, TRUE))
496 if (ERROR_SUCCESS == RegOpenKeyExA(HKEY_CLASSES_ROOT, szTemp, 0, KEY_QUERY_VALUE, &keyCls))
498 if (ERROR_SUCCESS == RegQueryValueExA(keyCls, "IsShortcut", NULL, NULL, NULL, NULL))
500 uFlags |= GIL_FORSHORTCUT;
505 if (SUCCEEDED(IExtractIconW_GetIconLocation(ei, uFlags, szIconFile, MAX_PATH, &iSourceIndex, &dwFlags)))
507 *pIndex = SIC_GetIconIndex(szIconFile, iSourceIndex, uFlags);
510 IExtractIconW_Release(ei);
513 if (INVALID_INDEX == *pIndex) /* default icon when failed */
515 if (0 == (uFlags & GIL_FORSHORTCUT))
521 if (INVALID_INDEX == iShortcutDefaultIndex)
523 iShortcutDefaultIndex = SIC_LoadIcon(swShell32Name, 0, GIL_FORSHORTCUT);
525 *pIndex = (INVALID_INDEX != iShortcutDefaultIndex ? iShortcutDefaultIndex : 0);
533 /*************************************************************************
534 * SHMapPIDLToSystemImageListIndex [SHELL32.77]
537 * sh [IN] pointer to an instance of IShellFolder
539 * pIndex [OUT][OPTIONAL] SIC index for big icon
542 int WINAPI SHMapPIDLToSystemImageListIndex(
549 TRACE("(SF=%p,pidl=%p,%p)\n",sh,pidl,pIndex);
553 PidlToSicIndex ( sh, pidl, 1, 0, pIndex);
554 PidlToSicIndex ( sh, pidl, 0, 0, &Index);
558 /*************************************************************************
559 * Shell_GetCachedImageIndex [SHELL32.72]
562 INT WINAPI Shell_GetCachedImageIndexA(LPCSTR szPath, INT nIndex, BOOL bSimulateDoc)
567 WARN("(%s,%08x,%08x) semi-stub.\n",debugstr_a(szPath), nIndex, bSimulateDoc);
569 len = MultiByteToWideChar( CP_ACP, 0, szPath, -1, NULL, 0 );
570 szTemp = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
571 MultiByteToWideChar( CP_ACP, 0, szPath, -1, szTemp, len );
573 ret = SIC_GetIconIndex( szTemp, nIndex, 0 );
575 HeapFree( GetProcessHeap(), 0, szTemp );
580 INT WINAPI Shell_GetCachedImageIndexW(LPCWSTR szPath, INT nIndex, BOOL bSimulateDoc)
582 WARN("(%s,%08x,%08x) semi-stub.\n",debugstr_w(szPath), nIndex, bSimulateDoc);
584 return SIC_GetIconIndex(szPath, nIndex, 0);
587 INT WINAPI Shell_GetCachedImageIndexAW(LPCVOID szPath, INT nIndex, BOOL bSimulateDoc)
588 { if( SHELL_OsIsUnicode())
589 return Shell_GetCachedImageIndexW(szPath, nIndex, bSimulateDoc);
590 return Shell_GetCachedImageIndexA(szPath, nIndex, bSimulateDoc);
593 /*************************************************************************
594 * ExtractIconExW [SHELL32.@]
597 * -1 file is not valid
598 * or number of icons extracted
600 UINT WINAPI ExtractIconExW(LPCWSTR lpszFile, INT nIconIndex, HICON * phiconLarge, HICON * phiconSmall, UINT nIcons)
602 TRACE("%s %i %p %p %i\n", debugstr_w(lpszFile), nIconIndex, phiconLarge, phiconSmall, nIcons);
604 return PrivateExtractIconExW(lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
607 /*************************************************************************
608 * ExtractIconExA [SHELL32.@]
610 UINT WINAPI ExtractIconExA(LPCSTR lpszFile, INT nIconIndex, HICON * phiconLarge, HICON * phiconSmall, UINT nIcons)
613 INT len = MultiByteToWideChar(CP_ACP, 0, lpszFile, -1, NULL, 0);
614 LPWSTR lpwstrFile = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
616 TRACE("%s %i %p %p %i\n", lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
620 MultiByteToWideChar(CP_ACP, 0, lpszFile, -1, lpwstrFile, len);
621 ret = ExtractIconExW(lpwstrFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
622 HeapFree(GetProcessHeap(), 0, lpwstrFile);
627 /*************************************************************************
628 * ExtractAssociatedIconA (SHELL32.@)
630 * Return icon for given file (either from file itself or from associated
631 * executable) and patch parameters if needed.
633 HICON WINAPI ExtractAssociatedIconA(HINSTANCE hInst, LPSTR lpIconPath, LPWORD lpiIcon)
636 INT len = MultiByteToWideChar(CP_ACP, 0, lpIconPath, -1, NULL, 0);
637 LPWSTR lpIconPathW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
639 TRACE("%p %s %p\n", hInst, debugstr_a(lpIconPath), lpiIcon);
643 MultiByteToWideChar(CP_ACP, 0, lpIconPath, -1, lpIconPathW, len);
644 hIcon = ExtractAssociatedIconW(hInst, lpIconPathW, lpiIcon);
645 HeapFree(GetProcessHeap(), 0, lpIconPathW);
650 HICON WINAPI ExtractAssociatedIconW(HINSTANCE hInst, LPWSTR lpIconPath, LPWORD lpiIcon)
655 TRACE("%p %s %p\n", hInst, debugstr_w(lpIconPath), lpiIcon);
658 lpiIcon = &wDummyIcon;
660 hIcon = ExtractIconW(hInst, lpIconPath, *lpiIcon);
662 if( hIcon < (HICON)2 )
663 { if( hIcon == (HICON)1 ) /* no icons found in given file */
664 { WCHAR tempPath[MAX_PATH];
665 HINSTANCE uRet = FindExecutableW(lpIconPath,NULL,tempPath);
667 if( uRet > (HINSTANCE)32 && tempPath[0] )
668 { lstrcpyW(lpIconPath,tempPath);
669 hIcon = ExtractIconW(hInst, lpIconPath, *lpiIcon);
670 if( hIcon > (HICON)2 )
675 if( hIcon == (HICON)1 )
676 *lpiIcon = 2; /* MSDOS icon - we found .exe but no icons in it */
678 *lpiIcon = 6; /* generic icon - found nothing */
680 if (GetModuleFileNameW(hInst, lpIconPath, MAX_PATH))
681 hIcon = LoadIconW(hInst, MAKEINTRESOURCEW(*lpiIcon));
686 /*************************************************************************
687 * ExtractAssociatedIconExW (SHELL32.@)
689 * Return icon for given file (either from file itself or from associated
690 * executable) and patch parameters if needed.
692 HICON WINAPI ExtractAssociatedIconExW(HINSTANCE hInst, LPWSTR lpIconPath, LPWORD lpiIconIdx, LPWORD lpiIconId)
694 FIXME("%p %s %p %p): stub\n", hInst, debugstr_w(lpIconPath), lpiIconIdx, lpiIconId);
698 /*************************************************************************
699 * ExtractAssociatedIconExA (SHELL32.@)
701 * Return icon for given file (either from file itself or from associated
702 * executable) and patch parameters if needed.
704 HICON WINAPI ExtractAssociatedIconExA(HINSTANCE hInst, LPSTR lpIconPath, LPWORD lpiIconIdx, LPWORD lpiIconId)
707 INT len = MultiByteToWideChar( CP_ACP, 0, lpIconPath, -1, NULL, 0 );
708 LPWSTR lpwstrFile = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
710 TRACE("%p %s %p %p)\n", hInst, lpIconPath, lpiIconIdx, lpiIconId);
712 MultiByteToWideChar( CP_ACP, 0, lpIconPath, -1, lpwstrFile, len );
713 ret = ExtractAssociatedIconExW(hInst, lpwstrFile, lpiIconIdx, lpiIconId);
714 HeapFree(GetProcessHeap(), 0, lpwstrFile);
719 /****************************************************************************
720 * SHDefExtractIconW [SHELL32.@]
722 HRESULT WINAPI SHDefExtractIconW(LPCWSTR pszIconFile, int iIndex, UINT uFlags,
723 HICON* phiconLarge, HICON* phiconSmall, UINT nIconSize)
727 WARN("%s %d 0x%08x %p %p %d, semi-stub\n", debugstr_w(pszIconFile), iIndex, uFlags, phiconLarge, phiconSmall, nIconSize);
729 ret = PrivateExtractIconsW(pszIconFile, iIndex, nIconSize, nIconSize, hIcons, NULL, 2, LR_DEFAULTCOLOR);
730 /* FIXME: deal with uFlags parameter which contains GIL_ flags */
731 if (ret == 0xFFFFFFFF)
734 *phiconLarge = hIcons[0];
735 *phiconSmall = hIcons[1];
741 /****************************************************************************
742 * SHDefExtractIconA [SHELL32.@]
744 HRESULT WINAPI SHDefExtractIconA(LPCSTR pszIconFile, int iIndex, UINT uFlags,
745 HICON* phiconLarge, HICON* phiconSmall, UINT nIconSize)
748 INT len = MultiByteToWideChar(CP_ACP, 0, pszIconFile, -1, NULL, 0);
749 LPWSTR lpwstrFile = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
751 TRACE("%s %d 0x%08x %p %p %d\n", pszIconFile, iIndex, uFlags, phiconLarge, phiconSmall, nIconSize);
753 MultiByteToWideChar(CP_ACP, 0, pszIconFile, -1, lpwstrFile, len);
754 ret = SHDefExtractIconW(lpwstrFile, iIndex, uFlags, phiconLarge, phiconSmall, nIconSize);
755 HeapFree(GetProcessHeap(), 0, lpwstrFile);