From 77932fa09ada882bfb8a89fce519a141883660a5 Mon Sep 17 00:00:00 2001 From: Martin Fuchs Date: Sun, 1 Jan 2006 15:21:03 +0000 Subject: [PATCH] explorer: - simplify SCAN flags - extend shell browser to use WINFS - resolve a few FIXMEs - simplify ShellBrowser initialization - handle /root command line option svn path=/trunk/; revision=20515 --- .../system/explorer/dialogs/searchprogram.cpp | 2 +- .../subsys/system/explorer/doc/changes.txt | 1 + .../subsys/system/explorer/shell/entries.cpp | 1 + .../subsys/system/explorer/shell/entries.h | 22 +-- reactos/subsys/system/explorer/shell/fatfs.h | 2 +- .../system/explorer/shell/mainframe.cpp | 49 ++--- .../subsys/system/explorer/shell/ntobjfs.h | 2 +- reactos/subsys/system/explorer/shell/pane.cpp | 1 - reactos/subsys/system/explorer/shell/regfs.h | 4 +- .../system/explorer/shell/shellbrowser.cpp | 186 ++++++++++-------- .../system/explorer/shell/shellbrowser.h | 20 +- .../subsys/system/explorer/shell/shellfs.cpp | 54 +++-- .../subsys/system/explorer/shell/shellfs.h | 4 +- .../subsys/system/explorer/shell/winfs.cpp | 17 +- reactos/subsys/system/explorer/shell/winfs.h | 2 +- .../system/explorer/taskbar/favorites.cpp | 2 +- .../system/explorer/taskbar/quicklaunch.cpp | 12 +- .../system/explorer/taskbar/startmenu.cpp | 8 +- 18 files changed, 208 insertions(+), 181 deletions(-) diff --git a/reactos/subsys/system/explorer/dialogs/searchprogram.cpp b/reactos/subsys/system/explorer/dialogs/searchprogram.cpp index 6b1755041d2..55c8c03cc9d 100644 --- a/reactos/subsys/system/explorer/dialogs/searchprogram.cpp +++ b/reactos/subsys/system/explorer/dialogs/searchprogram.cpp @@ -59,7 +59,7 @@ void CollectProgramsThread::collect_programs(const ShellPath& path) ShellDirectory* dir = new ShellDirectory(GetDesktopFolder(), path, 0); _dirs.push(dir); - dir->smart_scan(SORT_NONE, /*SCAN_EXTRACT_ICONS|*/SCAN_FILESYSTEM); + dir->smart_scan(SORT_NONE); for(Entry*entry=dir->_down; _alive && entry; entry=entry->_next) { if (entry->_shell_attribs & SFGAO_HIDDEN) diff --git a/reactos/subsys/system/explorer/doc/changes.txt b/reactos/subsys/system/explorer/doc/changes.txt index acd1966253a..372642f99f6 100644 --- a/reactos/subsys/system/explorer/doc/changes.txt +++ b/reactos/subsys/system/explorer/doc/changes.txt @@ -167,3 +167,4 @@ If you search for more information, look into the Subversion repository. 01.11.2005 m. fuchs String::str(), String::toLower() to allow conventient and WINE compatible string conversions 29.11.2005 m. fuchs Adjustments for Visual Studio 2005: use new secure CT functions, COUNTOF for buffer sizes 28.12.2005 m. fuchs display icon overlays in Explorer tree view +31.12.2005 m. fuchs handle "/root" command line parameter diff --git a/reactos/subsys/system/explorer/shell/entries.cpp b/reactos/subsys/system/explorer/shell/entries.cpp index 5782d88543b..24ea8f03607 100644 --- a/reactos/subsys/system/explorer/shell/entries.cpp +++ b/reactos/subsys/system/explorer/shell/entries.cpp @@ -614,6 +614,7 @@ HRESULT Entry::GetUIObjectOf(HWND hWnd, REFIID riid, LPVOID* ppvOut) return hr; } + // get full path of specified directory entry bool Entry::get_path_base ( PTSTR path, size_t path_count, ENTRY_TYPE etype ) const { diff --git a/reactos/subsys/system/explorer/shell/entries.h b/reactos/subsys/system/explorer/shell/entries.h index 946c452cf79..2b39fbdc810 100644 --- a/reactos/subsys/system/explorer/shell/entries.h +++ b/reactos/subsys/system/explorer/shell/entries.h @@ -50,12 +50,9 @@ enum SORT_ORDER { }; enum SCAN_FLAGS { -// SCAN_EXTRACT_ICONS = 1, - SCAN_DO_ACCESS = 2, - - SCAN_ALL = 3, - - SCAN_FILESYSTEM = 4 + SCAN_DONT_EXTRACT_ICONS = 1, + SCAN_DONT_ACCESS = 2, + SCAN_NO_FILESYSTEM = 4 }; #ifndef ATTRIBUTE_SYMBOLIC_LINK @@ -114,19 +111,20 @@ public: void free_subentries(); - void read_directory_base(SORT_ORDER sortOrder=SORT_NAME, int scan_flags=SCAN_ALL); - Entry* read_tree(const void* path, SORT_ORDER sortOrder=SORT_NAME, int scan_flags=SCAN_ALL); + void read_directory_base(SORT_ORDER sortOrder=SORT_NAME, int scan_flags=0); + Entry* read_tree(const void* path, SORT_ORDER sortOrder=SORT_NAME, int scan_flags=0); void sort_directory(SORT_ORDER sortOrder); - void smart_scan(SORT_ORDER sortOrder=SORT_NAME, int scan_flags=SCAN_ALL); + void smart_scan(SORT_ORDER sortOrder=SORT_NAME, int scan_flags=0); int extract_icon(ICONCACHE_FLAGS flags=ICF_NORMAL); int safe_extract_icon(ICONCACHE_FLAGS flags=ICF_NORMAL); - virtual void read_directory(int scan_flags=SCAN_ALL) {} + virtual void read_directory(int scan_flags=0) {} virtual const void* get_next_path_component(const void*) const {return NULL;} virtual Entry* find_entry(const void*) {return NULL;} virtual bool get_path(PTSTR path, size_t path_count) const = 0; virtual ShellPath create_absolute_pidl() const {return (LPCITEMIDLIST)NULL;} virtual HRESULT GetUIObjectOf(HWND hWnd, REFIID riid, LPVOID* ppvOut); + virtual ShellFolder get_shell_folder() const; virtual BOOL launch_entry(HWND hwnd, UINT nCmdShow=SW_SHOWNORMAL); virtual HRESULT do_context_menu(HWND hwnd, const POINT& pos, CtxMenuInterfaces& cm_ifs); @@ -158,6 +156,6 @@ struct Root { DWORD _fs_flags; SORT_ORDER _sort_order; - Entry* read_tree(LPCTSTR path, int scan_flags=SCAN_ALL); - Entry* read_tree(LPCITEMIDLIST pidl, int scan_flags=SCAN_ALL); + Entry* read_tree(LPCTSTR path, int scan_flags=0); + Entry* read_tree(LPCITEMIDLIST pidl, int scan_flags=0); }; diff --git a/reactos/subsys/system/explorer/shell/fatfs.h b/reactos/subsys/system/explorer/shell/fatfs.h index 1824e00f104..cf976302785 100644 --- a/reactos/subsys/system/explorer/shell/fatfs.h +++ b/reactos/subsys/system/explorer/shell/fatfs.h @@ -50,7 +50,7 @@ struct FATDirectory : public FATEntry, public Directory FATDirectory(FATDrive& drive, Entry* parent, LPCTSTR path, unsigned cluster); ~FATDirectory(); - virtual void read_directory(int scan_flags=SCAN_ALL); + virtual void read_directory(int scan_flags=0); virtual const void* get_next_path_component(const void*) const; virtual Entry* find_entry(const void*); diff --git a/reactos/subsys/system/explorer/shell/mainframe.cpp b/reactos/subsys/system/explorer/shell/mainframe.cpp index 09ae01388e6..eb489a99baf 100644 --- a/reactos/subsys/system/explorer/shell/mainframe.cpp +++ b/reactos/subsys/system/explorer/shell/mainframe.cpp @@ -980,6 +980,11 @@ LRESULT MDIMainFrame::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) // Shell Namespace as default view ShellChildWndInfo create_info(_hmdiclient, path, shell_path); + if (wparam & OWM_ROOTED) + create_info._root_shell_path = shell_path; + else + create_info._root_shell_path = DesktopFolderPath(); //SpecialFolderPath(CSIDL_DRIVES, _hwnd); + create_info._pos.showCmd = wparam&OWM_SEPARATE? SW_SHOWNORMAL: SW_SHOWMAXIMIZED; create_info._pos.rcNormalPosition.left = CW_USEDEFAULT; create_info._pos.rcNormalPosition.top = CW_USEDEFAULT; @@ -1521,7 +1526,7 @@ LRESULT SDIMainFrame::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) if (wparam & OWM_ROOTED) _shellpath_info._root_shell_path = shell_path; else - _shellpath_info._root_shell_path = SpecialFolderPath(CSIDL_DESKTOP, _hwnd); // CSIDL_DRIVES + _shellpath_info._root_shell_path = DesktopFolderPath(); //SpecialFolderPath(CSIDL_DRIVES, _hwnd); jump_to(shell_path, wparam); //@todo content of 'path' not used any more return TRUE;} // success @@ -1660,11 +1665,9 @@ void SDIMainFrame::update_shell_browser() } } - _shellBrowser = auto_ptr(new ShellBrowser(_hwnd, _left_hwnd, _right_hwnd, + _shellBrowser = auto_ptr(new ShellBrowser(_hwnd, _hwnd, _left_hwnd, _right_hwnd, _shellpath_info, this, _cm_ifs)); - _shellBrowser->Init(_hwnd); - if (_left_hwnd) _shellBrowser->Init(); @@ -1674,37 +1677,25 @@ void SDIMainFrame::update_shell_browser() void SDIMainFrame::entry_selected(Entry* entry) { - if (entry->_etype == ET_SHELL) { - ShellEntry* shell_entry = static_cast(entry); - IShellFolder* folder; - - if (shell_entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - folder = static_cast(shell_entry)->_folder; - else - folder = shell_entry->get_parent_folder(); - - if (!folder) { - assert(folder); - return; - } + if (_left_hwnd) + _shellBrowser->select_folder(entry, false); - TCHAR path[MAX_PATH]; + _shellBrowser->UpdateFolderView(entry->get_shell_folder()); - if (shell_entry->get_path(path, COUNTOF(path))) { - String url; + // set size of new created shell view windows + resize_children(); - if (path[0] == ':') - url.printf(TEXT("shell://%s"), path); - else - url.printf(TEXT("file://%s"), path); + TCHAR path[MAX_PATH]; - set_url(url); - } + if (entry->get_path(path, COUNTOF(path))) { + String url; - _shellBrowser->UpdateFolderView(folder); + if (path[0] == ':') + url.printf(TEXT("shell://%s"), path); + else + url.printf(TEXT("file://%s"), path); - // update _clnt_rect and set size of new created shell view windows - update_clnt_rect(); + set_url(url); } } diff --git a/reactos/subsys/system/explorer/shell/ntobjfs.h b/reactos/subsys/system/explorer/shell/ntobjfs.h index 9330198586e..fe5c4b2a615 100644 --- a/reactos/subsys/system/explorer/shell/ntobjfs.h +++ b/reactos/subsys/system/explorer/shell/ntobjfs.h @@ -117,6 +117,6 @@ struct NtObjDirectory : public NtObjEntry, public Directory _path = NULL; } - virtual void read_directory(int scan_flags=SCAN_ALL); + virtual void read_directory(int scan_flags=0); virtual Entry* find_entry(const void*); }; diff --git a/reactos/subsys/system/explorer/shell/pane.cpp b/reactos/subsys/system/explorer/shell/pane.cpp index d8e46301d62..a3fe36f4fde 100644 --- a/reactos/subsys/system/explorer/shell/pane.cpp +++ b/reactos/subsys/system/explorer/shell/pane.cpp @@ -648,7 +648,6 @@ void Pane::calc_tabbed_width(LPDRAWITEMSTRUCT dis, int col, LPCTSTR str) DrawTextEx(dis->hDC, (LPTSTR)str, -1, &rt, DT_CALCRECT|DT_SINGLELINE|DT_NOPREFIX|DT_EXPANDTABS|DT_TABSTOP, &dtp);*/ DrawText(dis->hDC, (LPTSTR)str, -1, &rt, DT_CALCRECT|DT_SINGLELINE|DT_EXPANDTABS|DT_TABSTOP|(2<<8)); - //FIXME rt (0,0) ??? if (rt.right > _widths[col]) _widths[col] = rt.right; diff --git a/reactos/subsys/system/explorer/shell/regfs.h b/reactos/subsys/system/explorer/shell/regfs.h index 33338244ad7..44598fc56b1 100644 --- a/reactos/subsys/system/explorer/shell/regfs.h +++ b/reactos/subsys/system/explorer/shell/regfs.h @@ -50,7 +50,7 @@ struct RegDirectory : public RegEntry, public Directory _path = NULL; } - virtual void read_directory(int scan_flags=SCAN_ALL); + virtual void read_directory(int scan_flags=0); virtual const void* get_next_path_component(const void*) const; virtual Entry* find_entry(const void*); @@ -78,5 +78,5 @@ struct RegistryRoot : public RegEntry, public Directory _path = NULL; } - virtual void read_directory(int scan_flags=SCAN_ALL); + virtual void read_directory(int scan_flags=0); }; diff --git a/reactos/subsys/system/explorer/shell/shellbrowser.cpp b/reactos/subsys/system/explorer/shell/shellbrowser.cpp index 8e138e09dad..28e9588d9f2 100644 --- a/reactos/subsys/system/explorer/shell/shellbrowser.cpp +++ b/reactos/subsys/system/explorer/shell/shellbrowser.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2003, 2004, 2005 Martin Fuchs + * Copyright 2003, 2004, 2005, 2006 Martin Fuchs * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -37,7 +37,7 @@ const LPCTSTR C_DRIVE = C_DRIVE_STR; #endif -ShellBrowser::ShellBrowser(HWND hwnd, HWND left_hwnd, WindowHandle& right_hwnd, ShellPathInfo& create_info, +ShellBrowser::ShellBrowser(HWND hwnd, HWND hwndFrame, HWND left_hwnd, WindowHandle& right_hwnd, ShellPathInfo& create_info, BrowserCallback* cb, CtxMenuInterfaces& cm_ifs) #ifndef __MINGW32__ // IShellFolderViewCB missing in MinGW (as of 25.09.2005) : super(IID_IShellFolderViewCB), @@ -45,6 +45,7 @@ ShellBrowser::ShellBrowser(HWND hwnd, HWND left_hwnd, WindowHandle& right_hwnd, : #endif _hwnd(hwnd), + _hwndFrame(hwndFrame), _left_hwnd(left_hwnd), _right_hwnd(right_hwnd), _create_info(create_info), @@ -81,12 +82,10 @@ ShellBrowser::~ShellBrowser() } -LRESULT ShellBrowser::Init(HWND hWndFrame) +void ShellBrowser::Init() { CONTEXT("ShellBrowser::Init()"); - _hWndFrame = hWndFrame; - const String& root_name = GetDesktopFolder().get_name(_create_info._root_shell_path, SHGDN_FORADDRESSBAR); _root._drive_type = DRIVE_UNKNOWN; @@ -96,22 +95,23 @@ LRESULT ShellBrowser::Init(HWND hWndFrame) _root._entry = new ShellDirectory(GetDesktopFolder(), _create_info._root_shell_path, _hwnd); - jump_to(_create_info._shell_path); + _root._entry->read_directory(SCAN_DONT_ACCESS|SCAN_NO_FILESYSTEM); // avoid to handle desktop root folder as file system directory + + if (_left_hwnd) { + InitializeTree(); + InitDragDrop(); + } - // -> set_curdir() - _root._entry->read_directory(); + jump_to(_create_info._shell_path); /* already filled by ShellDirectory constructor lstrcpy(_root._entry->_data.cFileName, TEXT("Desktop")); */ - - return 0; } void ShellBrowser::jump_to(LPCITEMIDLIST pidl) { Entry* entry = NULL; - //@@ if (!_cur_dir) _cur_dir = static_cast(_root._entry); @@ -129,7 +129,7 @@ void ShellBrowser::jump_to(LPCITEMIDLIST pidl) if (!child_pidl || !child_pidl->mkid.cb) break; - _cur_dir->smart_scan(); + _cur_dir->smart_scan(SORT_NAME, SCAN_DONT_ACCESS); entry = _cur_dir->find_entry(child_pidl); if (!entry) @@ -139,7 +139,7 @@ void ShellBrowser::jump_to(LPCITEMIDLIST pidl) _callback->entry_selected(entry); } } else { - _cur_dir->smart_scan(); + _cur_dir->smart_scan(SORT_NAME, SCAN_DONT_ACCESS); entry = _cur_dir->find_entry(pidl); // This is not correct in the common case, but works on the desktop level. @@ -211,30 +211,6 @@ bool ShellBrowser::InitDragDrop() } -void ShellBrowser::OnTreeItemRClick(int idCtrl, LPNMHDR pnmh) -{ - CONTEXT("ShellBrowser::OnTreeItemRClick()"); - - TVHITTESTINFO tvhti; - - GetCursorPos(&tvhti.pt); - ScreenToClient(_left_hwnd, &tvhti.pt); - - tvhti.flags = LVHT_NOWHERE; - (void)TreeView_HitTest(_left_hwnd, &tvhti); - - if (TVHT_ONITEM & tvhti.flags) { - LPARAM itemData = TreeView_GetItemData(_left_hwnd, tvhti.hItem); - - if (itemData) { - Entry* entry = (Entry*)itemData; - ClientToScreen(_left_hwnd, &tvhti.pt); - - CHECKERROR(entry->do_context_menu(_hwnd, tvhti.pt, _cm_ifs)); - } - } -} - void ShellBrowser::OnTreeGetDispInfo(int idCtrl, LPNMHDR pnmh) { CONTEXT("ShellBrowser::OnTreeGetDispInfo()"); @@ -289,6 +265,7 @@ void ShellBrowser::invalidate_cache() _image_map.clear(); } + void ShellBrowser::OnTreeItemExpanding(int idCtrl, LPNMTREEVIEW pnmtv) { CONTEXT("ShellBrowser::OnTreeItemExpanding()"); @@ -325,7 +302,7 @@ int ShellBrowser::InsertSubitems(HTREEITEM hParentItem, Entry* entry, IShellFold SendMessage(_left_hwnd, WM_SETREDRAW, FALSE, 0); try { - entry->smart_scan(); + entry->smart_scan(SORT_NAME, SCAN_DONT_ACCESS); } catch(COMException& e) { HandleException(e, g_Globals._hMainWnd); } @@ -344,6 +321,16 @@ int ShellBrowser::InsertSubitems(HTREEITEM hParentItem, Entry* entry, IShellFold if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) #endif { + // ignore hidden directories + if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) + continue; + + // ignore directory entries "." and ".." + if (entry->_data.cFileName[0]==TEXT('.') && + (entry->_data.cFileName[1]==TEXT('\0') || + (entry->_data.cFileName[1]==TEXT('.') && entry->_data.cFileName[2]==TEXT('\0')))) + continue; + ZeroMemory(&tvItem, sizeof(tvItem)); tvItem.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN; @@ -363,9 +350,9 @@ int ShellBrowser::InsertSubitems(HTREEITEM hParentItem, Entry* entry, IShellFold tvInsert.hParent = hParentItem; (void)TreeView_InsertItem(_left_hwnd, &tvInsert); - } - ++cnt; + ++cnt; + } } SendMessage(_left_hwnd, WM_SETREDRAW, TRUE, 0); @@ -373,11 +360,12 @@ int ShellBrowser::InsertSubitems(HTREEITEM hParentItem, Entry* entry, IShellFold return cnt; } + void ShellBrowser::OnTreeItemSelected(int idCtrl, LPNMTREEVIEW pnmtv) { CONTEXT("ShellBrowser::OnTreeItemSelected()"); - ShellEntry* entry = (ShellEntry*)pnmtv->itemNew.lParam; + Entry* entry = (Entry*)pnmtv->itemNew.lParam; _last_sel = pnmtv->itemNew.hItem; @@ -385,6 +373,32 @@ void ShellBrowser::OnTreeItemSelected(int idCtrl, LPNMTREEVIEW pnmtv) _callback->entry_selected(entry); } + +void ShellBrowser::OnTreeItemRClick(int idCtrl, LPNMHDR pnmh) +{ + CONTEXT("ShellBrowser::OnTreeItemRClick()"); + + TVHITTESTINFO tvhti; + + GetCursorPos(&tvhti.pt); + ScreenToClient(_left_hwnd, &tvhti.pt); + + tvhti.flags = LVHT_NOWHERE; + (void)TreeView_HitTest(_left_hwnd, &tvhti); + + if (TVHT_ONITEM & tvhti.flags) { + LPARAM itemData = TreeView_GetItemData(_left_hwnd, tvhti.hItem); + + if (itemData) { + Entry* entry = (Entry*)itemData; + ClientToScreen(_left_hwnd, &tvhti.pt); + + CHECKERROR(entry->do_context_menu(_hwnd, tvhti.pt, _cm_ifs)); + } + } +} + + void ShellBrowser::UpdateFolderView(IShellFolder* folder) { CONTEXT("ShellBrowser::UpdateFolderView()"); @@ -461,7 +475,7 @@ HRESULT ShellBrowser::OnDefaultCommand(LPIDA pida) if (parent) { try { - parent->smart_scan(); + parent->smart_scan(SORT_NAME, SCAN_DONT_ACCESS); } catch(COMException& e) { return e.Error(); } @@ -475,10 +489,13 @@ HRESULT ShellBrowser::OnDefaultCommand(LPIDA pida) if (entry->_etype == ET_SHELL) if (_last_sel && select_entry(_last_sel, entry)) return S_OK; + + //@todo look for hidden or new subfolders and refresh/add new entry instead of opening a new window + return E_NOTIMPL; } } } else { // no tree control - if (MainFrameBase::OpenShellFolders(pida, _hWndFrame)) + if (MainFrameBase::OpenShellFolders(pida, _hwndFrame)) return S_OK; /* create new Frame Window @@ -534,7 +551,7 @@ bool ShellBrowser::jump_to_pidl(LPCITEMIDLIST pidl) if (!entry || !hitem) break; - entry->smart_scan(SORT_NAME); + entry->smart_scan(SORT_NAME, SCAN_DONT_ACCESS); Entry* found = entry->find_entry(p); p = entry->get_next_path_component(p); @@ -549,12 +566,40 @@ bool ShellBrowser::jump_to_pidl(LPCITEMIDLIST pidl) } +bool ShellBrowser::select_folder(Entry* entry, bool expand) +{ + CONTEXT("ShellBrowser::expand_folder()"); + + if (!_last_sel) + return false; + + if (!TreeView_Expand(_left_hwnd, _last_sel, TVE_EXPAND)) + return false; + + for(HTREEITEM hitem=TreeView_GetChild(_left_hwnd,_last_sel); hitem; hitem=TreeView_GetNextSibling(_left_hwnd,hitem)) { + if ((ShellDirectory*)TreeView_GetItemData(_left_hwnd,hitem) == entry) { + if (TreeView_SelectItem(_left_hwnd, hitem)) { + if (expand) + if (!TreeView_Expand(_left_hwnd, hitem, TVE_EXPAND)) + return false; + + return true; + } + + break; + } + } + + return false; +} + + #ifndef _NO_MDI MDIShellBrowserChild::MDIShellBrowserChild(HWND hwnd, const ShellChildWndInfo& info) : super(hwnd, info), _create_info(info), - _shellpath_info(info) //@@ copies info -> no referenz to _create_info ! + _shellpath_info(info) //@@ copies info -> no reference to _create_info ! { /**todo Conversion of shell path into path string -> store into URL history const String& path = GetDesktopFolder().get_name(info._shell_path, SHGDN_FORADDRESSBAR); @@ -585,12 +630,6 @@ LRESULT MDIShellBrowserChild::Init(LPCREATESTRUCT pcs) update_shell_browser(); - if (_shellBrowser.get()) - if (_left_hwnd) - _shellBrowser->Init(); - else - _shellBrowser->UpdateFolderView(_create_info._shell_path.get_folder()); - return 0; } @@ -651,10 +690,10 @@ void MDIShellBrowserChild::update_shell_browser() } } - _shellBrowser = auto_ptr(new ShellBrowser(_hwnd, _left_hwnd, _right_hwnd, + _shellBrowser = auto_ptr(new ShellBrowser(_hwnd, _hwndFrame, _left_hwnd, _right_hwnd, _shellpath_info, this, _cm_ifs)); - _shellBrowser->Init(_hwndFrame); + _shellBrowser->Init(); } @@ -681,38 +720,27 @@ String MDIShellBrowserChild::jump_to_int(LPCTSTR url) void MDIShellBrowserChild::entry_selected(Entry* entry) { - if (entry->_etype == ET_SHELL) { - ShellEntry* shell_entry = static_cast(entry); - IShellFolder* folder; + if (_left_hwnd) + _shellBrowser->select_folder(entry, false); - if (shell_entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - folder = static_cast(shell_entry)->_folder; - else - folder = shell_entry->get_parent_folder(); + _shellBrowser->UpdateFolderView(entry->get_shell_folder()); - if (!folder) { - assert(folder); - return; - } - - TCHAR path[MAX_PATH]; + // set size of new created shell view windows + ClientRect rt(_hwnd); + resize_children(rt.right, rt.bottom); - if (shell_entry->get_path(path, COUNTOF(path))) { - String url; + // set new URL + TCHAR path[MAX_PATH]; - if (path[0] == ':') - url.printf(TEXT("shell://%s"), path); - else - url.printf(TEXT("file://%s"), path); + if (entry->get_path(path, COUNTOF(path))) { + String url; - set_url(url); - } - - _shellBrowser->UpdateFolderView(folder); + if (path[0] == ':') + url.printf(TEXT("shell://%s"), path); + else + url.printf(TEXT("file://%s"), path); - // set size of new created shell view windows - ClientRect rt(_hwnd); - resize_children(rt.right, rt.bottom); + set_url(url); } } diff --git a/reactos/subsys/system/explorer/shell/shellbrowser.h b/reactos/subsys/system/explorer/shell/shellbrowser.h index 43b7ff915d9..3bdce69db7c 100644 --- a/reactos/subsys/system/explorer/shell/shellbrowser.h +++ b/reactos/subsys/system/explorer/shell/shellbrowser.h @@ -61,7 +61,7 @@ struct ShellBrowser : public IShellBrowserImpl , public IComSrvBase, public SimpleComObject #endif { - ShellBrowser(HWND hwnd, HWND left_hwnd, WindowHandle& right_hwnd, ShellPathInfo& create_info, + ShellBrowser(HWND hwnd, HWND hwndFrame, HWND left_hwnd, WindowHandle& right_hwnd, ShellPathInfo& create_info, BrowserCallback* cb, CtxMenuInterfaces& cm_ifs); virtual ~ShellBrowser(); @@ -90,7 +90,7 @@ struct ShellBrowser : public IShellBrowserImpl return S_OK; } - HWND hwnd = (HWND)SendMessage(_hWndFrame, PM_GET_CONTROLWINDOW, id, 0); + HWND hwnd = (HWND)SendMessage(_hwndFrame, PM_GET_CONTROLWINDOW, id, 0); if (hwnd) { *lphwnd = hwnd; @@ -105,7 +105,7 @@ struct ShellBrowser : public IShellBrowserImpl if (!pret) return E_POINTER; - HWND hstatusbar = (HWND)SendMessage(_hWndFrame, PM_GET_CONTROLWINDOW, id, 0); + HWND hstatusbar = (HWND)SendMessage(_hwndFrame, PM_GET_CONTROLWINDOW, id, 0); if (hstatusbar) { *pret = ::SendMessage(hstatusbar, uMsg, wParam, lParam); @@ -122,13 +122,7 @@ struct ShellBrowser : public IShellBrowserImpl void OnTreeItemRClick(int idCtrl, LPNMHDR pnmh); void OnTreeItemSelected(int idCtrl, LPNMTREEVIEW pnmtv); - LRESULT Init(HWND hWndFrame); - - void Init() - { - InitializeTree(); - InitDragDrop(); - } + void Init(); int InsertSubitems(HTREEITEM hParentItem, Entry* entry, IShellFolder* pParentFolder); @@ -139,6 +133,8 @@ struct ShellBrowser : public IShellBrowserImpl void UpdateFolderView(IShellFolder* folder); HTREEITEM select_entry(HTREEITEM hitem, Entry* entry, bool expand=true); + bool select_folder(Entry* entry, bool expand); + // for SDIMainFrame void jump_to(LPCITEMIDLIST pidl); @@ -153,7 +149,7 @@ protected: HIMAGELIST _himl_old; BrowserCallback* _callback; - WindowHandle _hWndFrame; + HWND _hwndFrame; ShellFolder _folder; IShellView* _pShellView; // current hosted shellview @@ -272,7 +268,7 @@ protected: void update_shell_browser(); // interface BrowserCallback - virtual void entry_selected(Entry* entry); + virtual void entry_selected(Entry* entry); }; #endif diff --git a/reactos/subsys/system/explorer/shell/shellfs.cpp b/reactos/subsys/system/explorer/shell/shellfs.cpp index 7eb005a346b..824e70a4550 100644 --- a/reactos/subsys/system/explorer/shell/shellfs.cpp +++ b/reactos/subsys/system/explorer/shell/shellfs.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2003, 2004, 2005 Martin Fuchs + * Copyright 2003, 2004, 2005, 2006 Martin Fuchs * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -228,6 +228,22 @@ HRESULT ShellEntry::GetUIObjectOf(HWND hWnd, REFIID riid, LPVOID* ppvOut) } +ShellFolder Entry::get_shell_folder() const +{ + return ShellFolder(create_absolute_pidl()); +} + +ShellFolder ShellEntry::get_shell_folder() const +{ + return get_parent_folder(); +} + +ShellFolder ShellDirectory::get_shell_folder() const +{ + return _folder; +} + + void ShellDirectory::read_directory(int scan_flags) { CONTEXT("ShellDirectory::read_directory()"); @@ -241,14 +257,13 @@ void ShellDirectory::read_directory(int scan_flags) return;*/ #ifndef _NO_WIN_FS - TCHAR buffer[MAX_PATH]; + TCHAR buffer[_MAX_PATH+_MAX_FNAME]; - if ((scan_flags&SCAN_FILESYSTEM) && get_path(buffer, COUNTOF(buffer)) && _tcsncmp(buffer,TEXT("::{"),3)) { + if (!(scan_flags&SCAN_NO_FILESYSTEM) && get_path(buffer, COUNTOF(buffer)) && _tcsncmp(buffer,TEXT("::{"),3)) { Entry* entry = NULL; // eliminate useless GCC warning by initializing entry LPTSTR p = buffer + _tcslen(buffer); - // TODO FIXME - this can overflow lstrcpy(p, TEXT("\\*")); WIN32_FIND_DATA w32fd; @@ -284,7 +299,7 @@ void ShellDirectory::read_directory(int scan_flags) entry->_level = level; - if (scan_flags & SCAN_DO_ACCESS) { + if (!(scan_flags & SCAN_DONT_ACCESS)) { HANDLE hFile = CreateFile(buffer, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); @@ -325,19 +340,18 @@ void ShellDirectory::read_directory(int scan_flags) if (w32fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) entry->_icon_id = ICID_FOLDER; -/* else if (scan_flags & SCAN_EXTRACT_ICONS) - entry->safe_extract_icon(large_icons); -*/ + else if (!(scan_flags & SCAN_DONT_EXTRACT_ICONS)) + entry->_icon_id = entry->safe_extract_icon(); // Assume small icon, we can extract the large icon later on demand. + last = entry; } while(FindNextFile(hFind, &w32fd)); FindClose(hFind); } } - else // !SCAN_FILESYSTEM + else // SCAN_NO_FILESYSTEM #endif { - ShellItemEnumerator enumerator(_folder, SHCONTF_FOLDERS|SHCONTF_NONFOLDERS|SHCONTF_INCLUDEHIDDEN|SHCONTF_SHAREABLE|SHCONTF_STORAGE); TCHAR name[MAX_PATH]; @@ -376,7 +390,7 @@ void ShellDirectory::read_directory(int scan_flags) if (attribs & SFGAO_REMOVABLE) { attribs |= SFGAO_HASSUBFOLDER; removeable = true; - } else if (scan_flags & SCAN_DO_ACCESS) { + } else if (!(scan_flags & SCAN_DONT_ACCESS)) { DWORD attribs2 = SFGAO_READONLY; HRESULT hr = _folder->GetAttributesOf(1, (LPCITEMIDLIST*)&pidls[n], &attribs2); @@ -388,7 +402,7 @@ void ShellDirectory::read_directory(int scan_flags) attribs = 0; bhfi_valid = fill_w32fdata_shell(pidls[n], attribs, &w32fd, &bhfi, - (scan_flags&SCAN_DO_ACCESS) && !removeable); + !(scan_flags&SCAN_DONT_ACCESS) && !removeable); try { Entry* entry = NULL; // eliminate useless GCC warning by initializing entry @@ -429,9 +443,9 @@ void ShellDirectory::read_directory(int scan_flags) // get icons for files and virtual objects if (!(entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) || !(attribs & SFGAO_FILESYSTEM)) { -/* if (scan_flags & SCAN_EXTRACT_ICONS) - entry->extract_icon(large_icons); -*/ } else if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + if (!(scan_flags & SCAN_DONT_EXTRACT_ICONS)) + entry->_icon_id = entry->safe_extract_icon(); // Assume small icon, we can extract the large icon later on demand. + } else if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) entry->_icon_id = ICID_FOLDER; else entry->_icon_id = ICID_NONE; // don't try again later @@ -478,6 +492,16 @@ Entry* ShellDirectory::find_entry(const void* p) if (se->_pidl && se->_pidl->mkid.cb==pidl->mkid.cb && !memcmp(se->_pidl, pidl, se->_pidl->mkid.cb)) return entry; + } else { + const ShellPath& sp = entry->create_absolute_pidl(); + static DynamicFct ILFindLastID(TEXT("SHELL32"), "ILFindLastID"); + + if (ILFindLastID) { + LPCITEMIDLIST entry_pidl = (*ILFindLastID)(sp); + + if (entry_pidl && entry_pidl->mkid.cb==pidl->mkid.cb && !memcmp(entry_pidl, pidl, entry_pidl->mkid.cb)) + return entry; + } } return NULL; diff --git a/reactos/subsys/system/explorer/shell/shellfs.h b/reactos/subsys/system/explorer/shell/shellfs.h index 6467eb69018..979c58eaaca 100644 --- a/reactos/subsys/system/explorer/shell/shellfs.h +++ b/reactos/subsys/system/explorer/shell/shellfs.h @@ -37,6 +37,7 @@ struct ShellEntry : public Entry virtual HRESULT GetUIObjectOf(HWND hWnd, REFIID riid, LPVOID* ppvOut); virtual BOOL launch_entry(HWND hwnd, UINT nCmdShow=SW_SHOWNORMAL); virtual HRESULT do_context_menu(HWND hwnd, LPPOINT pptScreen, CtxMenuInterfaces& cm_ifs); + virtual ShellFolder get_shell_folder() const; IShellFolder* get_parent_folder() const; @@ -99,11 +100,12 @@ struct ShellDirectory : public ShellEntry, public Directory pFolder->Release(); } - virtual void read_directory(int scan_flags=SCAN_ALL); + virtual void read_directory(int scan_flags=0); virtual const void* get_next_path_component(const void*) const; virtual Entry* find_entry(const void*); virtual bool get_path(PTSTR path, size_t path_count) const; + virtual ShellFolder get_shell_folder() const; int extract_icons(ICONCACHE_FLAGS flags); diff --git a/reactos/subsys/system/explorer/shell/winfs.cpp b/reactos/subsys/system/explorer/shell/winfs.cpp index dba53e7c5b4..a2a1c8802e8 100644 --- a/reactos/subsys/system/explorer/shell/winfs.cpp +++ b/reactos/subsys/system/explorer/shell/winfs.cpp @@ -140,19 +140,6 @@ void WinDirectory::read_directory(int scan_flags) if (hFind != INVALID_HANDLE_VALUE) { do { -#ifdef _NO_WIN_FS //@todo not really correct: We shouldn't hide . and .. - // ignore hidden files (usefull in the start menu) - if (w32fd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) - continue; - - // ignore directory entries "." and ".." - if ((w32fd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) && - w32fd.cFileName[0]==TEXT('.') && - (w32fd.cFileName[1]==TEXT('\0') || - (w32fd.cFileName[1]==TEXT('.') && w32fd.cFileName[2]==TEXT('\0')))) - continue; -#endif - lstrcpy(pname+1, w32fd.cFileName); if (w32fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) @@ -172,7 +159,7 @@ void WinDirectory::read_directory(int scan_flags) // display file type names, but don't hide file extensions g_Globals._ftype_mgr.set_type(entry, true); - if (scan_flags & SCAN_DO_ACCESS) { + if (!(scan_flags & SCAN_DONT_ACCESS)) { HANDLE hFile = CreateFile(buffer, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); @@ -247,7 +234,7 @@ Entry* WinDirectory::find_entry(const void* p) // get full path of specified directory entry bool WinEntry::get_path(PTSTR path, size_t path_count) const { - return get_path_base ( path, path_count, ET_WINDOWS ); + return get_path_base(path, path_count, ET_WINDOWS); } ShellPath WinEntry::create_absolute_pidl() const diff --git a/reactos/subsys/system/explorer/shell/winfs.h b/reactos/subsys/system/explorer/shell/winfs.h index 2bc861d051c..c2954b461e0 100644 --- a/reactos/subsys/system/explorer/shell/winfs.h +++ b/reactos/subsys/system/explorer/shell/winfs.h @@ -60,7 +60,7 @@ struct WinDirectory : public WinEntry, public Directory _path = NULL; } - virtual void read_directory(int scan_flags=SCAN_ALL); + virtual void read_directory(int scan_flags=0); virtual const void* get_next_path_component(const void*) const; virtual Entry* find_entry(const void*); }; diff --git a/reactos/subsys/system/explorer/taskbar/favorites.cpp b/reactos/subsys/system/explorer/taskbar/favorites.cpp index 2b8a2dc5ece..ea35c4a42f0 100644 --- a/reactos/subsys/system/explorer/taskbar/favorites.cpp +++ b/reactos/subsys/system/explorer/taskbar/favorites.cpp @@ -373,7 +373,7 @@ void BookmarkList::import_IE_favorites(ShellDirectory& dir, HWND hwnd) { TCHAR path[MAX_PATH], ext[_MAX_EXT]; - dir.smart_scan(SORT_NAME, SCAN_FILESYSTEM); + dir.smart_scan(SORT_NAME, SCAN_DONT_EXTRACT_ICONS); for(Entry*entry=dir._down; entry; entry=entry->_next) { if (entry->_shell_attribs & SFGAO_HIDDEN) // ignore files like "desktop.ini" diff --git a/reactos/subsys/system/explorer/taskbar/quicklaunch.cpp b/reactos/subsys/system/explorer/taskbar/quicklaunch.cpp index 8214d931b21..29c1538720a 100644 --- a/reactos/subsys/system/explorer/taskbar/quicklaunch.cpp +++ b/reactos/subsys/system/explorer/taskbar/quicklaunch.cpp @@ -105,7 +105,7 @@ void QuickLaunchBar::AddShortcuts() RecursiveCreateDirectory(path); _dir = new ShellDirectory(GetDesktopFolder(), path, _hwnd); - _dir->smart_scan(SORT_NAME, /*SCAN_EXTRACT_ICONS|*/SCAN_FILESYSTEM); + _dir->smart_scan(SORT_NAME); // immediatelly extract the shortcut icons for(Entry*entry=_dir->_down; entry; entry=entry->_next) @@ -160,12 +160,12 @@ void QuickLaunchBar::AddShortcuts() if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) continue; - // hide subfolders - if (!(entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { - HBITMAP hbmp = g_Globals._icon_cache.get_icon(entry->_icon_id).create_bitmap(bk_color, bk_brush, canvas); + // hide subfolders + if (!(entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { + HBITMAP hbmp = g_Globals._icon_cache.get_icon(entry->_icon_id).create_bitmap(bk_color, bk_brush, canvas); - AddButton(_next_id++, hbmp, entry->_display_name, entry); //entry->_etype==ET_SHELL? desktop_folder.get_name(static_cast(entry)->_pidl): entry->_display_name); - } + AddButton(_next_id++, hbmp, entry->_display_name, entry); //entry->_etype==ET_SHELL? desktop_folder.get_name(static_cast(entry)->_pidl): entry->_display_name); + } } _btn_dist = LOWORD(SendMessage(_hwnd, TB_GETBUTTONSIZE, 0, 0)); diff --git a/reactos/subsys/system/explorer/taskbar/startmenu.cpp b/reactos/subsys/system/explorer/taskbar/startmenu.cpp index c1864d3752a..83dc2a9d8ce 100644 --- a/reactos/subsys/system/explorer/taskbar/startmenu.cpp +++ b/reactos/subsys/system/explorer/taskbar/startmenu.cpp @@ -218,9 +218,9 @@ void StartMenu::AddEntries() WaitCursor wait; #ifdef _LAZY_ICONEXTRACT - dir.smart_scan(SORT_NAME, SCAN_FILESYSTEM); // lazy icon extraction, try to read directly from filesystem + dir.smart_scan(SORT_NAME, SCAN_DONT_EXTRACT_ICONS); // lazy icon extraction, try to read directly from filesystem #else - dir.smart_scan(SORT_NAME, SCAN_EXTRACT_ICONS|SCAN_FILESYSTEM); + dir.smart_scan(SORT_NAME); #endif } @@ -2208,9 +2208,9 @@ void RecentStartMenu::AddEntries() WaitCursor wait; #ifdef _LAZY_ICONEXTRACT - dir.smart_scan(SORT_NAME, SCAN_FILESYSTEM); + dir.smart_scan(SORT_NAME, SCAN_DONT_EXTRACT_ICONS); #else - dir.smart_scan(SORT_NAME, SCAN_EXTRACT_ICONS|SCAN_FILESYSTEM); + dir.smart_scan(SORT_NAME); #endif } -- 2.17.1