/* * Class: sun_awt_shell_Win32ShellFolder2 * Method: getIconIndex * Signature: (JJ)I */ JNIEXPORT jint JNICALL Java_sun_awt_shell_Win32ShellFolder2_getIconIndex (JNIEnv* env, jclass cls, jlong pIShellIconL, jlong relativePIDL) { IShellIcon* pIShellIcon = (IShellIcon*)pIShellIconL; LPITEMIDLIST pidl = (LPITEMIDLIST)relativePIDL; if (pIShellIcon == NULL && pidl == NULL) { return 0; } INT index = -1; HRESULT hres; // http://msdn.microsoft.com/library/en-us/shellcc/platform/Shell/programmersguide/shell_int/shell_int_programming/std_ifaces.asp if (pIShellIcon != NULL) { hres = pIShellIcon->GetIconOf(pidl, GIL_FORSHELL, &index); } return (jint)index; }
// Thread to extract file icons in the background DWORD WINAPI DirList_IconThread(LPVOID lpParam) { HWND hwnd; LV_ITEM lvi; LPLV_ITEMDATA lplvid; IShellIcon* lpshi; int iItem = 0; int iMaxItem; DLDATA* lpdl = (DLDATA*)lpParam; ResetEvent(lpdl->hTerminatedThread); // Exit immediately if DirList_Fill() hasn't been called if (!lpdl->lpsf) { SetEvent(lpdl->hTerminatedThread); ExitThread(0); return 0; } hwnd = lpdl->hwnd; iMaxItem = ListView_GetItemCount(hwnd); (void)CoInitialize(NULL); // Get IShellIcon lpdl->lpsf->QueryInterface(IID_IShellIcon, (void**)&lpshi); while (iItem < iMaxItem && WaitForSingleObject(lpdl->hExitThread, 0) != WAIT_OBJECT_0) { lvi.iItem = iItem; lvi.mask = LVIF_PARAM; if (ListView_GetItem(hwnd, &lvi)) { SHFILEINFO shfi = { 0 }; LPITEMIDLIST pidl; DWORD dwAttributes = SFGAO_LINK | SFGAO_SHARE; lplvid = (LPLV_ITEMDATA)lvi.lParam; lvi.mask = LVIF_IMAGE; if (!lpshi || NOERROR != lpshi->GetIconOf(lplvid->pidl, GIL_FORSHELL, &lvi.iImage)) { pidl = IL_Create(lpdl->pidl, lpdl->cbidl, lplvid->pidl, 0); SHGetFileInfo((const WCHAR*)pidl, 0, &shfi, sizeof(SHFILEINFO), SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON); CoTaskMemFree(pidl); lvi.iImage = shfi.iIcon; } // It proved necessary to reset the state bits... lvi.stateMask = 0; lvi.state = 0; // Link and Share Overlay lplvid->lpsf->GetAttributesOf(1, (LPCITEMIDLIST*)&lplvid->pidl, &dwAttributes); if (dwAttributes & SFGAO_LINK) { lvi.mask |= LVIF_STATE; lvi.stateMask |= LVIS_OVERLAYMASK; lvi.state |= INDEXTOOVERLAYMASK(2); } if (dwAttributes & SFGAO_SHARE) { lvi.mask |= LVIF_STATE; lvi.stateMask |= LVIS_OVERLAYMASK; lvi.state |= INDEXTOOVERLAYMASK(1); } // Fade hidden/system files if (!lpdl->bNoFadeHidden) { WIN32_FIND_DATA fd; if (NOERROR == SHGetDataFromIDList(lplvid->lpsf, lplvid->pidl, SHGDFIL_FINDDATA, &fd, sizeof(WIN32_FIND_DATA))) { if ((fd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) || (fd.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM)) { lvi.mask |= LVIF_STATE; lvi.stateMask |= LVIS_CUT; lvi.state |= LVIS_CUT; } } } lvi.iSubItem = 0; ListView_SetItem(hwnd, &lvi); } iItem++; } if (lpshi) lpshi->Release(); CoUninitialize(); SetEvent(lpdl->hTerminatedThread); ExitThread(0); return 0; }