Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygeniconcache.cpp
Go to the documentation of this file.
00001 /* 00002 * shell icon cache (SIC) 00003 * 00004 * Copyright 1998, 1999 Juergen Schmied 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00019 */ 00020 00021 #include <precomp.h> 00022 00023 WINE_DEFAULT_DEBUG_CHANNEL(shell); 00024 00025 /********************** THE ICON CACHE ********************************/ 00026 00027 #define INVALID_INDEX -1 00028 00029 typedef struct 00030 { 00031 LPWSTR sSourceFile; /* file (not path!) containing the icon */ 00032 DWORD dwSourceIndex; /* index within the file, if it is a resoure ID it will be negated */ 00033 DWORD dwListIndex; /* index within the iconlist */ 00034 DWORD dwFlags; /* GIL_* flags */ 00035 DWORD dwAccessTime; 00036 } SIC_ENTRY, * LPSIC_ENTRY; 00037 00038 static HDPA sic_hdpa = 0; 00039 00040 namespace 00041 { 00042 extern CRITICAL_SECTION SHELL32_SicCS; 00043 CRITICAL_SECTION_DEBUG critsect_debug = 00044 { 00045 0, 0, &SHELL32_SicCS, 00046 { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList }, 00047 0, 0, { (DWORD_PTR)(__FILE__ ": SHELL32_SicCS") } 00048 }; 00049 CRITICAL_SECTION SHELL32_SicCS = { &critsect_debug, -1, 0, 0, 0, 0 }; 00050 } 00051 00052 /***************************************************************************** 00053 * SIC_CompareEntries 00054 * 00055 * NOTES 00056 * Callback for DPA_Search 00057 */ 00058 static INT CALLBACK SIC_CompareEntries( LPVOID p1, LPVOID p2, LPARAM lparam) 00059 { LPSIC_ENTRY e1 = (LPSIC_ENTRY)p1, e2 = (LPSIC_ENTRY)p2; 00060 00061 TRACE("%p %p %8lx\n", p1, p2, lparam); 00062 00063 /* Icons in the cache are keyed by the name of the file they are 00064 * loaded from, their resource index and the fact if they have a shortcut 00065 * icon overlay or not. 00066 */ 00067 if (e1->dwSourceIndex != e2->dwSourceIndex || /* first the faster one */ 00068 (e1->dwFlags & GIL_FORSHORTCUT) != (e2->dwFlags & GIL_FORSHORTCUT)) 00069 return 1; 00070 00071 if (wcsicmp(e1->sSourceFile,e2->sSourceFile)) 00072 return 1; 00073 00074 return 0; 00075 } 00076 00077 /* declare SIC_LoadOverlayIcon() */ 00078 static int SIC_LoadOverlayIcon(int icon_idx); 00079 00080 /***************************************************************************** 00081 * SIC_OverlayShortcutImage [internal] 00082 * 00083 * NOTES 00084 * Creates a new icon as a copy of the passed-in icon, overlayed with a 00085 * shortcut image. 00086 */ 00087 static HICON SIC_OverlayShortcutImage(HICON SourceIcon, BOOL large) 00088 { ICONINFO SourceIconInfo, ShortcutIconInfo, TargetIconInfo; 00089 HICON ShortcutIcon, TargetIcon; 00090 BITMAP SourceBitmapInfo, ShortcutBitmapInfo; 00091 HDC SourceDC = NULL, 00092 ShortcutDC = NULL, 00093 TargetDC = NULL, 00094 ScreenDC = NULL; 00095 HBITMAP OldSourceBitmap = NULL, 00096 OldShortcutBitmap = NULL, 00097 OldTargetBitmap = NULL; 00098 00099 static int s_imgListIdx = -1; 00100 00101 /* Get information about the source icon and shortcut overlay */ 00102 if (! GetIconInfo(SourceIcon, &SourceIconInfo) 00103 || 0 == GetObjectW(SourceIconInfo.hbmColor, sizeof(BITMAP), &SourceBitmapInfo)) 00104 { 00105 return NULL; 00106 } 00107 00108 /* search for the shortcut icon only once */ 00109 if (s_imgListIdx == -1) 00110 s_imgListIdx = SIC_LoadOverlayIcon(- IDI_SHELL_SHORTCUT); 00111 /* FIXME should use icon index 29 instead of the 00112 resource id, but not all icons are present yet 00113 so we can't use icon indices */ 00114 00115 if (s_imgListIdx != -1) 00116 { 00117 if (large) 00118 ShortcutIcon = ImageList_GetIcon(ShellBigIconList, s_imgListIdx, ILD_TRANSPARENT); 00119 else 00120 ShortcutIcon = ImageList_GetIcon(ShellSmallIconList, s_imgListIdx, ILD_TRANSPARENT); 00121 } else 00122 ShortcutIcon = NULL; 00123 00124 if (NULL == ShortcutIcon 00125 || ! GetIconInfo(ShortcutIcon, &ShortcutIconInfo) 00126 || 0 == GetObjectW(ShortcutIconInfo.hbmColor, sizeof(BITMAP), &ShortcutBitmapInfo)) 00127 { 00128 return NULL; 00129 } 00130 00131 TargetIconInfo = SourceIconInfo; 00132 TargetIconInfo.hbmMask = NULL; 00133 TargetIconInfo.hbmColor = NULL; 00134 00135 /* Setup the source, shortcut and target masks */ 00136 SourceDC = CreateCompatibleDC(NULL); 00137 if (NULL == SourceDC) goto fail; 00138 OldSourceBitmap = (HBITMAP)SelectObject(SourceDC, SourceIconInfo.hbmMask); 00139 if (NULL == OldSourceBitmap) goto fail; 00140 00141 ShortcutDC = CreateCompatibleDC(NULL); 00142 if (NULL == ShortcutDC) goto fail; 00143 OldShortcutBitmap = (HBITMAP)SelectObject(ShortcutDC, ShortcutIconInfo.hbmMask); 00144 if (NULL == OldShortcutBitmap) goto fail; 00145 00146 TargetDC = CreateCompatibleDC(NULL); 00147 if (NULL == TargetDC) goto fail; 00148 TargetIconInfo.hbmMask = CreateCompatibleBitmap(TargetDC, SourceBitmapInfo.bmWidth, 00149 SourceBitmapInfo.bmHeight); 00150 if (NULL == TargetIconInfo.hbmMask) goto fail; 00151 ScreenDC = GetDC(NULL); 00152 if (NULL == ScreenDC) goto fail; 00153 TargetIconInfo.hbmColor = CreateCompatibleBitmap(ScreenDC, SourceBitmapInfo.bmWidth, 00154 SourceBitmapInfo.bmHeight); 00155 ReleaseDC(NULL, ScreenDC); 00156 if (NULL == TargetIconInfo.hbmColor) goto fail; 00157 OldTargetBitmap = (HBITMAP)SelectObject(TargetDC, TargetIconInfo.hbmMask); 00158 if (NULL == OldTargetBitmap) goto fail; 00159 00160 /* Create the target mask by ANDing the source and shortcut masks */ 00161 if (! BitBlt(TargetDC, 0, 0, SourceBitmapInfo.bmWidth, SourceBitmapInfo.bmHeight, 00162 SourceDC, 0, 0, SRCCOPY) || 00163 ! BitBlt(TargetDC, 0, SourceBitmapInfo.bmHeight - ShortcutBitmapInfo.bmHeight, 00164 ShortcutBitmapInfo.bmWidth, ShortcutBitmapInfo.bmHeight, 00165 ShortcutDC, 0, 0, SRCAND)) 00166 { 00167 goto fail; 00168 } 00169 00170 /* Setup the source and target xor bitmap */ 00171 if (NULL == SelectObject(SourceDC, SourceIconInfo.hbmColor) || 00172 NULL == SelectObject(TargetDC, TargetIconInfo.hbmColor)) 00173 { 00174 goto fail; 00175 } 00176 00177 /* Copy the source color bitmap to the target */ 00178 if (! BitBlt(TargetDC, 0, 0, SourceBitmapInfo.bmWidth, SourceBitmapInfo.bmHeight, 00179 SourceDC, 0, 0, SRCCOPY)) goto fail; 00180 00181 /* Copy the source xor bitmap to the target and clear out part of it by using 00182 the shortcut mask */ 00183 if (NULL == SelectObject(ShortcutDC, ShortcutIconInfo.hbmColor)) goto fail; 00184 if (!MaskBlt(TargetDC, 0, SourceBitmapInfo.bmHeight - ShortcutBitmapInfo.bmHeight, 00185 ShortcutBitmapInfo.bmWidth, ShortcutBitmapInfo.bmHeight, 00186 ShortcutDC, 0, 0, ShortcutIconInfo.hbmMask, 0, 0, 00187 MAKEROP4(0xAA0000, SRCCOPY))) 00188 { 00189 goto fail; 00190 } 00191 00192 /* Clean up, we're not goto'ing to 'fail' after this so we can be lazy and not set 00193 handles to NULL */ 00194 SelectObject(TargetDC, OldTargetBitmap); 00195 DeleteObject(TargetDC); 00196 SelectObject(ShortcutDC, OldShortcutBitmap); 00197 DeleteObject(ShortcutDC); 00198 SelectObject(SourceDC, OldSourceBitmap); 00199 DeleteObject(SourceDC); 00200 00201 /* Create the icon using the bitmaps prepared earlier */ 00202 TargetIcon = CreateIconIndirect(&TargetIconInfo); 00203 00204 /* CreateIconIndirect copies the bitmaps, so we can release our bitmaps now */ 00205 DeleteObject(TargetIconInfo.hbmColor); 00206 DeleteObject(TargetIconInfo.hbmMask); 00207 00208 return TargetIcon; 00209 00210 fail: 00211 /* Clean up scratch resources we created */ 00212 if (NULL != OldTargetBitmap) SelectObject(TargetDC, OldTargetBitmap); 00213 if (NULL != TargetIconInfo.hbmColor) DeleteObject(TargetIconInfo.hbmColor); 00214 if (NULL != TargetIconInfo.hbmMask) DeleteObject(TargetIconInfo.hbmMask); 00215 if (NULL != TargetDC) DeleteObject(TargetDC); 00216 if (NULL != OldShortcutBitmap) SelectObject(ShortcutDC, OldShortcutBitmap); 00217 if (NULL != ShortcutDC) DeleteObject(ShortcutDC); 00218 if (NULL != OldSourceBitmap) SelectObject(SourceDC, OldSourceBitmap); 00219 if (NULL != SourceDC) DeleteObject(SourceDC); 00220 00221 return NULL; 00222 } 00223 00224 /***************************************************************************** 00225 * SIC_IconAppend [internal] 00226 * 00227 * NOTES 00228 * appends an icon pair to the end of the cache 00229 */ 00230 static INT SIC_IconAppend (LPCWSTR sSourceFile, INT dwSourceIndex, HICON hSmallIcon, HICON hBigIcon, DWORD dwFlags) 00231 { LPSIC_ENTRY lpsice; 00232 INT ret, index, index1; 00233 WCHAR path[MAX_PATH]; 00234 TRACE("%s %i %p %p\n", debugstr_w(sSourceFile), dwSourceIndex, hSmallIcon ,hBigIcon); 00235 00236 lpsice = (LPSIC_ENTRY) SHAlloc (sizeof (SIC_ENTRY)); 00237 00238 GetFullPathNameW(sSourceFile, MAX_PATH, path, NULL); 00239 lpsice->sSourceFile = (LPWSTR)HeapAlloc( GetProcessHeap(), 0, (wcslen(path)+1)*sizeof(WCHAR) ); 00240 wcscpy( lpsice->sSourceFile, path ); 00241 00242 lpsice->dwSourceIndex = dwSourceIndex; 00243 lpsice->dwFlags = dwFlags; 00244 00245 EnterCriticalSection(&SHELL32_SicCS); 00246 00247 index = DPA_InsertPtr(sic_hdpa, 0x7fff, lpsice); 00248 if ( INVALID_INDEX == index ) 00249 { 00250 HeapFree(GetProcessHeap(), 0, lpsice->sSourceFile); 00251 SHFree(lpsice); 00252 ret = INVALID_INDEX; 00253 } 00254 else 00255 { 00256 index = ImageList_AddIcon (ShellSmallIconList, hSmallIcon); 00257 index1= ImageList_AddIcon (ShellBigIconList, hBigIcon); 00258 00259 if (index!=index1) 00260 { 00261 FIXME("iconlists out of sync 0x%x 0x%x\n", index, index1); 00262 } 00263 lpsice->dwListIndex = index; 00264 ret = lpsice->dwListIndex; 00265 } 00266 00267 LeaveCriticalSection(&SHELL32_SicCS); 00268 return ret; 00269 } 00270 /**************************************************************************** 00271 * SIC_LoadIcon [internal] 00272 * 00273 * NOTES 00274 * gets small/big icon by number from a file 00275 */ 00276 static INT SIC_LoadIcon (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags) 00277 { HICON hiconLarge=0; 00278 HICON hiconSmall=0; 00279 HICON hiconLargeShortcut; 00280 HICON hiconSmallShortcut; 00281 00282 #if defined(__CYGWIN__) || defined (__MINGW32__) || defined(_MSC_VER) 00283 static UINT (WINAPI*PrivateExtractIconExW)(LPCWSTR,int,HICON*,HICON*,UINT) = NULL; 00284 00285 if (!PrivateExtractIconExW) { 00286 HMODULE hUser32 = GetModuleHandleA("user32"); 00287 PrivateExtractIconExW = (UINT(WINAPI*)(LPCWSTR,int,HICON*,HICON*,UINT)) GetProcAddress(hUser32, "PrivateExtractIconExW"); 00288 } 00289 00290 if (PrivateExtractIconExW) 00291 PrivateExtractIconExW(sSourceFile, dwSourceIndex, &hiconLarge, &hiconSmall, 1); 00292 else 00293 #endif 00294 { 00295 PrivateExtractIconsW(sSourceFile, dwSourceIndex, 32, 32, &hiconLarge, NULL, 1, 0); 00296 PrivateExtractIconsW(sSourceFile, dwSourceIndex, 16, 16, &hiconSmall, NULL, 1, 0); 00297 } 00298 00299 if ( !hiconLarge || !hiconSmall) 00300 { 00301 WARN("failure loading icon %i from %s (%p %p)\n", dwSourceIndex, debugstr_w(sSourceFile), hiconLarge, hiconSmall); 00302 return -1; 00303 } 00304 00305 if (0 != (dwFlags & GIL_FORSHORTCUT)) 00306 { 00307 hiconLargeShortcut = SIC_OverlayShortcutImage(hiconLarge, TRUE); 00308 hiconSmallShortcut = SIC_OverlayShortcutImage(hiconSmall, FALSE); 00309 if (NULL != hiconLargeShortcut && NULL != hiconSmallShortcut) 00310 { 00311 hiconLarge = hiconLargeShortcut; 00312 hiconSmall = hiconSmallShortcut; 00313 } 00314 else 00315 { 00316 WARN("Failed to create shortcut overlayed icons\n"); 00317 if (NULL != hiconLargeShortcut) DestroyIcon(hiconLargeShortcut); 00318 if (NULL != hiconSmallShortcut) DestroyIcon(hiconSmallShortcut); 00319 dwFlags &= ~ GIL_FORSHORTCUT; 00320 } 00321 } 00322 00323 return SIC_IconAppend (sSourceFile, dwSourceIndex, hiconSmall, hiconLarge, dwFlags); 00324 } 00325 /***************************************************************************** 00326 * SIC_GetIconIndex [internal] 00327 * 00328 * Parameters 00329 * sSourceFile [IN] filename of file containing the icon 00330 * index [IN] index/resID (negated) in this file 00331 * 00332 * NOTES 00333 * look in the cache for a proper icon. if not available the icon is taken 00334 * from the file and cached 00335 */ 00336 INT SIC_GetIconIndex (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags ) 00337 { 00338 SIC_ENTRY sice; 00339 INT ret, index = INVALID_INDEX; 00340 WCHAR path[MAX_PATH]; 00341 00342 TRACE("%s %i\n", debugstr_w(sSourceFile), dwSourceIndex); 00343 00344 GetFullPathNameW(sSourceFile, MAX_PATH, path, NULL); 00345 sice.sSourceFile = path; 00346 sice.dwSourceIndex = dwSourceIndex; 00347 sice.dwFlags = dwFlags; 00348 00349 EnterCriticalSection(&SHELL32_SicCS); 00350 00351 if (NULL != DPA_GetPtr (sic_hdpa, 0)) 00352 { 00353 /* search linear from position 0*/ 00354 index = DPA_Search (sic_hdpa, &sice, 0, SIC_CompareEntries, 0, 0); 00355 } 00356 00357 if ( INVALID_INDEX == index ) 00358 { 00359 ret = SIC_LoadIcon (sSourceFile, dwSourceIndex, dwFlags); 00360 } 00361 else 00362 { 00363 TRACE("-- found\n"); 00364 ret = ((LPSIC_ENTRY)DPA_GetPtr(sic_hdpa, index))->dwListIndex; 00365 } 00366 00367 LeaveCriticalSection(&SHELL32_SicCS); 00368 return ret; 00369 } 00370 /***************************************************************************** 00371 * SIC_Initialize [internal] 00372 */ 00373 BOOL SIC_Initialize(void) 00374 { 00375 HICON hSm = NULL, hLg = NULL; 00376 INT cx_small, cy_small; 00377 INT cx_large, cy_large; 00378 HDC hDC; 00379 INT bpp; 00380 DWORD ilMask; 00381 00382 TRACE("Entered SIC_Initialize\n"); 00383 00384 if (sic_hdpa) 00385 { 00386 TRACE("Icon cache already initialized\n"); 00387 return TRUE; 00388 } 00389 00390 sic_hdpa = DPA_Create(16); 00391 if (!sic_hdpa) 00392 { 00393 return FALSE; 00394 } 00395 00396 hDC = CreateICW(L"DISPLAY", NULL, NULL, NULL); 00397 if (!hDC) 00398 { 00399 ERR("Failed to create information context (error %d)\n", GetLastError()); 00400 return FALSE; 00401 } 00402 00403 bpp = GetDeviceCaps(hDC, BITSPIXEL); 00404 ReleaseDC(NULL, hDC); 00405 00406 if (bpp <= 4) 00407 ilMask = ILC_COLOR4; 00408 else if (bpp <= 8) 00409 ilMask = ILC_COLOR8; 00410 else if (bpp <= 16) 00411 ilMask = ILC_COLOR16; 00412 else if (bpp <= 24) 00413 ilMask = ILC_COLOR24; 00414 else if (bpp <= 32) 00415 ilMask = ILC_COLOR32; 00416 else 00417 ilMask = ILC_COLOR; 00418 00419 ilMask |= ILC_MASK; 00420 00421 cx_small = GetSystemMetrics(SM_CXSMICON); 00422 cy_small = GetSystemMetrics(SM_CYSMICON); 00423 cx_large = GetSystemMetrics(SM_CXICON); 00424 cy_large = GetSystemMetrics(SM_CYICON); 00425 00426 ShellSmallIconList = ImageList_Create(cx_small, 00427 cy_small, 00428 ilMask, 00429 100, 00430 100); 00431 00432 ShellBigIconList = ImageList_Create(cx_large, 00433 cy_large, 00434 ilMask, 00435 100, 00436 100); 00437 if (ShellSmallIconList) 00438 { 00439 /* Load the document icon, which is used as the default if an icon isn't found. */ 00440 hSm = (HICON)LoadImageW(shell32_hInstance, 00441 MAKEINTRESOURCEW(IDI_SHELL_DOCUMENT), 00442 IMAGE_ICON, 00443 cx_small, 00444 cy_small, 00445 LR_SHARED | LR_DEFAULTCOLOR); 00446 if (!hSm) 00447 { 00448 ERR("Failed to load IDI_SHELL_DOCUMENT icon1!\n"); 00449 return FALSE; 00450 } 00451 } 00452 else 00453 { 00454 ERR("Failed to load ShellSmallIconList\n"); 00455 return FALSE; 00456 } 00457 00458 if (ShellBigIconList) 00459 { 00460 hLg = (HICON)LoadImageW(shell32_hInstance, 00461 MAKEINTRESOURCEW(IDI_SHELL_DOCUMENT), 00462 IMAGE_ICON, 00463 cx_large, 00464 cy_large, 00465 LR_SHARED | LR_DEFAULTCOLOR); 00466 if (!hLg) 00467 { 00468 ERR("Failed to load IDI_SHELL_DOCUMENT icon2!\n"); 00469 DestroyIcon(hSm); 00470 return FALSE; 00471 } 00472 } 00473 else 00474 { 00475 ERR("Failed to load ShellBigIconList\n"); 00476 return FALSE; 00477 } 00478 00479 SIC_IconAppend(swShell32Name, IDI_SHELL_DOCUMENT-1, hSm, hLg, 0); 00480 SIC_IconAppend(swShell32Name, -IDI_SHELL_DOCUMENT, hSm, hLg, 0); 00481 00482 TRACE("hIconSmall=%p hIconBig=%p\n",ShellSmallIconList, ShellBigIconList); 00483 00484 return TRUE; 00485 } 00486 /************************************************************************* 00487 * SIC_Destroy 00488 * 00489 * frees the cache 00490 */ 00491 static INT CALLBACK sic_free( LPVOID ptr, LPVOID lparam ) 00492 { 00493 HeapFree(GetProcessHeap(), 0, ((LPSIC_ENTRY)ptr)->sSourceFile); 00494 SHFree(ptr); 00495 return TRUE; 00496 } 00497 00498 void SIC_Destroy(void) 00499 { 00500 TRACE("\n"); 00501 00502 EnterCriticalSection(&SHELL32_SicCS); 00503 00504 if (sic_hdpa) DPA_DestroyCallback(sic_hdpa, sic_free, NULL ); 00505 00506 sic_hdpa = NULL; 00507 ImageList_Destroy(ShellSmallIconList); 00508 ShellSmallIconList = 0; 00509 ImageList_Destroy(ShellBigIconList); 00510 ShellBigIconList = 0; 00511 00512 LeaveCriticalSection(&SHELL32_SicCS); 00513 //DeleteCriticalSection(&SHELL32_SicCS); //static 00514 } 00515 00516 /***************************************************************************** 00517 * SIC_LoadOverlayIcon [internal] 00518 * 00519 * Load a shell overlay icon and return its icon cache index. 00520 */ 00521 static int SIC_LoadOverlayIcon(int icon_idx) 00522 { 00523 WCHAR buffer[1024], wszIdx[8]; 00524 HKEY hKeyShellIcons; 00525 LPCWSTR iconPath; 00526 int iconIdx; 00527 00528 static const WCHAR wszShellIcons[] = { 00529 'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\', 00530 'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', 00531 'E','x','p','l','o','r','e','r','\\','S','h','e','l','l',' ','I','c','o','n','s',0 00532 }; 00533 static const WCHAR wszNumFmt[] = {'%','d',0}; 00534 00535 iconPath = swShell32Name; /* default: load icon from shell32.dll */ 00536 iconIdx = icon_idx; 00537 00538 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, wszShellIcons, 0, KEY_READ, &hKeyShellIcons) == ERROR_SUCCESS) 00539 { 00540 DWORD count = sizeof(buffer); 00541 00542 swprintf(wszIdx, wszNumFmt, icon_idx); 00543 00544 /* read icon path and index */ 00545 if (RegQueryValueExW(hKeyShellIcons, wszIdx, NULL, NULL, (LPBYTE)buffer, &count) == ERROR_SUCCESS) 00546 { 00547 LPWSTR p = wcschr(buffer, ','); 00548 00549 if (p) 00550 *p++ = 0; 00551 00552 iconPath = buffer; 00553 iconIdx = _wtoi(p); 00554 } 00555 00556 RegCloseKey(hKeyShellIcons); 00557 } 00558 00559 return SIC_LoadIcon(iconPath, iconIdx, 0); 00560 } 00561 00562 /************************************************************************* 00563 * Shell_GetImageLists [SHELL32.71] 00564 * 00565 * PARAMETERS 00566 * imglist[1|2] [OUT] pointer which receives imagelist handles 00567 * 00568 */ 00569 BOOL WINAPI Shell_GetImageLists(HIMAGELIST * lpBigList, HIMAGELIST * lpSmallList) 00570 { TRACE("(%p,%p)\n",lpBigList,lpSmallList); 00571 if (lpBigList) 00572 { *lpBigList = ShellBigIconList; 00573 } 00574 if (lpSmallList) 00575 { *lpSmallList = ShellSmallIconList; 00576 } 00577 00578 return TRUE; 00579 } 00580 /************************************************************************* 00581 * PidlToSicIndex [INTERNAL] 00582 * 00583 * PARAMETERS 00584 * sh [IN] IShellFolder 00585 * pidl [IN] 00586 * bBigIcon [IN] 00587 * uFlags [IN] GIL_* 00588 * pIndex [OUT] index within the SIC 00589 * 00590 */ 00591 BOOL PidlToSicIndex ( 00592 IShellFolder * sh, 00593 LPCITEMIDLIST pidl, 00594 BOOL bBigIcon, 00595 UINT uFlags, 00596 int * pIndex) 00597 { 00598 CComPtr<IExtractIconW> ei; 00599 WCHAR szIconFile[MAX_PATH]; /* file containing the icon */ 00600 INT iSourceIndex; /* index or resID(negated) in this file */ 00601 BOOL ret = FALSE; 00602 UINT dwFlags = 0; 00603 int iShortcutDefaultIndex = INVALID_INDEX; 00604 00605 TRACE("sf=%p pidl=%p %s\n", sh, pidl, bBigIcon?"Big":"Small"); 00606 00607 if (SUCCEEDED (sh->GetUIObjectOf(0, 1, &pidl, IID_IExtractIconW, 0, (void **)&ei))) 00608 { 00609 if (SUCCEEDED(ei->GetIconLocation(uFlags, szIconFile, MAX_PATH, &iSourceIndex, &dwFlags))) 00610 { 00611 *pIndex = SIC_GetIconIndex(szIconFile, iSourceIndex, uFlags); 00612 ret = TRUE; 00613 } 00614 } 00615 00616 if (INVALID_INDEX == *pIndex) /* default icon when failed */ 00617 { 00618 if (0 == (uFlags & GIL_FORSHORTCUT)) 00619 { 00620 *pIndex = 0; 00621 } 00622 else 00623 { 00624 if (INVALID_INDEX == iShortcutDefaultIndex) 00625 { 00626 iShortcutDefaultIndex = SIC_LoadIcon(swShell32Name, 0, GIL_FORSHORTCUT); 00627 } 00628 *pIndex = (INVALID_INDEX != iShortcutDefaultIndex ? iShortcutDefaultIndex : 0); 00629 } 00630 } 00631 00632 return ret; 00633 00634 } 00635 00636 /************************************************************************* 00637 * SHMapPIDLToSystemImageListIndex [SHELL32.77] 00638 * 00639 * PARAMETERS 00640 * sh [IN] pointer to an instance of IShellFolder 00641 * pidl [IN] 00642 * pIndex [OUT][OPTIONAL] SIC index for big icon 00643 * 00644 */ 00645 int WINAPI SHMapPIDLToSystemImageListIndex( 00646 IShellFolder *sh, 00647 LPCITEMIDLIST pidl, 00648 int *pIndex) 00649 { 00650 int Index; 00651 UINT uGilFlags = 0; 00652 00653 TRACE("(SF=%p,pidl=%p,%p)\n",sh,pidl,pIndex); 00654 pdump(pidl); 00655 00656 if (SHELL_IsShortcut(pidl)) 00657 uGilFlags |= GIL_FORSHORTCUT; 00658 00659 if (pIndex) 00660 if (!PidlToSicIndex ( sh, pidl, 1, uGilFlags, pIndex)) 00661 *pIndex = -1; 00662 00663 if (!PidlToSicIndex ( sh, pidl, 0, uGilFlags, &Index)) 00664 return -1; 00665 00666 return Index; 00667 } 00668 00669 /************************************************************************* 00670 * SHMapIDListToImageListIndexAsync [SHELL32.148] 00671 */ 00672 EXTERN_C HRESULT WINAPI SHMapIDListToImageListIndexAsync(IShellTaskScheduler *pts, IShellFolder *psf, 00673 LPCITEMIDLIST pidl, UINT flags, 00674 PFNASYNCICONTASKBALLBACK pfn, void *pvData, void *pvHint, 00675 int *piIndex, int *piIndexSel) 00676 { 00677 FIXME("(%p, %p, %p, 0x%08x, %p, %p, %p, %p, %p)\n", 00678 pts, psf, pidl, flags, pfn, pvData, pvHint, piIndex, piIndexSel); 00679 return E_FAIL; 00680 } 00681 00682 /************************************************************************* 00683 * Shell_GetCachedImageIndex [SHELL32.72] 00684 * 00685 */ 00686 INT WINAPI Shell_GetCachedImageIndexA(LPCSTR szPath, INT nIndex, UINT bSimulateDoc) 00687 { 00688 INT ret, len; 00689 LPWSTR szTemp; 00690 00691 WARN("(%s,%08x,%08x) semi-stub.\n",debugstr_a(szPath), nIndex, bSimulateDoc); 00692 00693 len = MultiByteToWideChar( CP_ACP, 0, szPath, -1, NULL, 0 ); 00694 szTemp = (LPWSTR)HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ); 00695 MultiByteToWideChar( CP_ACP, 0, szPath, -1, szTemp, len ); 00696 00697 ret = SIC_GetIconIndex( szTemp, nIndex, 0 ); 00698 00699 HeapFree( GetProcessHeap(), 0, szTemp ); 00700 00701 return ret; 00702 } 00703 00704 INT WINAPI Shell_GetCachedImageIndexW(LPCWSTR szPath, INT nIndex, UINT bSimulateDoc) 00705 { 00706 WARN("(%s,%08x,%08x) semi-stub.\n",debugstr_w(szPath), nIndex, bSimulateDoc); 00707 00708 return SIC_GetIconIndex(szPath, nIndex, 0); 00709 } 00710 00711 EXTERN_C INT WINAPI Shell_GetCachedImageIndexAW(LPCVOID szPath, INT nIndex, BOOL bSimulateDoc) 00712 { if( SHELL_OsIsUnicode()) 00713 return Shell_GetCachedImageIndexW((LPCWSTR)szPath, nIndex, bSimulateDoc); 00714 return Shell_GetCachedImageIndexA((LPCSTR)szPath, nIndex, bSimulateDoc); 00715 } 00716 00717 /************************************************************************* 00718 * ExtractIconExW [SHELL32.@] 00719 * RETURNS 00720 * 0 no icon found 00721 * -1 file is not valid 00722 * or number of icons extracted 00723 */ 00724 UINT WINAPI ExtractIconExW(LPCWSTR lpszFile, INT nIconIndex, HICON * phiconLarge, HICON * phiconSmall, UINT nIcons) 00725 { 00726 /* get entry point of undocumented function PrivateExtractIconExW() in user32 */ 00727 #if defined(__CYGWIN__) || defined (__MINGW32__) || defined(_MSC_VER) 00728 static UINT (WINAPI*PrivateExtractIconExW)(LPCWSTR,int,HICON*,HICON*,UINT) = NULL; 00729 00730 if (!PrivateExtractIconExW) { 00731 HMODULE hUser32 = GetModuleHandleA("user32"); 00732 PrivateExtractIconExW = (UINT(WINAPI*)(LPCWSTR,int,HICON*,HICON*,UINT)) GetProcAddress(hUser32, "PrivateExtractIconExW"); 00733 00734 if (!PrivateExtractIconExW) 00735 return 0; 00736 } 00737 #endif 00738 00739 TRACE("%s %i %p %p %i\n", debugstr_w(lpszFile), nIconIndex, phiconLarge, phiconSmall, nIcons); 00740 00741 return PrivateExtractIconExW(lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons); 00742 } 00743 00744 /************************************************************************* 00745 * ExtractIconExA [SHELL32.@] 00746 */ 00747 UINT WINAPI ExtractIconExA(LPCSTR lpszFile, INT nIconIndex, HICON * phiconLarge, HICON * phiconSmall, UINT nIcons) 00748 { 00749 UINT ret = 0; 00750 INT len = MultiByteToWideChar(CP_ACP, 0, lpszFile, -1, NULL, 0); 00751 LPWSTR lpwstrFile = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); 00752 00753 TRACE("%s %i %p %p %i\n", lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons); 00754 00755 if (lpwstrFile) 00756 { 00757 MultiByteToWideChar(CP_ACP, 0, lpszFile, -1, lpwstrFile, len); 00758 ret = ExtractIconExW(lpwstrFile, nIconIndex, phiconLarge, phiconSmall, nIcons); 00759 HeapFree(GetProcessHeap(), 0, lpwstrFile); 00760 } 00761 return ret; 00762 } 00763 00764 /************************************************************************* 00765 * ExtractAssociatedIconA (SHELL32.@) 00766 * 00767 * Return icon for given file (either from file itself or from associated 00768 * executable) and patch parameters if needed. 00769 */ 00770 HICON WINAPI ExtractAssociatedIconA(HINSTANCE hInst, LPSTR lpIconPath, LPWORD lpiIcon) 00771 { 00772 HICON hIcon = NULL; 00773 INT len = MultiByteToWideChar(CP_ACP, 0, lpIconPath, -1, NULL, 0); 00774 /* Note that we need to allocate MAX_PATH, since we are supposed to fill 00775 * the correct executable if there is no icon in lpIconPath directly. 00776 * lpIconPath itself is supposed to be large enough, so make sure lpIconPathW 00777 * is large enough too. Yes, I am puking too. 00778 */ 00779 LPWSTR lpIconPathW = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR)); 00780 00781 TRACE("%p %s %p\n", hInst, debugstr_a(lpIconPath), lpiIcon); 00782 00783 if (lpIconPathW) 00784 { 00785 MultiByteToWideChar(CP_ACP, 0, lpIconPath, -1, lpIconPathW, len); 00786 hIcon = ExtractAssociatedIconW(hInst, lpIconPathW, lpiIcon); 00787 WideCharToMultiByte(CP_ACP, 0, lpIconPathW, -1, lpIconPath, MAX_PATH , NULL, NULL); 00788 HeapFree(GetProcessHeap(), 0, lpIconPathW); 00789 } 00790 return hIcon; 00791 } 00792 00793 /************************************************************************* 00794 * ExtractAssociatedIconW (SHELL32.@) 00795 * 00796 * Return icon for given file (either from file itself or from associated 00797 * executable) and patch parameters if needed. 00798 */ 00799 HICON WINAPI ExtractAssociatedIconW(HINSTANCE hInst, LPWSTR lpIconPath, LPWORD lpiIcon) 00800 { 00801 HICON hIcon = NULL; 00802 WORD wDummyIcon = 0; 00803 00804 TRACE("%p %s %p\n", hInst, debugstr_w(lpIconPath), lpiIcon); 00805 00806 if(lpiIcon == NULL) 00807 lpiIcon = &wDummyIcon; 00808 00809 hIcon = ExtractIconW(hInst, lpIconPath, *lpiIcon); 00810 00811 if( hIcon < (HICON)2 ) 00812 { if( hIcon == (HICON)1 ) /* no icons found in given file */ 00813 { WCHAR tempPath[MAX_PATH]; 00814 HINSTANCE uRet = FindExecutableW(lpIconPath,NULL,tempPath); 00815 00816 if( uRet > (HINSTANCE)32 && tempPath[0] ) 00817 { wcscpy(lpIconPath,tempPath); 00818 hIcon = ExtractIconW(hInst, lpIconPath, *lpiIcon); 00819 if( hIcon > (HICON)2 ) 00820 return hIcon; 00821 } 00822 } 00823 00824 if( hIcon == (HICON)1 ) 00825 *lpiIcon = 2; /* MSDOS icon - we found .exe but no icons in it */ 00826 else 00827 *lpiIcon = 6; /* generic icon - found nothing */ 00828 00829 if (GetModuleFileNameW(hInst, lpIconPath, MAX_PATH)) 00830 hIcon = LoadIconW(hInst, MAKEINTRESOURCEW(*lpiIcon)); 00831 } 00832 return hIcon; 00833 } 00834 00835 /************************************************************************* 00836 * ExtractAssociatedIconExW (SHELL32.@) 00837 * 00838 * Return icon for given file (either from file itself or from associated 00839 * executable) and patch parameters if needed. 00840 */ 00841 EXTERN_C HICON WINAPI ExtractAssociatedIconExW(HINSTANCE hInst, LPWSTR lpIconPath, LPWORD lpiIconIdx, LPWORD lpiIconId) 00842 { 00843 FIXME("%p %s %p %p): stub\n", hInst, debugstr_w(lpIconPath), lpiIconIdx, lpiIconId); 00844 return 0; 00845 } 00846 00847 /************************************************************************* 00848 * ExtractAssociatedIconExA (SHELL32.@) 00849 * 00850 * Return icon for given file (either from file itself or from associated 00851 * executable) and patch parameters if needed. 00852 */ 00853 EXTERN_C HICON WINAPI ExtractAssociatedIconExA(HINSTANCE hInst, LPSTR lpIconPath, LPWORD lpiIconIdx, LPWORD lpiIconId) 00854 { 00855 HICON ret; 00856 INT len = MultiByteToWideChar( CP_ACP, 0, lpIconPath, -1, NULL, 0 ); 00857 LPWSTR lpwstrFile = (LPWSTR)HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ); 00858 00859 TRACE("%p %s %p %p)\n", hInst, lpIconPath, lpiIconIdx, lpiIconId); 00860 00861 MultiByteToWideChar( CP_ACP, 0, lpIconPath, -1, lpwstrFile, len ); 00862 ret = ExtractAssociatedIconExW(hInst, lpwstrFile, lpiIconIdx, lpiIconId); 00863 HeapFree(GetProcessHeap(), 0, lpwstrFile); 00864 return ret; 00865 } 00866 00867 00868 /**************************************************************************** 00869 * SHDefExtractIconW [SHELL32.@] 00870 */ 00871 HRESULT WINAPI SHDefExtractIconW(LPCWSTR pszIconFile, int iIndex, UINT uFlags, 00872 HICON* phiconLarge, HICON* phiconSmall, UINT nIconSize) 00873 { 00874 UINT ret; 00875 HICON hIcons[2]; 00876 WARN("%s %d 0x%08x %p %p %d, semi-stub\n", debugstr_w(pszIconFile), iIndex, uFlags, phiconLarge, phiconSmall, nIconSize); 00877 00878 ret = PrivateExtractIconsW(pszIconFile, iIndex, nIconSize, nIconSize, hIcons, NULL, 2, LR_DEFAULTCOLOR); 00879 /* FIXME: deal with uFlags parameter which contains GIL_ flags */ 00880 if (ret == 0xFFFFFFFF) 00881 return E_FAIL; 00882 if (ret > 0) { 00883 if (phiconLarge) 00884 *phiconLarge = hIcons[0]; 00885 else 00886 DestroyIcon(hIcons[0]); 00887 if (phiconSmall) 00888 *phiconSmall = hIcons[1]; 00889 else 00890 DestroyIcon(hIcons[1]); 00891 return S_OK; 00892 } 00893 return S_FALSE; 00894 } 00895 00896 /**************************************************************************** 00897 * SHDefExtractIconA [SHELL32.@] 00898 */ 00899 HRESULT WINAPI SHDefExtractIconA(LPCSTR pszIconFile, int iIndex, UINT uFlags, 00900 HICON* phiconLarge, HICON* phiconSmall, UINT nIconSize) 00901 { 00902 HRESULT ret; 00903 INT len = MultiByteToWideChar(CP_ACP, 0, pszIconFile, -1, NULL, 0); 00904 LPWSTR lpwstrFile = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); 00905 00906 TRACE("%s %d 0x%08x %p %p %d\n", pszIconFile, iIndex, uFlags, phiconLarge, phiconSmall, nIconSize); 00907 00908 MultiByteToWideChar(CP_ACP, 0, pszIconFile, -1, lpwstrFile, len); 00909 ret = SHDefExtractIconW(lpwstrFile, iIndex, uFlags, phiconLarge, phiconSmall, nIconSize); 00910 HeapFree(GetProcessHeap(), 0, lpwstrFile); 00911 return ret; 00912 } 00913 00914 /**************************************************************************** 00915 * SHGetIconOverlayIndexA [SHELL32.@] 00916 * 00917 * Returns the index of the overlay icon in the system image list. 00918 */ 00919 EXTERN_C INT WINAPI SHGetIconOverlayIndexA(LPCSTR pszIconPath, INT iIconIndex) 00920 { 00921 FIXME("%s, %d\n", debugstr_a(pszIconPath), iIconIndex); 00922 00923 return -1; 00924 } 00925 00926 /**************************************************************************** 00927 * SHGetIconOverlayIndexW [SHELL32.@] 00928 * 00929 * Returns the index of the overlay icon in the system image list. 00930 */ 00931 EXTERN_C INT WINAPI SHGetIconOverlayIndexW(LPCWSTR pszIconPath, INT iIconIndex) 00932 { 00933 FIXME("%s, %d\n", debugstr_w(pszIconPath), iIconIndex); 00934 00935 return -1; 00936 } Generated on Thu May 24 2012 04:26:52 for ReactOS by
1.7.6.1
|