mirror of
https://github.com/reactos/reactos.git
synced 2025-05-29 22:18:13 +00:00
[BROWSEUI][SHDOCVW][SDK] Fix 'Add Favorite' command (#7804)
JIRA issue: CORE-19824 JIRA issue: CORE-19867 - Add shdocvw import to browseui. - Half-implement shdocvw! AddUrlToFavorites function. - Add AddUrlToFavorites prototype to <shdocvw_undoc.h>. - Fix browseui!CShellBrowser:: OnAddToFavorites and shdocvw!CNSCBand::_AddFavorite by using AddUrlToFavorites.
This commit is contained in:
parent
0c6423da8d
commit
151ba9ee8f
6 changed files with 122 additions and 99 deletions
|
@ -48,7 +48,7 @@ add_library(browseui MODULE
|
|||
|
||||
set_module_type(browseui win32dll UNICODE)
|
||||
target_link_libraries(browseui shellbars shellfind uuid wine cpprt atl_classes)
|
||||
add_importlibs(browseui uxtheme shlwapi shell32 comctl32 gdi32 ole32 oleaut32 user32 advapi32 mpr msvcrt kernel32 ntdll)
|
||||
add_importlibs(browseui uxtheme shdocvw shlwapi shell32 comctl32 gdi32 ole32 oleaut32 user32 advapi32 mpr msvcrt kernel32 ntdll)
|
||||
add_pch(browseui precomp.h "${PCH_SKIP_SOURCE}")
|
||||
add_cd_file(TARGET browseui DESTINATION reactos/system32 FOR all)
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <shellapi.h>
|
||||
#include <htiframe.h>
|
||||
#include <strsafe.h>
|
||||
#include <shdocvw_undoc.h>
|
||||
|
||||
extern HRESULT IUnknown_ShowDW(IUnknown * punk, BOOL fShow);
|
||||
|
||||
|
@ -3871,41 +3872,6 @@ LRESULT CShellBrowser::OnBackspace(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOO
|
|||
return 0;
|
||||
}
|
||||
|
||||
static BOOL
|
||||
CreateShortcut(
|
||||
IN LPCWSTR pszLnkFileName,
|
||||
IN LPCITEMIDLIST pidl,
|
||||
IN LPCWSTR pszDescription OPTIONAL)
|
||||
{
|
||||
IPersistFile *pPF;
|
||||
IShellLinkW *pSL;
|
||||
HRESULT hr = CoInitialize(NULL);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
|
||||
IID_IShellLinkW, (LPVOID*)&pSL);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
pSL->SetIDList(pidl);
|
||||
|
||||
if (pszDescription)
|
||||
pSL->SetDescription(pszDescription);
|
||||
|
||||
hr = pSL->QueryInterface(IID_IPersistFile, (LPVOID*)&pPF);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = pPF->Save(pszLnkFileName, TRUE);
|
||||
pPF->Release();
|
||||
}
|
||||
pSL->Release();
|
||||
}
|
||||
|
||||
CoUninitialize();
|
||||
|
||||
return SUCCEEDED(hr);
|
||||
}
|
||||
|
||||
HRESULT GetFavsLocation(HWND hWnd, LPITEMIDLIST *pPidl)
|
||||
{
|
||||
HRESULT hr = SHGetSpecialFolderLocation(hWnd, CSIDL_FAVORITES, pPidl);
|
||||
|
@ -3917,24 +3883,23 @@ HRESULT GetFavsLocation(HWND hWnd, LPITEMIDLIST *pPidl)
|
|||
|
||||
LRESULT CShellBrowser::OnAddToFavorites(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
|
||||
{
|
||||
LPITEMIDLIST pidlFavs;
|
||||
HRESULT hr = GetFavsLocation(m_hWnd, &pidlFavs);
|
||||
CComPtr<IShellFolder> pParent;
|
||||
LPCITEMIDLIST pidlLast;
|
||||
HRESULT hr = SHBindToParent(fCurrentDirectoryPIDL, IID_PPV_ARG(IShellFolder, &pParent), &pidlLast);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
||||
STRRET strret;
|
||||
hr = pParent->GetDisplayNameOf(pidlLast, SHGDN_FORPARSING, &strret);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return 0;
|
||||
|
||||
SHFILEINFOW fileInfo = { NULL };
|
||||
if (!SHGetFileInfoW((LPCWSTR)fCurrentDirectoryPIDL, 0, &fileInfo, sizeof(fileInfo),
|
||||
SHGFI_PIDL | SHGFI_DISPLAYNAME))
|
||||
{
|
||||
CComHeapPtr<WCHAR> pszURL;
|
||||
hr = StrRetToStrW(&strret, NULL, &pszURL);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return 0;
|
||||
}
|
||||
|
||||
WCHAR szPath[MAX_PATH];
|
||||
SHGetPathFromIDListW(pidlFavs, szPath);
|
||||
PathAppendW(szPath, fileInfo.szDisplayName);
|
||||
PathAddExtensionW(szPath, L".lnk");
|
||||
|
||||
CreateShortcut(szPath, fCurrentDirectoryPIDL, NULL);
|
||||
AddUrlToFavorites(m_hWnd, pszURL, NULL, TRUE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,33 +45,6 @@ SHDOCVW_GetPathOfShortcut(
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
SHDOCVW_CreateShortcut(
|
||||
_In_ LPCWSTR pszLnkFileName,
|
||||
_In_ PCIDLIST_ABSOLUTE pidlTarget,
|
||||
_In_opt_ LPCWSTR pszDescription)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
CComPtr<IShellLink> psl;
|
||||
hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
|
||||
IID_PPV_ARG(IShellLink, &psl));
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
||||
psl->SetIDList(pidlTarget);
|
||||
|
||||
if (pszDescription)
|
||||
psl->SetDescription(pszDescription);
|
||||
|
||||
CComPtr<IPersistFile> ppf;
|
||||
hr = psl->QueryInterface(IID_PPV_ARG(IPersistFile, &ppf));
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
||||
return ppf->Save(pszLnkFileName, TRUE);
|
||||
}
|
||||
|
||||
CNSCBand::CNSCBand()
|
||||
{
|
||||
SHDOCVW_LockModule();
|
||||
|
@ -648,31 +621,23 @@ HRESULT CNSCBand::_AddFavorite()
|
|||
CComHeapPtr<ITEMIDLIST> pidlCurrent;
|
||||
_GetCurrentLocation(&pidlCurrent);
|
||||
|
||||
WCHAR szCurDir[MAX_PATH];
|
||||
if (!ILGetDisplayName(pidlCurrent, szCurDir))
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
CComPtr<IShellFolder> pParent;
|
||||
LPCITEMIDLIST pidlLast;
|
||||
HRESULT hr = SHBindToParent(pidlCurrent, IID_PPV_ARG(IShellFolder, &pParent), &pidlLast);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
||||
WCHAR szPath[MAX_PATH], szSuffix[32];
|
||||
SHGetSpecialFolderPathW(m_hWnd, szPath, CSIDL_FAVORITES, TRUE);
|
||||
PathAppendW(szPath, PathFindFileNameW(szCurDir));
|
||||
STRRET strret;
|
||||
hr = pParent->GetDisplayNameOf(pidlLast, SHGDN_FORPARSING, &strret);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
||||
const INT ich = lstrlenW(szPath);
|
||||
for (INT iTry = 2; iTry <= 9999; ++iTry)
|
||||
{
|
||||
PathAddExtensionW(szPath, L".lnk");
|
||||
if (!PathFileExistsW(szPath))
|
||||
break;
|
||||
szPath[ich] = UNICODE_NULL;
|
||||
wsprintfW(szSuffix, L" (%d)", iTry);
|
||||
lstrcatW(szPath, szSuffix);
|
||||
}
|
||||
CComHeapPtr<WCHAR> pszURL;
|
||||
hr = StrRetToStrW(&strret, NULL, &pszURL);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
||||
TRACE("%S, %S\n", szCurDir, szPath);
|
||||
|
||||
return SHDOCVW_CreateShortcut(szPath, pidlCurrent, NULL);
|
||||
return AddUrlToFavorites(m_hWnd, pszURL, NULL, TRUE);
|
||||
}
|
||||
|
||||
LRESULT CNSCBand::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
103 stub -noname CreateShortcutInDirW # FIXME: Inspect
|
||||
104 stdcall -noname WhichPlatformFORWARD()
|
||||
105 stub -noname CreateShortcutInDirEx # FIXME: Inspect
|
||||
106 stub AddUrlToFavorites
|
||||
106 stdcall AddUrlToFavorites(ptr wstr wstr long)
|
||||
@ stdcall -private DllCanUnloadNow()
|
||||
@ stdcall -private DllGetClassObject(ptr ptr ptr)
|
||||
@ stdcall -private DllGetVersion(ptr)
|
||||
|
|
|
@ -139,3 +139,89 @@ IEILIsEqual(
|
|||
FIXME("%p, %p\n", pidl1, pidl2);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static VOID
|
||||
SHDOCVW_PathDeleteInvalidChars(LPWSTR pszDisplayName)
|
||||
{
|
||||
#define PATH_VALID_ELEMENT ( \
|
||||
PATH_CHAR_CLASS_DOT | PATH_CHAR_CLASS_SEMICOLON | PATH_CHAR_CLASS_COMMA | \
|
||||
PATH_CHAR_CLASS_SPACE | PATH_CHAR_CLASS_OTHER_VALID \
|
||||
)
|
||||
PWCHAR pch, pchSrc;
|
||||
for (pch = pchSrc = pszDisplayName; *pchSrc; ++pchSrc)
|
||||
{
|
||||
if (PathIsValidCharW(*pchSrc, PATH_VALID_ELEMENT))
|
||||
*pch++ = *pchSrc;
|
||||
}
|
||||
*pch = UNICODE_NULL;
|
||||
}
|
||||
|
||||
static HRESULT
|
||||
SHDOCVW_CreateShortcut(
|
||||
_In_ LPCWSTR pszLnkFileName,
|
||||
_In_ PCIDLIST_ABSOLUTE pidlTarget,
|
||||
_In_opt_ LPCWSTR pszDescription)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
CComPtr<IShellLink> psl;
|
||||
hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
|
||||
IID_PPV_ARG(IShellLink, &psl));
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
||||
psl->SetIDList(pidlTarget);
|
||||
|
||||
if (pszDescription)
|
||||
psl->SetDescription(pszDescription);
|
||||
|
||||
CComPtr<IPersistFile> ppf;
|
||||
hr = psl->QueryInterface(IID_PPV_ARG(IPersistFile, &ppf));
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
||||
return ppf->Save(pszLnkFileName, TRUE);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* AddUrlToFavorites [SHDOCVW.106]
|
||||
*/
|
||||
EXTERN_C HRESULT WINAPI
|
||||
AddUrlToFavorites(
|
||||
_In_ HWND hwnd,
|
||||
_In_ LPCWSTR pszUrlW,
|
||||
_In_opt_ LPCWSTR pszTitleW,
|
||||
_In_ BOOL fDisplayUI)
|
||||
{
|
||||
TRACE("%p, %s, %s, %d\n", hwnd, wine_dbgstr_w(pszUrlW), wine_dbgstr_w(pszTitleW), fDisplayUI);
|
||||
|
||||
if (fDisplayUI)
|
||||
FIXME("fDisplayUI\n"); // NOTE: Use SHBrowseForFolder callback
|
||||
|
||||
if (PathIsURLW(pszUrlW))
|
||||
FIXME("Internet Shortcut\n");
|
||||
|
||||
CComHeapPtr<ITEMIDLIST> pidl;
|
||||
HRESULT hr = SHParseDisplayName(pszUrlW, NULL, &pidl, 0, NULL);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
||||
// Get title
|
||||
WCHAR szTitle[MAX_PATH];
|
||||
if (pszTitleW)
|
||||
lstrcpynW(szTitle, pszTitleW, _countof(szTitle));
|
||||
else
|
||||
ILGetDisplayNameEx(NULL, pidl, szTitle, ILGDN_NORMAL);
|
||||
|
||||
// Delete invalid characters
|
||||
SHDOCVW_PathDeleteInvalidChars(szTitle);
|
||||
|
||||
// Build shortcut pathname
|
||||
WCHAR szPath[MAX_PATH];
|
||||
if (!SHGetSpecialFolderPathW(hwnd, szPath, CSIDL_FAVORITES, TRUE))
|
||||
SHGetSpecialFolderPathW(hwnd, szPath, CSIDL_COMMON_FAVORITES, TRUE);
|
||||
PathAppendW(szPath, szTitle);
|
||||
PathAddExtensionW(szPath, L".lnk");
|
||||
|
||||
return SHDOCVW_CreateShortcut(szPath, pidl, NULL);
|
||||
}
|
||||
|
|
|
@ -19,6 +19,13 @@ IEILIsEqual(
|
|||
_In_ LPCITEMIDLIST pidl2,
|
||||
_In_ BOOL bUnknown);
|
||||
|
||||
HRESULT WINAPI
|
||||
AddUrlToFavorites(
|
||||
_In_ HWND hwnd,
|
||||
_In_opt_ LPCWSTR pszUrlW,
|
||||
_In_ LPCWSTR pszTitleW,
|
||||
_In_ BOOL fDisplayUI);
|
||||
|
||||
BOOL WINAPI WinList_Init(VOID);
|
||||
VOID WINAPI WinList_Terminate(VOID);
|
||||
HRESULT WINAPI WinList_Revoke(_In_ LONG lCookie);
|
||||
|
|
Loading…
Reference in a new issue