explorer:
authorMartin Fuchs <fuchs.martin@gmail.com>
Sun, 1 Jan 2006 15:21:03 +0000 (15:21 +0000)
committerMartin Fuchs <fuchs.martin@gmail.com>
Sun, 1 Jan 2006 15:21:03 +0000 (15:21 +0000)
- 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

18 files changed:
reactos/subsys/system/explorer/dialogs/searchprogram.cpp
reactos/subsys/system/explorer/doc/changes.txt
reactos/subsys/system/explorer/shell/entries.cpp
reactos/subsys/system/explorer/shell/entries.h
reactos/subsys/system/explorer/shell/fatfs.h
reactos/subsys/system/explorer/shell/mainframe.cpp
reactos/subsys/system/explorer/shell/ntobjfs.h
reactos/subsys/system/explorer/shell/pane.cpp
reactos/subsys/system/explorer/shell/regfs.h
reactos/subsys/system/explorer/shell/shellbrowser.cpp
reactos/subsys/system/explorer/shell/shellbrowser.h
reactos/subsys/system/explorer/shell/shellfs.cpp
reactos/subsys/system/explorer/shell/shellfs.h
reactos/subsys/system/explorer/shell/winfs.cpp
reactos/subsys/system/explorer/shell/winfs.h
reactos/subsys/system/explorer/taskbar/favorites.cpp
reactos/subsys/system/explorer/taskbar/quicklaunch.cpp
reactos/subsys/system/explorer/taskbar/startmenu.cpp

index 6b17550..55c8c03 100644 (file)
@@ -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)
index acd1966..372642f 100644 (file)
@@ -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
index 5782d88..24ea8f0 100644 (file)
@@ -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
 {
index 946c452..2b39fbd 100644 (file)
@@ -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);
 };
index 1824e00..cf97630 100644 (file)
@@ -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*);
 
index 09ae013..eb489a9 100644 (file)
@@ -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<ShellBrowser>(new ShellBrowser(_hwnd, _left_hwnd, _right_hwnd,
+       _shellBrowser = auto_ptr<ShellBrowser>(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<ShellEntry*>(entry);
-               IShellFolder* folder;
-
-               if (shell_entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
-                       folder = static_cast<ShellDirectory*>(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);
        }
 }
 
index 9330198..fe5c4b2 100644 (file)
@@ -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*);
 };
index d8e4630..a3fe36f 100644 (file)
@@ -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;
index 3333824..44598fc 100644 (file)
@@ -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);
 };
index 8e138e0..28e9588 100644 (file)
@@ -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<ShellDirectory*>(_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<ShellBrowser>(new ShellBrowser(_hwnd, _left_hwnd, _right_hwnd,
+       _shellBrowser = auto_ptr<ShellBrowser>(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<ShellEntry*>(entry);
-               IShellFolder* folder;
+       if (_left_hwnd)
+               _shellBrowser->select_folder(entry, false);
 
-               if (shell_entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
-                       folder = static_cast<ShellDirectory*>(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);
        }
 }
 
index 43b7ff9..3bdce69 100644 (file)
@@ -61,7 +61,7 @@ struct ShellBrowser : public IShellBrowserImpl
        ,       public IComSrvBase<IShellFolderViewCB, ShellBrowser>, 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
index 7eb005a..824e70a 100644 (file)
@@ -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<LPITEMIDLIST(WINAPI*)(LPCITEMIDLIST)> 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;
index 6467eb6..979c58e 100644 (file)
@@ -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);
 
index dba53e7..a2a1c88 100644 (file)
@@ -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
index 2bc861d..c2954b4 100644 (file)
@@ -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*);
 };
index 2b8a2dc..ea35c4a 100644 (file)
@@ -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"
index 8214d93..29c1538 100644 (file)
@@ -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<ShellEntry*>(entry)->_pidl): entry->_display_name);
-                       }
+                       AddButton(_next_id++, hbmp, entry->_display_name, entry);       //entry->_etype==ET_SHELL? desktop_folder.get_name(static_cast<ShellEntry*>(entry)->_pidl): entry->_display_name);
+               }
        }
 
        _btn_dist = LOWORD(SendMessage(_hwnd, TB_GETBUTTONSIZE, 0, 0));
index c1864d3..83dc2a9 100644 (file)
@@ -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
                }