diff --git a/dll/win32/shell32/CShellLink.cpp b/dll/win32/shell32/CShellLink.cpp index 3ea7c3d5e6c..5fbcc3243d0 100644 --- a/dll/win32/shell32/CShellLink.cpp +++ b/dll/win32/shell32/CShellLink.cpp @@ -294,7 +294,6 @@ CShellLink::CShellLink() m_pDBList = NULL; m_bInInit = FALSE; m_hIcon = NULL; - m_idCmdFirst = 0; m_sLinkPath = NULL; @@ -2543,8 +2542,6 @@ HRESULT STDMETHODCALLTYPE CShellLink::QueryContextMenu(HMENU hMenu, UINT indexMe { INT id = 0; - m_idCmdFirst = idCmdFirst; - TRACE("%p %p %u %u %u %u\n", this, hMenu, indexMenu, idCmdFirst, idCmdLast, uFlags); @@ -2934,14 +2931,41 @@ void CShellLink::OnCommand(HWND hwndDlg, int id, HWND hwndCtl, UINT codeNotify) case IDC_SHORTCUT_CHANGE_ICON: { - WCHAR wszPath[MAX_PATH] = L""; - - if (m_sIcoPath) - wcscpy(wszPath, m_sIcoPath); - else - FindExecutableW(m_sPath, NULL, wszPath); - + SHFILEINFOW fi; INT IconIndex = m_Header.nIconIndex; + WCHAR wszPath[MAX_PATH]; + *wszPath = UNICODE_NULL; + + if (!StrIsNullOrEmpty(m_sIcoPath)) + { + PWSTR pszPath = m_sIcoPath; + if (*m_sIcoPath == '.') // Extension-only icon location, we need a fake path + { + if (SUCCEEDED(StringCchPrintfW(wszPath, _countof(wszPath), L"x:\\x%s", m_sIcoPath)) && + SHGetFileInfoW(wszPath, 0, &fi, sizeof(fi), SHGFI_ICONLOCATION | SHGFI_USEFILEATTRIBUTES)) + { + pszPath = fi.szDisplayName; // The path is now a generic icon based + IconIndex = fi.iIcon; // on the registry info of the file extension. + } + } + + if (FAILED(StringCchCopyW(wszPath, _countof(wszPath), pszPath))) + *wszPath = UNICODE_NULL; + } + else if (!StrIsNullOrEmpty(m_sPath)) + { + FindExecutableW(m_sPath, NULL, wszPath); + } + + if (!*wszPath && m_pPidl) + { + if (SHGetFileInfoW((PWSTR)m_pPidl, 0, &fi, sizeof(fi), SHGFI_ICONLOCATION | SHGFI_PIDL) && + SUCCEEDED(StringCchCopyW(wszPath, _countof(wszPath), fi.szDisplayName))) + { + IconIndex = fi.iIcon; + } + } + if (PickIconDlg(hwndDlg, wszPath, _countof(wszPath), &IconIndex)) { SetIconLocation(wszPath, IconIndex); @@ -2993,44 +3017,45 @@ LRESULT CShellLink::OnNotify(HWND hwndDlg, int idFrom, LPNMHDR pnmhdr) SetWorkingDirectory(wszBuf); /* set link destination */ - GetDlgItemTextW(hwndDlg, IDC_SHORTCUT_TARGET_TEXT, wszBuf, _countof(wszBuf)); - LPWSTR lpszArgs = NULL; - LPWSTR unquoted = strdupW(wszBuf); - StrTrimW(unquoted, L" "); - - if (!PathFileExistsW(unquoted)) + HWND hWndTarget = GetDlgItem(hwndDlg, IDC_SHORTCUT_TARGET_TEXT); + GetWindowTextW(hWndTarget, wszBuf, _countof(wszBuf)); + // Only set the path and arguments for filesystem targets (we can't verify other targets) + if (IsWindowEnabled(hWndTarget)) { - lpszArgs = PathGetArgsW(unquoted); - PathRemoveArgsW(unquoted); - StrTrimW(lpszArgs, L" "); + LPWSTR lpszArgs = NULL; + LPWSTR unquoted = wszBuf; + StrTrimW(unquoted, L" "); + + if (!PathFileExistsW(unquoted)) + { + lpszArgs = PathGetArgsW(unquoted); + PathRemoveArgsW(unquoted); + StrTrimW(lpszArgs, L" "); + } + if (unquoted[0] == '"' && unquoted[wcslen(unquoted) - 1] == '"') + PathUnquoteSpacesW(unquoted); + + WCHAR *pwszExt = PathFindExtensionW(unquoted); + if (!_wcsicmp(pwszExt, L".lnk")) + { + // TODO: SLDF_ALLOW_LINK_TO_LINK (Win7+) + // FIXME load localized error msg + MessageBoxW(hwndDlg, L"You cannot create a link to a shortcut", NULL, MB_ICONERROR); + SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE); + return TRUE; + } + + if (!PathFileExistsW(unquoted)) + { + // FIXME load localized error msg + MessageBoxW(hwndDlg, L"The specified file name in the target box is invalid", NULL, MB_ICONERROR); + SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE); + return TRUE; + } + + SetPath(unquoted); + SetArguments(lpszArgs ? lpszArgs : L"\0"); } - if (unquoted[0] == '"' && unquoted[wcslen(unquoted) - 1] == '"') - PathUnquoteSpacesW(unquoted); - - WCHAR *pwszExt = PathFindExtensionW(unquoted); - if (!_wcsicmp(pwszExt, L".lnk")) - { - // FIXME load localized error msg - MessageBoxW(hwndDlg, L"You cannot create a link to a shortcut", L"Error", MB_ICONERROR); - SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE); - return TRUE; - } - - if (!PathFileExistsW(unquoted)) - { - // FIXME load localized error msg - MessageBoxW(hwndDlg, L"The specified file name in the target box is invalid", L"Error", MB_ICONERROR); - SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE); - return TRUE; - } - - SetPath(unquoted); - if (lpszArgs) - SetArguments(lpszArgs); - else - SetArguments(L"\0"); - - HeapFree(GetProcessHeap(), 0, unquoted); m_Header.wHotKey = (WORD)SendDlgItemMessageW(hwndDlg, IDC_SHORTCUT_KEY_HOTKEY, HKM_GETHOTKEY, 0, 0); diff --git a/dll/win32/shell32/CShellLink.h b/dll/win32/shell32/CShellLink.h index 53fd75d49d9..34e25a16c82 100644 --- a/dll/win32/shell32/CShellLink.h +++ b/dll/win32/shell32/CShellLink.h @@ -87,7 +87,6 @@ private: LPDBLIST m_pDBList; /* Optional data block list (in the extra data section) */ BOOL m_bInInit; // in initialization or not HICON m_hIcon; - UINT m_idCmdFirst; /* Pointers to strings inside Logo3/Darwin info blocks, cached for debug info purposes only */ LPWSTR sProduct;