diff --git a/dll/win32/shell32/CShellLink.cpp b/dll/win32/shell32/CShellLink.cpp index dfbd05792f..58fddc775c 100644 --- a/dll/win32/shell32/CShellLink.cpp +++ b/dll/win32/shell32/CShellLink.cpp @@ -1766,8 +1766,9 @@ HRESULT STDMETHODCALLTYPE CShellLink::GetIconLocation(UINT uFlags, PWSTR pszIcon HRESULT STDMETHODCALLTYPE CShellLink::Extract(PCWSTR pszFile, UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize) { - UNIMPLEMENTED; - return E_FAIL; + if (!::ExtractIconExW(pszFile, nIconIndex, phiconLarge, phiconSmall, nIconSize)) + return E_FAIL; + return S_OK; } #if 0 @@ -2895,9 +2896,14 @@ INT_PTR CALLBACK CShellLink::SH_ShellLinkDlgProc(HWND hwndDlg, UINT uMsg, WPARAM if (PickIconDlg(hwndDlg, wszPath, _countof(wszPath), &IconIndex)) { pThis->SetIconLocation(wszPath, IconIndex); - /// - /// FIXME redraw icon - /// + + HICON hIconLarge = NULL; + if (S_OK == pThis->Extract(wszPath, IconIndex, &hIconLarge, NULL, 1)) + { + HICON hIconOld = (HICON)SendDlgItemMessageW(hwndDlg, 14000, STM_GETICON, 0, 0); + SendDlgItemMessageW(hwndDlg, 14000, STM_SETICON, (WPARAM)hIconLarge, 0); + DestroyIcon(hIconOld); + } } return TRUE; } diff --git a/dll/win32/shell32/dialogs/dialogs.cpp b/dll/win32/shell32/dialogs/dialogs.cpp index f266e79787..8d1fadde21 100644 --- a/dll/win32/shell32/dialogs/dialogs.cpp +++ b/dll/win32/shell32/dialogs/dialogs.cpp @@ -48,6 +48,8 @@ typedef struct HWND hDlgCtrl; WCHAR szName[MAX_PATH]; INT Index; + INT nIcons; + HICON *phIcons; } PICK_ICON_CONTEXT, *PPICK_ICON_CONTEXT; BOOL CALLBACK EnumPickIconResourceProc(HMODULE hModule, @@ -58,21 +60,17 @@ BOOL CALLBACK EnumPickIconResourceProc(HMODULE hModule, { WCHAR szName[100]; int index; - HICON hIcon; - HWND hDlgCtrl = (HWND)lParam; + PPICK_ICON_CONTEXT pPickIcon = PPICK_ICON_CONTEXT(lParam); + HWND hDlgCtrl = pPickIcon->hDlgCtrl; if (IS_INTRESOURCE(lpszName)) swprintf(szName, L"%u", (DWORD)lpszName); else StringCbCopyW(szName, sizeof(szName), lpszName); - hIcon = LoadIconW(hModule, lpszName); - if (hIcon == NULL) - return TRUE; - index = SendMessageW(hDlgCtrl, LB_ADDSTRING, 0, (LPARAM)szName); if (index != LB_ERR) - SendMessageW(hDlgCtrl, LB_SETITEMDATA, index, (LPARAM)hIcon); + SendMessageW(hDlgCtrl, LB_SETITEMDATA, index, (LPARAM)pPickIcon->phIcons[index]); return TRUE; } @@ -116,11 +114,13 @@ INT_PTR CALLBACK PickIconProc(HWND hwndDlg, SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pIconContext); pIconContext->hDlgCtrl = GetDlgItem(hwndDlg, IDC_PICKICON_LIST); SendMessageW(pIconContext->hDlgCtrl, LB_SETCOLUMNWIDTH, 32, 0); - EnumResourceNamesW(pIconContext->hLibrary, RT_ICON, EnumPickIconResourceProc, (LPARAM)pIconContext->hDlgCtrl); - if (ExpandEnvironmentStringsW(pIconContext->szName, szText, MAX_PATH)) - SetDlgItemTextW(hwndDlg, IDC_EDIT_PATH, szText); - else - SetDlgItemTextW(hwndDlg, IDC_EDIT_PATH, pIconContext->szName); + + pIconContext->nIcons = (INT)(INT_PTR)ExtractIconExW(pIconContext->szName, -1, NULL, NULL, 0); + pIconContext->phIcons = new HICON[pIconContext->nIcons]; + ExtractIconExW(pIconContext->szName, 0, pIconContext->phIcons, NULL, pIconContext->nIcons); + EnumResourceNamesW(pIconContext->hLibrary, RT_GROUP_ICON, EnumPickIconResourceProc, (LPARAM)pIconContext); + + SetDlgItemTextW(hwndDlg, IDC_EDIT_PATH, pIconContext->szName); count = SendMessageW(pIconContext->hDlgCtrl, LB_GETCOUNT, 0, 0); if (count != LB_ERR) @@ -139,10 +139,12 @@ INT_PTR CALLBACK PickIconProc(HWND hwndDlg, pIconContext->Index = index; GetDlgItemTextW(hwndDlg, IDC_EDIT_PATH, pIconContext->szName, MAX_PATH); DestroyIconList(pIconContext->hDlgCtrl); + delete[] pIconContext->phIcons; EndDialog(hwndDlg, 1); break; case IDCANCEL: DestroyIconList(pIconContext->hDlgCtrl); + delete[] pIconContext->phIcons; EndDialog(hwndDlg, 0); break; case IDC_PICKICON_LIST: @@ -163,24 +165,27 @@ INT_PTR CALLBACK PickIconProc(HWND hwndDlg, ofn.lpstrFilter = szFilter; if (GetOpenFileNameW(&ofn)) { - HMODULE hLibrary; - if (!wcsicmp(pIconContext->szName, szText)) break; DestroyIconList(pIconContext->hDlgCtrl); + SendMessageW(pIconContext->hDlgCtrl, LB_RESETCONTENT, 0, 0); - hLibrary = LoadLibraryExW(szText, NULL, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE); + HMODULE hLibrary = LoadLibraryExW(szText, NULL, LOAD_LIBRARY_AS_DATAFILE); if (hLibrary == NULL) break; FreeLibrary(pIconContext->hLibrary); pIconContext->hLibrary = hLibrary; + wcscpy(pIconContext->szName, szText); - EnumResourceNamesW(pIconContext->hLibrary, RT_ICON, EnumPickIconResourceProc, (LPARAM)pIconContext->hDlgCtrl); - if (ExpandEnvironmentStringsW(pIconContext->szName, szText, MAX_PATH)) - SetDlgItemTextW(hwndDlg, IDC_EDIT_PATH, szText); - else - SetDlgItemTextW(hwndDlg, IDC_EDIT_PATH, pIconContext->szName); + + pIconContext->nIcons = (INT)(INT_PTR)ExtractIconExW(szText, -1, NULL, NULL, 0); + delete[] pIconContext->phIcons; + pIconContext->phIcons = new HICON[pIconContext->nIcons]; + ExtractIconExW(szText, 0, pIconContext->phIcons, NULL, pIconContext->nIcons); + EnumResourceNamesW(pIconContext->hLibrary, RT_GROUP_ICON, EnumPickIconResourceProc, (LPARAM)pIconContext); + + SetDlgItemTextW(hwndDlg, IDC_EDIT_PATH, szText); SendMessageW(pIconContext->hDlgCtrl, LB_SETCURSEL, 0, 0); } @@ -214,7 +219,7 @@ INT_PTR CALLBACK PickIconProc(HWND hwndDlg, 0, 0, 0, NULL, DI_NORMAL); break; } - break; + return TRUE; } return FALSE; @@ -229,11 +234,14 @@ BOOL WINAPI PickIconDlg( HMODULE hLibrary; int res; PICK_ICON_CONTEXT IconContext; + WCHAR szExpanded[MAX_PATH]; + + ExpandEnvironmentStringsW(lpstrFile, szExpanded, _countof(szExpanded)); - hLibrary = LoadLibraryExW(lpstrFile, NULL, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE); + hLibrary = LoadLibraryExW(szExpanded, NULL, LOAD_LIBRARY_AS_DATAFILE); IconContext.hLibrary = hLibrary; IconContext.Index = *lpdwIconIndex; - StringCchCopyNW(IconContext.szName, _countof(IconContext.szName), lpstrFile, nMaxFile); + StringCchCopyW(IconContext.szName, _countof(IconContext.szName), szExpanded); res = DialogBoxParamW(shell32_hInstance, MAKEINTRESOURCEW(IDD_PICK_ICON), hWndOwner, PickIconProc, (LPARAM)&IconContext); if (res)