/*
- * Copyright 2003 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 "../utility/utility.h"
+#include <precomp.h>
-#include "../explorer.h"
-#include "../globals.h"
+#include "../resource.h"
-#include "../explorer_intres.h"
-
-static LPARAM TreeView_GetItemData(HWND hwndTreeView, HTREEITEM hItem)
-{
- TVITEM tvItem;
-
- tvItem.mask = TVIF_PARAM;
- tvItem.hItem = hItem;
-
- if (!TreeView_GetItem(hwndTreeView, &tvItem))
- return 0;
-
- return tvItem.lParam;
-}
+ // work around GCC's wide string constant bug
+#ifdef __GNUC__
+const LPCTSTR C_DRIVE = C_DRIVE_STR;
+#endif
-ShellBrowserChild::ShellBrowserChild(HWND hwnd, HWND left_hwnd, WindowHandle& right_hwnd, ShellPathInfo& create_info)
- : _hwnd(hwnd),
+ShellBrowser::ShellBrowser(HWND hwnd, 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),
+#else
+ :
+#endif
+ _hwnd(hwnd),
_left_hwnd(left_hwnd),
_right_hwnd(right_hwnd),
- _create_info(create_info)
+ _create_info(create_info),
+ _callback(cb),
+ _cm_ifs(cm_ifs)
{
_pShellView = NULL;
_pDropTarget = NULL;
- _himlSmall = 0;
_last_sel = 0;
- // SDI integration
- _split_pos = DEFAULT_SPLIT_POS;
- _last_split = DEFAULT_SPLIT_POS;
-
_cur_dir = NULL;
- Init(hwnd);
+ _himl = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_MASK|ILC_COLOR24, 2, 0);
+ ImageList_SetBkColor(_himl, GetSysColor(COLOR_WINDOW));
}
-ShellBrowserChild::~ShellBrowserChild()
+ShellBrowser::~ShellBrowser()
{
+ (void)TreeView_SetImageList(_left_hwnd, _himl_old, TVSIL_NORMAL);
+ ImageList_Destroy(_himl);
+
if (_pShellView)
_pShellView->Release();
}
-LRESULT ShellBrowserChild::Init(HWND hWndFrame)
+LRESULT ShellBrowser::Init(HWND hWndFrame)
{
- CONTEXT("ShellBrowserChild::Init()");
+ CONTEXT("ShellBrowser::Init()");
_hWndFrame = hWndFrame;
- ClientRect rect(_hwnd);
-
- SHFILEINFO sfi;
-
- _himlSmall = (HIMAGELIST)SHGetFileInfo(TEXT("C:\\"), 0, &sfi, sizeof(SHFILEINFO), SHGFI_SYSICONINDEX|SHGFI_SMALLICON);
-// _himlLarge = (HIMAGELIST)SHGetFileInfo(TEXT("C:\\"), 0, &sfi, sizeof(SHFILEINFO), SHGFI_SYSICONINDEX|SHGFI_LARGEICON);
-
- if (_left_hwnd) {
- InitializeTree();
- InitDragDrop();
- }
-
- 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); // most of the time "Desktop"
+ lstrcpy(_root._volname, root_name);
_root._fs_flags = 0;
lstrcpy(_root._fs, TEXT("Desktop"));
_root._entry = new ShellDirectory(GetDesktopFolder(), _create_info._root_shell_path, _hwnd);
- jump_to((void*)(LPCITEMIDLIST)_create_info._shell_path);
+ jump_to(_create_info._shell_path);
// -> set_curdir()
_root._entry->read_directory();
return 0;
}
+void ShellBrowser::jump_to(LPCITEMIDLIST pidl)
+{
+ Entry* entry = NULL;
+
+ //@@
+ if (!_cur_dir)
+ _cur_dir = static_cast<ShellDirectory*>(_root._entry);
+
+ //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)
+ child_pidl = (*ILFindChild)(_cur_dir->create_absolute_pidl(), pidl);
+ else
+ child_pidl = pidl; // This is not correct in the common case, but works on the desktop level.
+
+ if (child_pidl) {
+ _cur_dir->smart_scan();
+
+ entry = _cur_dir->find_entry(child_pidl);
+
+ if (entry) {
+ _cur_dir = static_cast<ShellDirectory*>(entry);
+ _callback->entry_selected(entry);
+ }
+ }
+ }
+
+ //@@ work around as long as we don't iterate correctly through the ShellEntry tree
+ if (!entry)
+ UpdateFolderView(ShellFolder(pidl));
+}
+
-void ShellBrowserChild::InitializeTree()
+void ShellBrowser::InitializeTree()
{
CONTEXT("ShellBrowserChild::InitializeTree()");
- TreeView_SetImageList(_left_hwnd, _himlSmall, TVSIL_NORMAL);
+ _himl_old = TreeView_SetImageList(_left_hwnd, _himl, TVSIL_NORMAL);
TreeView_SetScrollTime(_left_hwnd, 100);
- TV_ITEM tvItem;
+ TV_INSERTSTRUCT tvInsert;
+ TV_ITEM& tvItem = tvInsert.item;
+
+ tvInsert.hParent = 0;
+ tvInsert.hInsertAfter = TVI_LAST;
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;
- TV_INSERTSTRUCT tvInsert;
-
- tvInsert.hParent = 0;
- tvInsert.hInsertAfter = TVI_LAST;
- tvInsert.item = tvItem;
-
HTREEITEM hItem = TreeView_InsertItem(_left_hwnd, &tvInsert);
TreeView_SelectItem(_left_hwnd, hItem);
TreeView_Expand(_left_hwnd, hItem, TVE_EXPAND);
}
-
-bool ShellBrowserChild::InitDragDrop()
+bool ShellBrowser::InitDragDrop()
{
- CONTEXT("ShellBrowserChild::InitDragDrop()");
+ CONTEXT("ShellBrowser::InitDragDrop()");
_pDropTarget = new TreeDropTarget(_left_hwnd);
_pDropTarget->Release(); // free TreeDropTarget
_pDropTarget = NULL;
return false;
- }
- else
+ } else
_pDropTarget->Release();
FORMATETC ftetc;
}
-void ShellBrowserChild::OnTreeItemRClick(int idCtrl, LPNMHDR pnmh)
+void ShellBrowser::OnTreeItemRClick(int idCtrl, LPNMHDR pnmh)
{
- CONTEXT("ShellBrowserChild::OnTreeItemRClick()");
+ CONTEXT("ShellBrowser::OnTreeItemRClick()");
TVHITTESTINFO tvhti;
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) {
- ClientToScreen(_left_hwnd, &tvhti.pt);
- Tree_DoItemMenu(_left_hwnd, tvhti.hItem , &tvhti.pt);
+ 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 ShellBrowserChild::Tree_DoItemMenu(HWND hwndTreeView, HTREEITEM hItem, LPPOINT pptScreen)
+void ShellBrowser::OnTreeGetDispInfo(int idCtrl, LPNMHDR pnmh)
{
- CONTEXT("ShellBrowserChild::Tree_DoItemMenu()");
-
- LPARAM itemData = TreeView_GetItemData(hwndTreeView, hItem);
+ CONTEXT("ShellBrowser::OnTreeGetDispInfo()");
- if (itemData) {
- Entry* entry = (Entry*)itemData;
+ LPNMTVDISPINFO lpdi = (LPNMTVDISPINFO)pnmh;
+ ShellEntry* entry = (ShellEntry*)lpdi->item.lParam;
- if (entry->_etype == ET_SHELL) {
- ShellDirectory* dir = static_cast<ShellDirectory*>(entry->_up);
- ShellFolder folder = dir? dir->_folder: GetDesktopFolder();
- LPCITEMIDLIST pidl = static_cast<ShellEntry*>(entry)->_pidl;
+ if (entry) {
+ if (lpdi->item.mask & TVIF_TEXT)
+ lpdi->item.pszText = entry->_display_name;
- CHECKERROR(ShellFolderContextMenu(folder, ::GetParent(hwndTreeView), 1, &pidl, pptScreen->x, pptScreen->y));
- } else {
- ShellPath shell_path = entry->create_absolute_pidl();
- LPCITEMIDLIST pidl = shell_path;
+ if (lpdi->item.mask & (TVIF_IMAGE|TVIF_SELECTEDIMAGE)) {
+ if (lpdi->item.mask & TVIF_IMAGE)
+ lpdi->item.iImage = get_image_idx(
+ entry->safe_extract_icon((ICONCACHE_FLAGS)(ICF_HICON|ICF_OVERLAYS)));
- ///@todo use parent folder instead of desktop
- CHECKERROR(ShellFolderContextMenu(GetDesktopFolder(), _hwnd, 1, &pidl, pptScreen->x, pptScreen->y));
+ if (lpdi->item.mask & TVIF_SELECTEDIMAGE)
+ lpdi->item.iSelectedImage = get_image_idx(
+ entry->safe_extract_icon((ICONCACHE_FLAGS)(ICF_HICON|ICF_OVERLAYS|ICF_OPEN)));
}
}
}
-void ShellBrowserChild::OnTreeGetDispInfo(int idCtrl, LPNMHDR pnmh)
+int ShellBrowser::get_image_idx(int icon_id)
{
- CONTEXT("ShellBrowserChild::OnTreeGetDispInfo()");
+ if (icon_id != ICID_NONE) {
+ map<int,int>::const_iterator found = _image_map.find(icon_id);
- LPNMTVDISPINFO lpdi = (LPNMTVDISPINFO)pnmh;
- ShellEntry* entry = (ShellEntry*)lpdi->item.lParam;
+ if (found != _image_map.end())
+ return found->second;
- if (lpdi->item.mask & TVIF_TEXT)
- lpdi->item.pszText = entry->_display_name;
+ int idx = ImageList_AddIcon(_himl, g_Globals._icon_cache.get_icon(icon_id).get_hicon());
- 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;
+ _image_map[icon_id] = idx;
- 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)
- if ((HIMAGELIST)SHGetFileInfo((LPCTSTR)pidl, 0, &sfi, sizeof(sfi), SHGFI_PIDL|SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_LINKOVERLAY) == _himlSmall)
- lpdi->item.iImage = sfi.iIcon;
- else
- lpdi->item.iImage = -1;
+ return idx;
+ } else
+ return -1;
+}
- if (lpdi->item.mask & TVIF_SELECTEDIMAGE)
- if ((HIMAGELIST)SHGetFileInfo((LPCTSTR)pidl, 0, &sfi, sizeof(sfi), SHGFI_PIDL|SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_OPENICON) == _himlSmall)
- lpdi->item.iSelectedImage = sfi.iIcon;
- else
- lpdi->item.iSelectedImage = -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 ShellBrowserChild::OnTreeItemExpanding(int idCtrl, LPNMTREEVIEW pnmtv)
+void ShellBrowser::OnTreeItemExpanding(int idCtrl, LPNMTREEVIEW pnmtv)
{
- CONTEXT("ShellBrowserChild::OnTreeItemExpanding()");
+ CONTEXT("ShellBrowser::OnTreeItemExpanding()");
if (pnmtv->action == TVE_COLLAPSE)
TreeView_Expand(_left_hwnd, pnmtv->itemNew.hItem, TVE_COLLAPSE|TVE_COLLAPSERESET);
}
}
-int ShellBrowserChild::InsertSubitems(HTREEITEM hParentItem, Entry* entry, IShellFolder* pParentFolder)
+int ShellBrowser::InsertSubitems(HTREEITEM hParentItem, Entry* entry, IShellFolder* pParentFolder)
{
- CONTEXT("ShellBrowserChild::InsertSubitems()");
+ CONTEXT("ShellBrowser::InsertSubitems()");
WaitCursor wait;
tvInsert.hInsertAfter = TVI_LAST;
tvInsert.hParent = hParentItem;
- TreeView_InsertItem(_left_hwnd, &tvInsert);
+ (void)TreeView_InsertItem(_left_hwnd, &tvInsert);
}
++cnt;
return cnt;
}
-void ShellBrowserChild::OnTreeItemSelected(int idCtrl, LPNMTREEVIEW pnmtv)
+void ShellBrowser::OnTreeItemSelected(int idCtrl, LPNMTREEVIEW pnmtv)
{
- CONTEXT("ShellBrowserChild::OnTreeItemSelected()");
+ CONTEXT("ShellBrowser::OnTreeItemSelected()");
+
+ ShellEntry* entry = (ShellEntry*)pnmtv->itemNew.lParam;
_last_sel = pnmtv->itemNew.hItem;
- Entry* entry = (Entry*)pnmtv->itemNew.lParam;
- jump_to(entry);
+ if (entry)
+ _callback->entry_selected(entry);
}
-void ShellBrowserChild::UpdateFolderView(IShellFolder* folder)
+void ShellBrowser::UpdateFolderView(IShellFolder* folder)
{
- CONTEXT("ShellBrowserChild::UpdateFolderView()");
+ CONTEXT("ShellBrowser::UpdateFolderView()");
FOLDERSETTINGS fs;
IShellView* pLastShellView = _pShellView;
pLastShellView->GetCurrentInfo(&fs);
else {
fs.ViewMode = _create_info._open_mode&OWM_DETAILS? FVM_DETAILS: FVM_ICON;
- fs.fFlags = FWF_BESTFITWINDOW;
+ 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;
pLastShellView->UIActivate(SVUIA_DEACTIVATE);
pLastShellView->DestroyViewWindow();
pLastShellView->Release();
-
- resize_children();
}
_pShellView->UIActivate(SVUIA_ACTIVATE_NOFOCUS);
}
-void ShellBrowserChild::resize_children()
-{
- RECT rect = _clnt_rect;
-
- HDWP hdwp = BeginDeferWindowPos(2);
-
- int cx = rect.left;
-
- if (_left_hwnd) {
- cx = _split_pos + SPLIT_WIDTH/2;
+#ifndef __MINGW32__ // IShellFolderViewCB missing in MinGW (as of 25.09.2005)
- hdwp = DeferWindowPos(hdwp, _left_hwnd, 0, rect.left, rect.top, _split_pos-SPLIT_WIDTH/2-rect.left, rect.bottom-rect.top, SWP_NOZORDER|SWP_NOACTIVATE);
- } else {
- _split_pos = 0;
- cx = 0;
+ /// 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;
}
- if (_right_hwnd)
- hdwp = DeferWindowPos(hdwp, _right_hwnd, 0, rect.left+cx+1, rect.top, rect.right-cx, rect.bottom-rect.top, SWP_NOZORDER|SWP_NOACTIVATE);
-
- EndDeferWindowPos(hdwp);
+ return E_NOTIMPL;
}
+#endif
-LRESULT ShellBrowserChild::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
-{
- switch(nmsg) {
- case WM_GETISHELLBROWSER: // for Registry Explorer Plugin
- return (LRESULT)static_cast<IShellBrowser*>(this);
+HRESULT ShellBrowser::OnDefaultCommand(LPIDA pida)
+{
+ CONTEXT("ShellBrowser::OnDefaultCommand()");
- // SDI integration:
+ if (pida->cidl >= 1) {
+ if (_left_hwnd) { // explorer mode
+ if (_last_sel) {
+ ShellDirectory* parent = (ShellDirectory*)TreeView_GetItemData(_left_hwnd, _last_sel);
- case WM_PAINT: {
- PaintCanvas canvas(_hwnd);
- ClientRect rt(_hwnd);
- rt.left = _split_pos-SPLIT_WIDTH/2;
- rt.right = _split_pos+SPLIT_WIDTH/2+1;
-
- if (_right_hwnd) {
- WindowRect right_rect(_right_hwnd);
- ScreenToClient(_hwnd, &right_rect);
- rt.top = right_rect.top;
- rt.bottom = right_rect.bottom;
- }
+ if (parent) {
+ try {
+ parent->smart_scan();
+ } catch(COMException& e) {
+ return e.Error();
+ }
- HBRUSH lastBrush = SelectBrush(canvas, GetStockBrush(COLOR_SPLITBAR));
- Rectangle(canvas, rt.left, rt.top-1, rt.right, rt.bottom+1);
- SelectObject(canvas, lastBrush);
- break;}
+ UINT firstOffset = pida->aoffset[1];
+ LPITEMIDLIST pidl = (LPITEMIDLIST)((LPBYTE)pida+firstOffset);
- case WM_SETCURSOR:
- if (LOWORD(lparam) == HTCLIENT) {
- POINT pt;
- GetCursorPos(&pt);
- ScreenToClient(_hwnd, &pt);
+ Entry* entry = parent->find_entry(pidl);
- if (pt.x>=_split_pos-SPLIT_WIDTH/2 && pt.x<_split_pos+SPLIT_WIDTH/2+1) {
- SetCursor(LoadCursor(0, IDC_SIZEWE));
- return TRUE;
+ if (entry && (entry->_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY))
+ if (entry->_etype == ET_SHELL)
+ if (_last_sel && select_entry(_last_sel, entry))
+ return S_OK;
+ }
}
+ } else { // no tree control
+ if (MainFrameBase::OpenShellFolders(pida, _hWndFrame))
+ return S_OK;
+
+/* create new Frame Window
+ if (MainFrame::OpenShellFolders(pida, 0))
+ return S_OK;
+*/
}
- goto def;
+ }
- case WM_LBUTTONDOWN: {
- int x = GET_X_LPARAM(lparam);
+ return E_NOTIMPL;
+}
- ClientRect rt(_hwnd);
- if (x>=_split_pos-SPLIT_WIDTH/2 && x<_split_pos+SPLIT_WIDTH/2+1) {
- _last_split = _split_pos;
- SetCapture(_hwnd);
- }
+HTREEITEM ShellBrowser::select_entry(HTREEITEM hitem, Entry* entry, bool expand)
+{
+ CONTEXT("ShellBrowser::select_entry()");
- break;}
-
- case WM_LBUTTONUP:
- if (GetCapture() == _hwnd)
- ReleaseCapture();
- break;
-
- case WM_KEYDOWN:
- if (wparam == VK_ESCAPE)
- if (GetCapture() == _hwnd) {
- _split_pos = _last_split;
- resize_children();
- _last_split = -1;
- ReleaseCapture();
- SetCursor(LoadCursor(0, IDC_ARROW));
- }
- break;
-
- case WM_MOUSEMOVE:
- if (GetCapture() == _hwnd) {
- int x = LOWORD(lparam);
-
- ClientRect rt(_hwnd);
-
- if (x>=0 && x<rt.right) {
- _split_pos = x;
- resize_children();
- rt.left = x-SPLIT_WIDTH/2;
- rt.right = x+SPLIT_WIDTH/2+1;
- InvalidateRect(_hwnd, &rt, FALSE);
- UpdateWindow(_left_hwnd);
- UpdateWindow(_hwnd);
- UpdateWindow(_right_hwnd);
- }
- }
- break;
+ if (expand && !TreeView_Expand(_left_hwnd, hitem, TVE_EXPAND))
+ return 0;
+
+ for(hitem=TreeView_GetChild(_left_hwnd,hitem); hitem; hitem=TreeView_GetNextSibling(_left_hwnd,hitem)) {
+ if ((Entry*)TreeView_GetItemData(_left_hwnd,hitem) == entry) {
+ if (TreeView_SelectItem(_left_hwnd, hitem)) {
+ if (expand)
+ TreeView_Expand(_left_hwnd, hitem, TVE_EXPAND);
+ return hitem;
+ }
- default: def:
- return DefWindowProc(_hwnd, nmsg, wparam, lparam);
+ break;
+ }
}
return 0;
}
-int ShellBrowserChild::Command(int id, int code)
+
+bool ShellBrowser::jump_to_pidl(LPCITEMIDLIST pidl)
{
- switch(id) {
- case ID_BROWSE_BACK:
- break;//@todo
+ if (!_root._entry)
+ return false;
- case ID_BROWSE_FORWARD:
- break;//@todo
+ // iterate through the hierarchy and open all folders to reach pidl
+ WaitCursor wait;
- case ID_BROWSE_UP:
- if (_left_hwnd) {
- //@@ not necessary in this simply case: jump_to(_cur_dir->_up);
+ HTREEITEM hitem = TreeView_GetRoot(_left_hwnd);
+ Entry* entry = _root._entry;
- //@@ -> move into jump_to()
- HTREEITEM hitem = TreeView_GetParent(_left_hwnd, _last_sel);
+ for(const void*p=pidl;;) {
+ if (!p)
+ return true;
- if (hitem)
- TreeView_SelectItem(_left_hwnd, hitem); // sends TVN_SELCHANGED notification
- } else {
- if (_cur_dir->_up)
- jump_to(_cur_dir->_up);
- }
- break;
+ if (!entry || !hitem)
+ break;
- default:
- return 1;
+ entry->smart_scan(SORT_NAME);
+
+ Entry* found = entry->find_entry(p);
+ p = entry->get_next_path_component(p);
+
+ if (found)
+ hitem = select_entry(hitem, found);
+
+ entry = found;
}
- return 0;
+ return false;
}
-int ShellBrowserChild::Notify(int id, NMHDR* pnmh)
+
+#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 !
{
- switch(pnmh->code) {
- case TVN_GETDISPINFO: OnTreeGetDispInfo(id, pnmh); break;
- case TVN_ITEMEXPANDING: OnTreeItemExpanding(id, (LPNMTREEVIEW)pnmh); break;
- case TVN_SELCHANGED: OnTreeItemSelected(id, (LPNMTREEVIEW)pnmh); break;
- case NM_RCLICK: OnTreeItemRClick(id, pnmh); break;
- }
+/**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);
- return 0;
+ // store path into history
+ if (info._path && *info._path)
+ _url_history.push(info._path);
+*/
}
-HRESULT ShellBrowserChild::OnDefaultCommand(LPIDA pida)
+MDIShellBrowserChild* MDIShellBrowserChild::create(const ShellChildWndInfo& info)
{
- CONTEXT("ShellBrowserChild::OnDefaultCommand()");
+ ChildWindow* child = ChildWindow::create(info, info._pos.rcNormalPosition,
+ WINDOW_CREATOR_INFO(MDIShellBrowserChild,ShellChildWndInfo), CLASSNAME_CHILDWND, NULL, info._pos.showCmd==SW_SHOWMAXIMIZED? WS_MAXIMIZE: 0);
- if (pida->cidl >= 1) {
- if (_left_hwnd) { // explorer mode
- //@@if (_last_sel) {
- ShellDirectory* parent = _cur_dir;//@@(ShellDirectory*)TreeView_GetItemData(_left_hwnd, _last_sel);
+ return static_cast<MDIShellBrowserChild*>(child);
+}
- if (parent) {
- try {
- parent->smart_scan();
- } catch(COMException& e) {
- return e.Error();
- }
- UINT firstOffset = pida->aoffset[1];
- LPITEMIDLIST pidl = (LPITEMIDLIST)((LPBYTE)pida+firstOffset);
+LRESULT MDIShellBrowserChild::Init(LPCREATESTRUCT pcs)
+{
+ CONTEXT("MDIShellBrowserChild::Init()");
- Entry* entry = parent->find_entry(pidl);
+ if (super::Init(pcs))
+ return 1;
- if (entry && (entry->_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY))
- if (entry->_etype == ET_SHELL)
- if (expand_folder(static_cast<ShellDirectory*>(entry)))
- return S_OK;
- }
- //@@}
- } else { // no tree control
- if (MainFrame::OpenShellFolders(pida, _hWndFrame))
- return S_OK;
+ update_shell_browser();
-/* create new Frame Window
- if (MainFrame::OpenShellFolders(pida, 0))
- return S_OK;
-*/
+ if (_shellBrowser.get())
+ if (_left_hwnd)
+ _shellBrowser->Init();
+ else
+ _shellBrowser->UpdateFolderView(_create_info._shell_path.get_folder());
+
+ return 0;
+}
+
+
+LRESULT MDIShellBrowserChild::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
+{
+ switch(nmsg) {
+ case PM_DISPATCH_COMMAND: {
+ switch(LOWORD(wparam)) {
+ case ID_WINDOW_NEW: {CONTEXT("MDIShellBrowserChild PM_DISPATCH_COMMAND ID_WINDOW_NEW");
+ MDIShellBrowserChild::create(_create_info);
+ break;}
+
+ case ID_REFRESH:
+ //@todo refresh shell child
+ _shellBrowser->invalidate_cache();
+ break;
+
+ case ID_VIEW_SDI:
+ MainFrameBase::Create(ExplorerCmd(_url, false));
+ break;
+
+ default:
+ return super::WndProc(nmsg, wparam, lparam);
}
+ return TRUE;}
+
+ default:
+ return super::WndProc(nmsg, wparam, lparam);
}
- return E_NOTIMPL;
+ return 0;
}
-
-bool ShellBrowserChild::expand_folder(ShellDirectory* entry)
+void MDIShellBrowserChild::update_shell_browser()
{
- CONTEXT("ShellBrowserChild::expand_folder()");
+ int split_pos = DEFAULT_SPLIT_POS;
- //HTREEITEM hitem_sel = TreeView_GetSelection(_left_hwnd);
- if (!_last_sel)
- return false;
+ if (_shellBrowser.get()) {
+ split_pos = _split_pos;
+ delete _shellBrowser.release();
+ }
- if (!TreeView_Expand(_left_hwnd, _last_sel, TVE_EXPAND))
- return false;
+ ///@todo use OWM_ROOTED flag
- 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) &&
- TreeView_Expand(_left_hwnd, hitem, TVE_EXPAND))
- return true;
+ // create explorer treeview
+ if (_create_info._open_mode & OWM_EXPLORE) {
+ if (!_left_hwnd) {
+ ClientRect rect(_hwnd);
- break;
+ _left_hwnd = CreateWindowEx(0, WC_TREEVIEW, NULL,
+ WS_CHILD|WS_TABSTOP|WS_VISIBLE|WS_CHILD|TVS_HASLINES|TVS_LINESATROOT|TVS_HASBUTTONS|TVS_SHOWSELALWAYS,//|TVS_NOTOOLTIPS
+ 0, rect.top, split_pos-SPLIT_WIDTH/2, rect.bottom-rect.top,
+ _hwnd, (HMENU)IDC_FILETREE, g_Globals._hInstance, 0);
+ }
+ } else {
+ if (_left_hwnd) {
+ DestroyWindow(_left_hwnd);
+ _left_hwnd = 0;
}
}
- return false;
+ _shellBrowser = auto_ptr<ShellBrowser>(new ShellBrowser(_hwnd, _left_hwnd, _right_hwnd,
+ _shellpath_info, this, _cm_ifs));
+
+ _shellBrowser->Init(_hwndFrame);
}
-void ShellBrowserChild::jump_to(void* path)
+String MDIShellBrowserChild::jump_to_int(LPCTSTR url)
{
- Entry* entry = NULL;
-
- //@@
- if (!_cur_dir)
- _cur_dir = static_cast<ShellDirectory*>(_root._entry);
+ String dir, fname;
-/*@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()
-*/
+ if (!_tcsnicmp(url, TEXT("shell://"), 8)) {
+ if (_shellBrowser->jump_to_pidl(ShellPath(url+8)))
+ return url;
+ }
- if (_cur_dir) {
- _cur_dir->smart_scan();
+ if (SplitFileSysURL(url, dir, fname)) {
- entry = _cur_dir->find_entry(path);
+ ///@todo use fname
- if (entry)
- jump_to(entry);
- }
-
- //@@ work around as long as we don't iterate correctly through the ShellEntry tree
- if (!entry) {
- LPITEMIDLIST pidl = (LPITEMIDLIST)path;
- UpdateFolderView(ShellFolder(pidl));
+ if (_shellBrowser->jump_to_pidl(ShellPath(dir)))
+ return FmtString(TEXT("file://%s"), (LPCTSTR)dir);
}
+
+ return String();
}
-void ShellBrowserChild::jump_to(Entry* entry)
+
+void MDIShellBrowserChild::entry_selected(Entry* entry)
{
if (entry->_etype == ET_SHELL) {
+ ShellEntry* shell_entry = static_cast<ShellEntry*>(entry);
IShellFolder* folder;
- ShellDirectory* se = static_cast<ShellDirectory*>(entry);
- if (se->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- folder = static_cast<ShellDirectory*>(se)->_folder;
+ if (shell_entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ folder = static_cast<ShellDirectory*>(shell_entry)->_folder;
else
- folder = se->get_parent_folder();
+ folder = shell_entry->get_parent_folder();
if (!folder) {
assert(folder);
return;
}
- UpdateFolderView(folder);
+ 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);
- _cur_dir = se;
+ set_url(url);
+ }
+
+ _shellBrowser->UpdateFolderView(folder);
+
+ // set size of new created shell view windows
+ ClientRect rt(_hwnd);
+ resize_children(rt.right, rt.bottom);
}
}
+
+#endif