/*
- * Copyright 2003, 2004 Martin Fuchs
+ * Copyright 2003, 2004, 2005 Martin Fuchs
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
//
-#include "precomp.h"
+#include <precomp.h>
-#include "../explorer_intres.h"
+#include "../resource.h"
+
+
+ // work around GCC's wide string constant bug
+#ifdef __GNUC__
+const LPCTSTR C_DRIVE = C_DRIVE_STR;
+#endif
ShellBrowser::ShellBrowser(HWND hwnd, HWND left_hwnd, WindowHandle& right_hwnd, ShellPathInfo& create_info,
- HIMAGELIST himl, BrowserCallback* cb, CtxMenuInterfaces& cm_ifs)
- : _hwnd(hwnd),
+ BrowserCallback* cb, CtxMenuInterfaces& cm_ifs)
+#ifndef __MINGW32__ // IShellFolderViewCB missing in MinGW (as of 25.09.2005)
+ : super(IID_IShellFolderViewCB),
+#else
+ :
+#endif
+ _hwnd(hwnd),
_left_hwnd(left_hwnd),
_right_hwnd(right_hwnd),
_create_info(create_info),
- _himl(himl),
_callback(cb),
_cm_ifs(cm_ifs)
{
_last_sel = 0;
_cur_dir = NULL;
+
+ _himl = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_MASK|ILC_COLOR24, 2, 0);
+ ImageList_SetBkColor(_himl, GetSysColor(COLOR_WINDOW));
}
ShellBrowser::~ShellBrowser()
{
+ (void)TreeView_SetImageList(_left_hwnd, _himl_old, TVSIL_NORMAL);
+ ImageList_Destroy(_himl);
+
if (_pShellView)
_pShellView->Release();
_hWndFrame = hWndFrame;
- const String& root_name = GetDesktopFolder().get_name(_create_info._root_shell_path, SHGDN_FORPARSING);
+ const String& root_name = GetDesktopFolder().get_name(_create_info._root_shell_path, SHGDN_FORADDRESSBAR);
_root._drive_type = DRIVE_UNKNOWN;
lstrcpy(_root._volname, root_name);
if (!_cur_dir)
_cur_dir = static_cast<ShellDirectory*>(_root._entry);
-/*@todo
- we should call read_tree() here to iterate through the hierarchy and open all folders from shell_info._root_shell_path to shell_info._shell_path
- _root._entry->read_tree(shell_info._root_shell_path.get_folder(), info._shell_path, SORT_NAME);
- -> see FileChildWindow::FileChildWindow()
-*/
+ //LOG(FmtString(TEXT("ShellBrowser::jump_to(): pidl=%s"), (LPCTSTR)FileSysShellPath(pidl)));
if (_cur_dir) {
static DynamicFct<LPITEMIDLIST(WINAPI*)(LPCITEMIDLIST, LPCITEMIDLIST)> ILFindChild(TEXT("SHELL32"), 24);
+/*@todo
+ we should call read_tree() here to iterate through the hierarchy and open all folders from _create_info._root_shell_path (_cur_dir) to _create_info._shell_path (pidl)
+ _root._entry->read_tree(_create_info._root_shell_path.get_folder(), info._shell_path, SORT_NAME);
+ -> see FileChildWindow::FileChildWindow()_create_info._shell_path
+*/
+
LPCITEMIDLIST child_pidl;
if (ILFindChild)
entry = _cur_dir->find_entry(child_pidl);
- if (entry)
+ if (entry) {
+ _cur_dir = static_cast<ShellDirectory*>(entry);
_callback->entry_selected(entry);
+ }
}
}
}
-void ShellBrowser::InitializeTree(HIMAGELIST himl)
+void ShellBrowser::InitializeTree()
{
CONTEXT("ShellBrowserChild::InitializeTree()");
- TreeView_SetImageList(_left_hwnd, himl, TVSIL_NORMAL);
+ _himl_old = TreeView_SetImageList(_left_hwnd, _himl, TVSIL_NORMAL);
TreeView_SetScrollTime(_left_hwnd, 100);
TV_INSERTSTRUCT tvInsert;
+ TV_ITEM& tvItem = tvInsert.item;
tvInsert.hParent = 0;
tvInsert.hInsertAfter = TVI_LAST;
- TV_ITEM& tvItem = tvInsert.item;
tvItem.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN;
tvItem.lParam = (LPARAM)_root._entry;
- tvItem.pszText = LPSTR_TEXTCALLBACK;
+ tvItem.pszText = _root._volname; //LPSTR_TEXTCALLBACK;
tvItem.iImage = tvItem.iSelectedImage = I_IMAGECALLBACK;
tvItem.cChildren = 1;
_pDropTarget->Release(); // free TreeDropTarget
_pDropTarget = NULL;
return false;
- }
- else
+ } else
_pDropTarget->Release();
FORMATETC ftetc;
ScreenToClient(_left_hwnd, &tvhti.pt);
tvhti.flags = LVHT_NOWHERE;
- TreeView_HitTest(_left_hwnd, &tvhti);
+ (void)TreeView_HitTest(_left_hwnd, &tvhti);
if (TVHT_ONITEM & tvhti.flags) {
LPARAM itemData = TreeView_GetItemData(_left_hwnd, tvhti.hItem);
if (lpdi->item.mask & TVIF_TEXT)
lpdi->item.pszText = entry->_display_name;
- if (lpdi->item.mask & (/*TVIF_TEXT|*/TVIF_IMAGE|TVIF_SELECTEDIMAGE)) {
- ShellPath pidl_abs = entry->create_absolute_pidl(); // Caching of absolute PIDLs could enhance performance.
- LPCITEMIDLIST pidl = pidl_abs;
-
- SHFILEINFO sfi;
-/*
- if (lpdi->item.mask & TVIF_TEXT)
- if (SHGetFileInfo((LPCTSTR)pidl, 0, &sfi, sizeof(sfi), SHGFI_PIDL|SHGFI_DISPLAYNAME))
- lstrcpy(lpdi->item.pszText, sfi.szDisplayName); ///@todo look at cchTextMax if there is enough space available
- else
- lpdi->item.pszText = entry->_data.cFileName;
-*/
+ if (lpdi->item.mask & (TVIF_IMAGE|TVIF_SELECTEDIMAGE)) {
if (lpdi->item.mask & TVIF_IMAGE)
- if ((HIMAGELIST)SHGetFileInfo((LPCTSTR)pidl, 0, &sfi, sizeof(sfi), SHGFI_PIDL|SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_LINKOVERLAY) == _himl)
- lpdi->item.iImage = sfi.iIcon;
- else
- lpdi->item.iImage = -1;
+ lpdi->item.iImage = get_image_idx(
+ entry->safe_extract_icon((ICONCACHE_FLAGS)(ICF_HICON|ICF_OVERLAYS)));
if (lpdi->item.mask & TVIF_SELECTEDIMAGE)
- if ((HIMAGELIST)SHGetFileInfo((LPCTSTR)pidl, 0, &sfi, sizeof(sfi), SHGFI_PIDL|SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_OPENICON) == _himl)
- lpdi->item.iSelectedImage = sfi.iIcon;
- else
- lpdi->item.iSelectedImage = -1;
+ lpdi->item.iSelectedImage = get_image_idx(
+ entry->safe_extract_icon((ICONCACHE_FLAGS)(ICF_HICON|ICF_OVERLAYS|ICF_OPEN)));
}
}
}
+int ShellBrowser::get_image_idx(int icon_id)
+{
+ if (icon_id != ICID_NONE) {
+ map<int,int>::const_iterator found = _image_map.find(icon_id);
+
+ if (found != _image_map.end())
+ return found->second;
+
+ int idx = ImageList_AddIcon(_himl, g_Globals._icon_cache.get_icon(icon_id).get_hicon());
+
+ _image_map[icon_id] = idx;
+
+ return idx;
+ } else
+ return -1;
+}
+
+void ShellBrowser::invalidate_cache()
+{
+ (void)TreeView_SetImageList(_left_hwnd, _himl_old, TVSIL_NORMAL);
+ ImageList_Destroy(_himl);
+
+ _himl_old = TreeView_SetImageList(_left_hwnd, _himl, TVSIL_NORMAL);
+ _himl = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_MASK|ILC_COLOR24, 2, 0);
+
+ for(map<int,int>::const_iterator it=_image_map.begin(); it!=_image_map.end(); ++it)
+ g_Globals._icon_cache.free_icon(it->first);
+
+ _image_map.clear();
+}
+
void ShellBrowser::OnTreeItemExpanding(int idCtrl, LPNMTREEVIEW pnmtv)
{
CONTEXT("ShellBrowser::OnTreeItemExpanding()");
tvInsert.hInsertAfter = TVI_LAST;
tvInsert.hParent = hParentItem;
- TreeView_InsertItem(_left_hwnd, &tvInsert);
+ (void)TreeView_InsertItem(_left_hwnd, &tvInsert);
}
++cnt;
fs.fFlags = FWF_NOCLIENTEDGE|FWF_BESTFITWINDOW;
}
+#ifndef __MINGW32__ // IShellFolderViewCB missing in MinGW (as of 25.09.2005)
+ SFV_CREATE sfv_create;
+
+ sfv_create.cbSize = sizeof(SFV_CREATE);
+ sfv_create.pshf = folder;
+ sfv_create.psvOuter = NULL;
+ sfv_create.psfvcb = this;
+
+ HRESULT hr = SHCreateShellFolderView(&sfv_create, &_pShellView);
+#else
HRESULT hr = folder->CreateViewObject(_hwnd, IID_IShellView, (void**)&_pShellView);
+#endif
if (FAILED(hr)) {
_pShellView = NULL;
}
+#ifndef __MINGW32__ // IShellFolderViewCB missing in MinGW (as of 25.09.2005)
+
+ /// shell view callback
+HRESULT STDMETHODCALLTYPE ShellBrowser::MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ if (uMsg == SFVM_INITMENUPOPUP) {
+ //@todo never reached
+ InsertMenu((HMENU)lParam, 0, MF_BYPOSITION, 12345, TEXT("TEST ENTRY"));
+ return S_OK;
+ }
+
+ return E_NOTIMPL;
+}
+
+#endif
+
+
HRESULT ShellBrowser::OnDefaultCommand(LPIDA pida)
{
CONTEXT("ShellBrowser::OnDefaultCommand()");
_shellpath_info(info) //@@ copies info -> no referenz 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);
+ const String& parsingpath = GetDesktopFolder().get_name(info._shell_path, SHGDN_FORPARSING);
+
// store path into history
if (info._path && *info._path)
_url_history.push(info._path);
if (super::Init(pcs))
return 1;
- init_himl();
-
update_shell_browser();
- if (&*_shellBrowser)
+ if (_shellBrowser.get())
if (_left_hwnd)
- _shellBrowser->Init(_himlSmall);
+ _shellBrowser->Init();
else
_shellBrowser->UpdateFolderView(_create_info._shell_path.get_folder());
case ID_REFRESH:
//@todo refresh shell child
+ _shellBrowser->invalidate_cache();
break;
case ID_VIEW_SDI:
- MainFrameBase::Create(_url, false);
+ MainFrameBase::Create(ExplorerCmd(_url, false));
break;
default:
delete _shellBrowser.release();
}
+ ///@todo use OWM_ROOTED flag
+
// create explorer treeview
if (_create_info._open_mode & OWM_EXPLORE) {
if (!_left_hwnd) {
}
_shellBrowser = auto_ptr<ShellBrowser>(new ShellBrowser(_hwnd, _left_hwnd, _right_hwnd,
- _shellpath_info, _himlSmall, this, _cm_ifs));
+ _shellpath_info, this, _cm_ifs));
_shellBrowser->Init(_hwndFrame);
}
TCHAR path[MAX_PATH];
- if (shell_entry->get_path(path)) {
+ if (shell_entry->get_path(path, COUNTOF(path))) {
String url;
if (path[0] == ':')