mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +00:00
[APPWIZ][SHELL32] Improve 'Create Shortcut' dialog (#6550)
Now we can open special folder shortcut, thanks to #6546. Let's allow users to create various shortcut files. JIRA issue: CORE-5866 - Remove BIF_RETURNONLYFSDIRS flag because the system can open special folder shortcuts now. - Add LPITEMIDLIST pidlTarget to CREATE_LINK_CONTEXT structure. - Use pidlTarget if the target is a special folder. - Fix CShellLink::DoOpen for arguments.
This commit is contained in:
parent
776c3a3495
commit
1d1472c78e
3 changed files with 71 additions and 50 deletions
|
@ -27,8 +27,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(appwiz);
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
LPITEMIDLIST pidlTarget;
|
||||||
WCHAR szTarget[2 * MAX_PATH];
|
WCHAR szTarget[2 * MAX_PATH];
|
||||||
WCHAR szWorkingDirectory[MAX_PATH];
|
|
||||||
WCHAR szDescription[MAX_PATH];
|
WCHAR szDescription[MAX_PATH];
|
||||||
WCHAR szArguments[2 * MAX_PATH];
|
WCHAR szArguments[2 * MAX_PATH];
|
||||||
WCHAR szOrigin[MAX_PATH];
|
WCHAR szOrigin[MAX_PATH];
|
||||||
|
|
|
@ -84,7 +84,11 @@ CreateShortcut(PCREATE_LINK_CONTEXT pContext)
|
||||||
/* get the extension */
|
/* get the extension */
|
||||||
lpExtension = PathFindExtensionW(pContext->szTarget);
|
lpExtension = PathFindExtensionW(pContext->szTarget);
|
||||||
|
|
||||||
if (IsExtensionAShortcut(lpExtension))
|
if (pContext->pidlTarget)
|
||||||
|
{
|
||||||
|
Path[0] = UNICODE_NULL;
|
||||||
|
}
|
||||||
|
else if (IsExtensionAShortcut(lpExtension))
|
||||||
{
|
{
|
||||||
hr = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_ALL, &IID_IShellLinkW, (void**)&pSourceShellLink);
|
hr = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_ALL, &IID_IShellLinkW, (void**)&pSourceShellLink);
|
||||||
|
|
||||||
|
@ -126,11 +130,16 @@ CreateShortcut(PCREATE_LINK_CONTEXT pContext)
|
||||||
if (hr != S_OK)
|
if (hr != S_OK)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
pShellLink->lpVtbl->SetPath(pShellLink, Path);
|
if (pContext->pidlTarget)
|
||||||
|
pShellLink->lpVtbl->SetIDList(pShellLink, pContext->pidlTarget);
|
||||||
|
else
|
||||||
|
pShellLink->lpVtbl->SetPath(pShellLink, Path);
|
||||||
|
|
||||||
if (pContext->szArguments[0])
|
if (pContext->szArguments[0])
|
||||||
pShellLink->lpVtbl->SetArguments(pShellLink, pContext->szArguments);
|
pShellLink->lpVtbl->SetArguments(pShellLink, pContext->szArguments);
|
||||||
pShellLink->lpVtbl->SetDescription(pShellLink, pContext->szDescription);
|
|
||||||
pShellLink->lpVtbl->SetWorkingDirectory(pShellLink, pContext->szWorkingDirectory);
|
if (pContext->szDescription[0])
|
||||||
|
pShellLink->lpVtbl->SetDescription(pShellLink, pContext->szDescription);
|
||||||
|
|
||||||
hr = IUnknown_QueryInterface(pShellLink, &IID_IPersistFile, (void**)&pPersistFile);
|
hr = IUnknown_QueryInterface(pShellLink, &IID_IPersistFile, (void**)&pPersistFile);
|
||||||
if (hr != S_OK)
|
if (hr != S_OK)
|
||||||
|
@ -233,9 +242,9 @@ WelcomeDlgProc(HWND hwndDlg,
|
||||||
LPARAM lParam)
|
LPARAM lParam)
|
||||||
{
|
{
|
||||||
LPPROPSHEETPAGEW ppsp;
|
LPPROPSHEETPAGEW ppsp;
|
||||||
PCREATE_LINK_CONTEXT pContext;
|
PCREATE_LINK_CONTEXT pContext = (PCREATE_LINK_CONTEXT)GetWindowLongPtr(hwndDlg, DWLP_USER);
|
||||||
LPPSHNOTIFY lppsn;
|
LPPSHNOTIFY lppsn;
|
||||||
WCHAR szPath[MAX_PATH * 2];
|
WCHAR szPath[MAX_PATH * 2], szDisplayName[MAX_PATH];
|
||||||
WCHAR szDesc[100];
|
WCHAR szDesc[100];
|
||||||
WCHAR szTitle[100];
|
WCHAR szTitle[100];
|
||||||
BROWSEINFOW brws;
|
BROWSEINFOW brws;
|
||||||
|
@ -253,54 +262,61 @@ WelcomeDlgProc(HWND hwndDlg,
|
||||||
break;
|
break;
|
||||||
case WM_COMMAND:
|
case WM_COMMAND:
|
||||||
{
|
{
|
||||||
switch(HIWORD(wParam))
|
switch (LOWORD(wParam))
|
||||||
{
|
{
|
||||||
case EN_CHANGE:
|
case IDC_SHORTCUT_LOCATION:
|
||||||
if (SendDlgItemMessage(hwndDlg, IDC_SHORTCUT_LOCATION, WM_GETTEXTLENGTH, 0, 0))
|
{
|
||||||
|
if (HIWORD(wParam) == EN_CHANGE)
|
||||||
{
|
{
|
||||||
PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT);
|
/* The text was changed by user. Invalidate pidlTarget. */
|
||||||
}
|
if (pContext->pidlTarget)
|
||||||
else
|
{
|
||||||
{
|
CoTaskMemFree(pContext->pidlTarget);
|
||||||
PropSheet_SetWizButtons(GetParent(hwndDlg), 0);
|
pContext->pidlTarget = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SendDlgItemMessage(hwndDlg, IDC_SHORTCUT_LOCATION, WM_GETTEXTLENGTH, 0, 0))
|
||||||
|
PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT);
|
||||||
|
else
|
||||||
|
PropSheet_SetWizButtons(GetParent(hwndDlg), 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
switch(LOWORD(wParam))
|
|
||||||
{
|
|
||||||
case IDC_SHORTCUT_BROWSE:
|
case IDC_SHORTCUT_BROWSE:
|
||||||
|
{
|
||||||
LoadStringW(hApplet, IDS_BROWSE_FOR_TARGET, szTitle, _countof(szTitle));
|
LoadStringW(hApplet, IDS_BROWSE_FOR_TARGET, szTitle, _countof(szTitle));
|
||||||
ZeroMemory(&brws, sizeof(brws));
|
ZeroMemory(&brws, sizeof(brws));
|
||||||
brws.hwndOwner = hwndDlg;
|
brws.hwndOwner = hwndDlg;
|
||||||
brws.pidlRoot = NULL;
|
brws.pidlRoot = NULL;
|
||||||
brws.pszDisplayName = szPath;
|
brws.pszDisplayName = szDisplayName;
|
||||||
brws.lpszTitle = szTitle;
|
brws.lpszTitle = szTitle;
|
||||||
brws.ulFlags = BIF_BROWSEINCLUDEFILES | BIF_RETURNONLYFSDIRS |
|
brws.ulFlags = BIF_BROWSEINCLUDEFILES | BIF_NEWDIALOGSTYLE | BIF_SHAREABLE;
|
||||||
BIF_NEWDIALOGSTYLE | BIF_SHAREABLE;
|
|
||||||
brws.lpfn = NULL;
|
brws.lpfn = NULL;
|
||||||
pidllist = SHBrowseForFolderW(&brws);
|
pidllist = SHBrowseForFolderW(&brws);
|
||||||
if (!pidllist)
|
if (!pidllist)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (SHGetPathFromIDListW(pidllist, szPath))
|
StringCchCopyW(pContext->szDescription, _countof(pContext->szDescription),
|
||||||
{
|
szDisplayName);
|
||||||
SetDlgItemTextW(hwndDlg, IDC_SHORTCUT_LOCATION, szPath);
|
|
||||||
SendDlgItemMessageW(hwndDlg, IDC_SHORTCUT_LOCATION, WM_SETFOCUS, 0, 0);
|
|
||||||
SendDlgItemMessageW(hwndDlg, IDC_SHORTCUT_LOCATION, EM_SETSEL, 0, -1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SetDlgItemTextW(hwndDlg, IDC_SHORTCUT_LOCATION, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Free memory, if possible */
|
SHGetPathFromIDListW(pidllist, szPath);
|
||||||
CoTaskMemFree(pidllist);
|
|
||||||
|
if (PathFileExistsW(szPath) && !PathIsRelativeW(szPath))
|
||||||
|
SetDlgItemTextW(hwndDlg, IDC_SHORTCUT_LOCATION, szPath);
|
||||||
|
else
|
||||||
|
SetDlgItemTextW(hwndDlg, IDC_SHORTCUT_LOCATION, szDisplayName);
|
||||||
|
|
||||||
|
SendDlgItemMessageW(hwndDlg, IDC_SHORTCUT_LOCATION, EM_SETSEL, 0, -1);
|
||||||
|
|
||||||
|
if (pContext->pidlTarget)
|
||||||
|
CoTaskMemFree(pContext->pidlTarget);
|
||||||
|
pContext->pidlTarget = pidllist;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WM_NOTIFY:
|
case WM_NOTIFY:
|
||||||
lppsn = (LPPSHNOTIFY) lParam;
|
lppsn = (LPPSHNOTIFY) lParam;
|
||||||
pContext = (PCREATE_LINK_CONTEXT)GetWindowLongPtr(hwndDlg, DWLP_USER);
|
|
||||||
if (lppsn->hdr.code == PSN_SETACTIVE)
|
if (lppsn->hdr.code == PSN_SETACTIVE)
|
||||||
{
|
{
|
||||||
SetDlgItemTextW(hwndDlg, IDC_SHORTCUT_LOCATION, pContext->szTarget);
|
SetDlgItemTextW(hwndDlg, IDC_SHORTCUT_LOCATION, pContext->szTarget);
|
||||||
|
@ -316,11 +332,19 @@ WelcomeDlgProc(HWND hwndDlg,
|
||||||
WCHAR szName[128];
|
WCHAR szName[128];
|
||||||
LoadStringW(hApplet, IDS_NEW_INTERNET_SHORTCUT, szName, _countof(szName));
|
LoadStringW(hApplet, IDS_NEW_INTERNET_SHORTCUT, szName, _countof(szName));
|
||||||
StringCchCopyW(pContext->szDescription, _countof(pContext->szDescription), szName);
|
StringCchCopyW(pContext->szDescription, _countof(pContext->szDescription), szName);
|
||||||
pContext->szWorkingDirectory[0] = 0;
|
|
||||||
pContext->szArguments[0] = 0;
|
pContext->szArguments[0] = 0;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pContext->pidlTarget) /* The result of SHBrowseForFolderW */
|
||||||
|
{
|
||||||
|
SHGetPathFromIDListW(pContext->pidlTarget, pContext->szTarget);
|
||||||
|
pContext->szArguments[0] = 0;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Otherwise, the target is a command line or pathname */
|
||||||
|
|
||||||
/* Split and build args */
|
/* Split and build args */
|
||||||
LPWSTR pszArgs = PathGetArgsW(szPath);
|
LPWSTR pszArgs = PathGetArgsW(szPath);
|
||||||
if (pszArgs && pszArgs > szPath)
|
if (pszArgs && pszArgs > szPath)
|
||||||
|
@ -334,10 +358,8 @@ WelcomeDlgProc(HWND hwndDlg,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find the file */
|
/* Find the file */
|
||||||
WCHAR szFound[MAX_PATH];
|
if (!PathFindOnPathExW(szPath, NULL, WHICH_DEFAULT) &&
|
||||||
StringCchCopyW(szFound, _countof(szFound), szPath);
|
!PathFileExistsW(szPath))
|
||||||
if (!PathFindOnPathExW(szFound, NULL, WHICH_DEFAULT) &&
|
|
||||||
FindExecutableW(szPath, NULL, szFound) <= (HINSTANCE)(INT_PTR)32)
|
|
||||||
{
|
{
|
||||||
/* Not found */
|
/* Not found */
|
||||||
SendDlgItemMessageW(hwndDlg, IDC_SHORTCUT_LOCATION, EM_SETSEL, 0, -1);
|
SendDlgItemMessageW(hwndDlg, IDC_SHORTCUT_LOCATION, EM_SETSEL, 0, -1);
|
||||||
|
@ -355,20 +377,17 @@ WelcomeDlgProc(HWND hwndDlg,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Rebuild target */
|
/* Rebuild target */
|
||||||
StringCchCopyW(pContext->szTarget, _countof(pContext->szTarget), szFound);
|
if (PathIsRelativeW(szPath))
|
||||||
|
GetFullPathNameW(szPath, _countof(pContext->szTarget), pContext->szTarget, NULL);
|
||||||
|
else
|
||||||
|
StringCchCopyW(pContext->szTarget, _countof(pContext->szTarget), szPath);
|
||||||
|
|
||||||
/* Get display name */
|
/* Get display name */
|
||||||
FileInfo.szDisplayName[0] = 0;
|
FileInfo.szDisplayName[0] = UNICODE_NULL;
|
||||||
if (SHGetFileInfoW(szFound, 0, &FileInfo, sizeof(FileInfo), SHGFI_DISPLAYNAME))
|
if (SHGetFileInfoW(pContext->szTarget, 0, &FileInfo, sizeof(FileInfo), SHGFI_DISPLAYNAME))
|
||||||
StringCchCopyW(pContext->szDescription, _countof(pContext->szDescription), FileInfo.szDisplayName);
|
StringCchCopyW(pContext->szDescription, _countof(pContext->szDescription), FileInfo.szDisplayName);
|
||||||
|
|
||||||
/* Set working directory */
|
break;
|
||||||
StringCchCopyW(pContext->szWorkingDirectory, _countof(pContext->szWorkingDirectory), szFound);
|
|
||||||
PathRemoveBackslashW(pContext->szWorkingDirectory);
|
|
||||||
PathRemoveFileSpecW(pContext->szWorkingDirectory);
|
|
||||||
PathRemoveBackslashW(pContext->szWorkingDirectory);
|
|
||||||
|
|
||||||
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE);
|
|
||||||
}
|
}
|
||||||
else if (lppsn->hdr.code == PSN_RESET && !lppsn->lParam)
|
else if (lppsn->hdr.code == PSN_RESET && !lppsn->lParam)
|
||||||
{
|
{
|
||||||
|
@ -618,6 +637,8 @@ ShowCreateShortcutWizard(HWND hwndCPl, LPCWSTR szPath)
|
||||||
|
|
||||||
/* Display the wizard */
|
/* Display the wizard */
|
||||||
PropertySheet(&psh);
|
PropertySheet(&psh);
|
||||||
|
|
||||||
|
CoTaskMemFree(pContext->pidlTarget);
|
||||||
HeapFree(GetProcessHeap(), 0, pContext);
|
HeapFree(GetProcessHeap(), 0, pContext);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2635,8 +2635,8 @@ HRESULT CShellLink::DoOpen(LPCMINVOKECOMMANDINFO lpici)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sei.lpFile = path;
|
sei.lpFile = path;
|
||||||
sei.lpParameters = args;
|
|
||||||
}
|
}
|
||||||
|
sei.lpParameters = args;
|
||||||
sei.lpClass = m_sLinkPath;
|
sei.lpClass = m_sLinkPath;
|
||||||
sei.nShow = m_Header.nShowCommand;
|
sei.nShow = m_Header.nShowCommand;
|
||||||
sei.lpDirectory = m_sWorkDir;
|
sei.lpDirectory = m_sWorkDir;
|
||||||
|
|
Loading…
Reference in a new issue