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
This commit is contained in:
Martin Fuchs 2006-01-01 15:21:03 +00:00
parent 69288462ca
commit 77932fa09a
18 changed files with 214 additions and 187 deletions

View 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)

View 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

View 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
{

View 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);
};

View 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*);

View 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 (_left_hwnd)
_shellBrowser->select_folder(entry, false);
if (shell_entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
folder = static_cast<ShellDirectory*>(shell_entry)->_folder;
_shellBrowser->UpdateFolderView(entry->get_shell_folder());
// set size of new created shell view windows
resize_children();
TCHAR path[MAX_PATH];
if (entry->get_path(path, COUNTOF(path))) {
String url;
if (path[0] == ':')
url.printf(TEXT("shell://%s"), path);
else
folder = shell_entry->get_parent_folder();
url.printf(TEXT("file://%s"), path);
if (!folder) {
assert(folder);
return;
}
TCHAR path[MAX_PATH];
if (shell_entry->get_path(path, COUNTOF(path))) {
String url;
if (path[0] == ':')
url.printf(TEXT("shell://%s"), path);
else
url.printf(TEXT("file://%s"), path);
set_url(url);
}
_shellBrowser->UpdateFolderView(folder);
// update _clnt_rect and set size of new created shell view windows
update_clnt_rect();
set_url(url);
}
}

View 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*);
};

View 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;

View 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);
};

View 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
// -> set_curdir()
_root._entry->read_directory();
if (_left_hwnd) {
InitializeTree();
InitDragDrop();
}
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;
_shellBrowser->UpdateFolderView(entry->get_shell_folder());
// set size of new created shell view windows
ClientRect rt(_hwnd);
resize_children(rt.right, rt.bottom);
// set new URL
TCHAR path[MAX_PATH];
if (entry->get_path(path, COUNTOF(path))) {
String url;
if (path[0] == ':')
url.printf(TEXT("shell://%s"), path);
else
folder = shell_entry->get_parent_folder();
url.printf(TEXT("file://%s"), path);
if (!folder) {
assert(folder);
return;
}
TCHAR path[MAX_PATH];
if (shell_entry->get_path(path, COUNTOF(path))) {
String url;
if (path[0] == ':')
url.printf(TEXT("shell://%s"), path);
else
url.printf(TEXT("file://%s"), path);
set_url(url);
}
_shellBrowser->UpdateFolderView(folder);
// set size of new created shell view windows
ClientRect rt(_hwnd);
resize_children(rt.right, rt.bottom);
set_url(url);
}
}

View 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

View 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;

View 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);

View 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

View 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*);
};

View 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"

View 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));

View 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
}