From: Vladislav Timonin timoninvlad@yandex.ru
--- dlls/comdlg32/navbar.c | 99 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 95 insertions(+), 4 deletions(-)
diff --git a/dlls/comdlg32/navbar.c b/dlls/comdlg32/navbar.c index 0d588a64c72..0f33e251bc1 100644 --- a/dlls/comdlg32/navbar.c +++ b/dlls/comdlg32/navbar.c @@ -27,6 +27,7 @@ #include "shlwapi.h" #include "commoncontrols.h" #include "pathcch.h" +#include "knownfolders.h"
#include "wine/debug.h" #include "wine/list.h" @@ -41,6 +42,14 @@ WINE_DEFAULT_DEBUG_CHANNEL(commdlg); #define IDC_OVERFLOW 205 #define IDC_NAVREFRESHGOTO 206
+static const KNOWNFOLDERID *ACCEPTED_KNOWN_FOLDERS[] = +{ + &FOLDERID_Desktop, + &FOLDERID_ComputerFolder, + &FOLDERID_RecycleBinFolder, + &FOLDERID_Documents, +}; + typedef struct { HWND parent_hwnd; HWND container_hwnd; @@ -123,12 +132,52 @@ static HDWP NAVBAR_DoLayout(NAVBAR_INFO *info, HDWP hdwp); static void NAVBAR_PATHEDIT_SetCurrentPath(NAVBAR_INFO *info) { struct crumb *crumb; - WCHAR cur_path[MAX_PATH]; + WCHAR *cur_path = NULL; + IShellFolder *desktop_sf; + SHGDNF shgdn = SHGDN_FORPARSING; + STRRET strret; + HRESULT hr; + INT i;
crumb = LIST_ENTRY(list_tail(&info->crumbs), struct crumb, entry); - SHGetPathFromIDListW(crumb->pidl, cur_path); - SetWindowTextW(info->pathedit_hwnd, cur_path); - SendMessageW(info->pathedit_hwnd, EM_SETSEL, 0, -1); /* select all */ + if (!crumb) + return; + + hr = SHGetDesktopFolder(&desktop_sf); + if (FAILED(hr)) + return; + + for (i = 0; i < ARRAY_SIZE(ACCEPTED_KNOWN_FOLDERS); i++) + { + ITEMIDLIST *known_folder_pidl = NULL; + BOOL is_known_folder = FALSE; + + hr = SHGetKnownFolderIDList(ACCEPTED_KNOWN_FOLDERS[i], 0, NULL, &known_folder_pidl); + if (FAILED(hr)) + continue; + + is_known_folder = ILIsEqual(crumb->pidl, known_folder_pidl); + ILFree(known_folder_pidl); + + if (is_known_folder) + { + shgdn = SHGDN_NORMAL; + break; + } + } + + hr = IShellFolder_GetDisplayNameOf(desktop_sf, crumb->pidl, shgdn, &strret); + if (SUCCEEDED(hr)) + hr = StrRetToStrW(&strret, crumb->pidl, &cur_path); + + if (SUCCEEDED(hr)) + { + SetWindowTextW(info->pathedit_hwnd, cur_path); + SendMessageW(info->pathedit_hwnd, EM_SETSEL, 0, -1); /* select all */ + CoTaskMemFree(cur_path); + } + + IShellFolder_Release(desktop_sf); }
static void NAVBAR_PATHEDIT_Edit(NAVBAR_INFO *info) @@ -201,7 +250,13 @@ static void NAVBAR_PATHEDIT_GoTo(NAVBAR_INFO *info) INT text_len = 0; DWORD expanded_len; ITEMIDLIST *pidl = NULL; + IShellFolder *desktop = NULL; HRESULT hr; + INT i; + + hr = SHGetDesktopFolder(&desktop); + if (FAILED(hr)) + goto exit;
text_len = GetWindowTextLengthW(info->pathedit_hwnd); if (!text_len) @@ -216,6 +271,39 @@ static void NAVBAR_PATHEDIT_GoTo(NAVBAR_INFO *info)
TRACE("text %s\n", debugstr_w(text));
+ StrTrimW(text, L" "); + + for (i = 0; i < ARRAY_SIZE(ACCEPTED_KNOWN_FOLDERS); i++) + { + ITEMIDLIST *known_folder_pidl = NULL; + STRRET strret; + + hr = SHGetKnownFolderIDList(ACCEPTED_KNOWN_FOLDERS[i], 0, NULL, &known_folder_pidl); + if (FAILED(hr)) + continue; + + hr = IShellFolder_GetDisplayNameOf(desktop, known_folder_pidl, SHGDN_NORMAL, &strret); + if (SUCCEEDED(hr)) + { + WCHAR *name; + + hr = StrRetToStrW(&strret, known_folder_pidl, &name); + if (SUCCEEDED(hr)) + { + BOOL is_known_folder = !lstrcmpiW(name, text); + CoTaskMemFree(name); + + if (is_known_folder) + { + pidl = known_folder_pidl; + goto send; + } + } + } + + ILFree(known_folder_pidl); + } + expanded_len = ExpandEnvironmentStringsW(text, NULL, 0); if (!expanded_len) goto cleanup; @@ -251,6 +339,7 @@ static void NAVBAR_PATHEDIT_GoTo(NAVBAR_INFO *info) if (FAILED(hr)) goto cleanup;
+send: TRACE("pidl %p\n", pidl);
SendMessageW(info->parent_hwnd, NBN_NAVPIDL, 0, (LPARAM)pidl); @@ -262,6 +351,8 @@ cleanup: HeapFree(GetProcessHeap(), 0, expanded); if (canonicalized) HeapFree(GetProcessHeap(), 0, canonicalized); + if (desktop) + IShellFolder_Release(desktop); exit: NAVBAR_PATHEDIT_Dismiss(info); }