From 6010f3ea82bc911b0229f246bf4e2c5a3ddbecef Mon Sep 17 00:00:00 2001 From: Martin Fuchs Date: Mon, 11 Aug 2003 22:04:26 +0000 Subject: [PATCH] open child folders by double click in ShellBrowserChild svn path=/trunk/; revision=5537 --- reactos/ChangeLog | 1 + .../system/explorer/desktop/desktop.cpp | 17 ++- .../subsys/system/explorer/desktop/desktop.h | 2 +- .../subsys/system/explorer/doc/changes.txt | 1 + .../subsys/system/explorer/shell/entries.cpp | 9 ++ .../subsys/system/explorer/shell/entries.h | 1 + .../system/explorer/shell/shellbrowser.cpp | 142 +++++++++++++++--- .../system/explorer/shell/shellbrowser.h | 7 +- .../explorer/utility/shellbrowserimpl.h | 8 +- 9 files changed, 153 insertions(+), 35 deletions(-) diff --git a/reactos/ChangeLog b/reactos/ChangeLog index 175ab557b97..9634229037d 100644 --- a/reactos/ChangeLog +++ b/reactos/ChangeLog @@ -2,6 +2,7 @@ * subsys/system/explorer Subclassing of shell window for drawing desktop background. + * open child folders by double click in ShellBrowserChild 2003-08-11 Casper S. Hornstrup diff --git a/reactos/subsys/system/explorer/desktop/desktop.cpp b/reactos/subsys/system/explorer/desktop/desktop.cpp index 9893e280c89..b97fa5d8f74 100644 --- a/reactos/subsys/system/explorer/desktop/desktop.cpp +++ b/reactos/subsys/system/explorer/desktop/desktop.cpp @@ -65,13 +65,19 @@ static void draw_desktop_background(HWND hwnd, HDC hdc) // This next part could be improved by working out how much // space the text actually needs... - rect.left = rect.right - 260; - rect.top = rect.bottom - 80; + rect.left = rect.right - 280; + rect.top = rect.bottom - 60; rect.right = rect.left + 250; rect.bottom = rect.top + 40; - SetTextColor(hdc, RGB(255,255,255)); SetBkMode(hdc, TRANSPARENT); + + SetTextColor(hdc, RGB(128,128,192)); + DrawText(hdc, BkgndText, -1, &rect, DT_RIGHT); + + SetTextColor(hdc, RGB(255,255,255)); + --rect.right; + ++rect.top; DrawText(hdc, BkgndText, -1, &rect, DT_RIGHT); } @@ -83,7 +89,7 @@ LRESULT BackgroundWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) draw_desktop_background(_hwnd, (HDC)wparam); return TRUE; - case WM_RBUTTONDBLCLK: + case WM_MBUTTONDBLCLK: explorer_show_frame(_hwnd, SW_SHOWNORMAL); break; @@ -119,6 +125,7 @@ LRESULT DesktopWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) case WM_LBUTTONDBLCLK: case WM_RBUTTONDBLCLK: + case WM_MBUTTONDBLCLK: explorer_show_frame(_hwnd, SW_SHOWNORMAL); break; @@ -134,7 +141,7 @@ LRESULT DesktopWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) FOLDERSETTINGS fs; fs.ViewMode = FVM_ICON; - fs.fFlags = FWF_DESKTOP|FWF_TRANSPARENT|FWF_NOCLIENTEDGE|FWF_NOSCROLL|FWF_BESTFITWINDOW|FWF_SNAPTOGRID; + fs.fFlags = FWF_DESKTOP|FWF_NOCLIENTEDGE|FWF_NOSCROLL|FWF_BESTFITWINDOW|FWF_SNAPTOGRID; RECT rect; GetClientRect(_hwnd, &rect); diff --git a/reactos/subsys/system/explorer/desktop/desktop.h b/reactos/subsys/system/explorer/desktop/desktop.h index baccb4cba91..1a9387dcac0 100644 --- a/reactos/subsys/system/explorer/desktop/desktop.h +++ b/reactos/subsys/system/explorer/desktop/desktop.h @@ -70,7 +70,7 @@ struct DesktopWindow : public Window, public IShellBrowserImpl return E_NOTIMPL; } - STDMETHOD(SendControlMsg)(UINT id, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *pret) + STDMETHOD(SendControlMsg)(UINT id, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT* pret) { return E_NOTIMPL; } diff --git a/reactos/subsys/system/explorer/doc/changes.txt b/reactos/subsys/system/explorer/doc/changes.txt index f65427b3a77..ec544a3394f 100644 --- a/reactos/subsys/system/explorer/doc/changes.txt +++ b/reactos/subsys/system/explorer/doc/changes.txt @@ -13,3 +13,4 @@ usage of IShellView C++, implementation of IShellBrowser, ... 09.08.2003 m. fuchs class DesktopWindow for shell view on the desktop 11.08.2003 m. fuchs class BackgroundWindow for painting of desktop background + open child folders by double click in ShellBrowserChild diff --git a/reactos/subsys/system/explorer/shell/entries.cpp b/reactos/subsys/system/explorer/shell/entries.cpp index 9a2efa06815..0f9d2b1eeab 100644 --- a/reactos/subsys/system/explorer/shell/entries.cpp +++ b/reactos/subsys/system/explorer/shell/entries.cpp @@ -247,6 +247,15 @@ void Entry::sort_directory(SORT_ORDER sortOrder) } +void Entry::smart_scan() +{ + if (!_scanned) { + free_subentries(); + read_directory(SORT_NAME); // we could use IShellFolder2::GetDefaultColumn to determine sort order + } +} + + BOOL Entry::launch_entry(HWND hwnd, UINT nCmdShow) { TCHAR cmd[MAX_PATH]; diff --git a/reactos/subsys/system/explorer/shell/entries.h b/reactos/subsys/system/explorer/shell/entries.h index 8c9d328d668..ea59de12c95 100644 --- a/reactos/subsys/system/explorer/shell/entries.h +++ b/reactos/subsys/system/explorer/shell/entries.h @@ -73,6 +73,7 @@ public: void read_directory(SORT_ORDER sortOrder); Entry* read_tree(const void* path, SORT_ORDER sortOrder); void sort_directory(SORT_ORDER sortOrder); + void smart_scan(); virtual void read_directory() {} virtual const void* get_next_path_component(const void*) {return NULL;} diff --git a/reactos/subsys/system/explorer/shell/shellbrowser.cpp b/reactos/subsys/system/explorer/shell/shellbrowser.cpp index 9677f15f225..f17b401bc73 100644 --- a/reactos/subsys/system/explorer/shell/shellbrowser.cpp +++ b/reactos/subsys/system/explorer/shell/shellbrowser.cpp @@ -35,6 +35,20 @@ #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; +} + + ShellBrowserChild::ShellBrowserChild(HWND hwnd) : super(hwnd) { @@ -42,6 +56,7 @@ ShellBrowserChild::ShellBrowserChild(HWND hwnd) _pShellView = NULL; _pDropTarget = NULL; _himlSmall = 0; + _last_sel = 0; } ShellBrowserChild::~ShellBrowserChild() @@ -71,7 +86,7 @@ void ShellBrowserChild::OnCreate(LPCREATESTRUCT pcs) // create explorer treeview _left_hwnd = CreateWindowEx(0, WC_TREEVIEW, NULL, - WS_CHILD|WS_TABSTOP|WS_VISIBLE|WS_CHILD|TVS_HASLINES|TVS_LINESATROOT|TVS_HASBUTTONS|TVS_NOTOOLTIPS, + WS_CHILD|WS_TABSTOP|WS_VISIBLE|WS_CHILD|TVS_HASLINES|TVS_LINESATROOT|TVS_HASBUTTONS|TVS_NOTOOLTIPS|TVS_SHOWSELALWAYS, 0, rect.top, _split_pos-SPLIT_WIDTH/2, rect.bottom-rect.top, _hwnd, (HMENU)IDC_FILETREE, g_Globals._hInstance, 0); @@ -172,14 +187,11 @@ void ShellBrowserChild::OnTreeItemRClick(int idCtrl, LPNMHDR pnmh) void ShellBrowserChild::Tree_DoItemMenu(HWND hwndTreeView, HTREEITEM hItem, LPPOINT pptScreen) { - TVITEM tvItem; + LPARAM itemData = TreeView_GetItemData(hwndTreeView, hItem); - tvItem.mask = TVIF_PARAM; - tvItem.hItem = hItem; - - if (TreeView_GetItem(hwndTreeView, &tvItem)) { + if (itemData) { HWND hwndParent = ::GetParent(hwndTreeView); - Entry* entry = (Entry*)tvItem.lParam; + Entry* entry = (Entry*)itemData; IShellFolder* folder; @@ -279,30 +291,20 @@ void ShellBrowserChild::OnTreeItemExpanding(int idCtrl, LPNMTREEVIEW pnmtv) if (pnmtv->action == TVE_COLLAPSE) TreeView_Expand(_left_hwnd, pnmtv->itemNew.hItem, TVE_COLLAPSE|TVE_COLLAPSERESET); else if (pnmtv->action == TVE_EXPAND) { - TVITEM tvItem; + ShellDirectory* entry = (ShellDirectory*)TreeView_GetItemData(_left_hwnd, pnmtv->itemNew.hItem); - tvItem.mask = TVIF_PARAM; - tvItem.hItem = pnmtv->itemNew.hItem; - - if (!TreeView_GetItem(_left_hwnd, &tvItem)) - return; - - WaitCursor wait; - - ShellDirectory* entry = (ShellDirectory*)tvItem.lParam; - - InsertSubitems(pnmtv->itemNew.hItem, entry, entry->_folder); + if (entry) + InsertSubitems(pnmtv->itemNew.hItem, entry, entry->_folder); } } void ShellBrowserChild::InsertSubitems(HTREEITEM hParentItem, Entry* entry, IShellFolder* pParentFolder) { + WaitCursor wait; + SendMessage(_left_hwnd, WM_SETREDRAW, FALSE, 0); - if (!entry->_scanned) { - entry->free_subentries(); - entry->read_directory(SORT_NAME); // we could use IShellFolder2::GetDefaultColumn to determine sort order - } + entry->smart_scan(); TV_ITEM tvItem; TV_INSERTSTRUCT tvInsert; @@ -341,6 +343,8 @@ void ShellBrowserChild::OnTreeItemSelected(int idCtrl, LPNMTREEVIEW pnmtv) { ShellEntry* entry = (ShellEntry*)pnmtv->itemNew.lParam; + _last_sel = pnmtv->itemNew.hItem; + IShellFolder* folder; if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) @@ -360,7 +364,7 @@ void ShellBrowserChild::OnTreeItemSelected(int idCtrl, LPNMTREEVIEW pnmtv) pLastShellView->GetCurrentInfo(&fs); else { fs.ViewMode = FVM_DETAILS; - fs.fFlags = 0; + fs.fFlags = FWF_NOCLIENTEDGE; } HRESULT hr = folder->CreateViewObject(_hwnd, IID_IShellView, (void**)&_pShellView); @@ -417,3 +421,93 @@ int ShellBrowserChild::Notify(int id, NMHDR* pnmh) return 0; } + + + // process default command: look for folders and traverse into them +HRESULT ShellBrowserChild::OnDefaultCommand(IShellView* ppshv) +{ + static UINT CF_IDLIST = RegisterClipboardFormat(CFSTR_SHELLIDLIST); + + HRESULT ret = E_NOTIMPL; + + IDataObject* selection; + HRESULT hr = ppshv->GetItemObject(SVGIO_SELECTION, IID_IDataObject, (void**)&selection); + if (FAILED(hr)) + return hr; + + + FORMATETC fetc; + fetc.cfFormat = CF_IDLIST; + fetc.ptd = NULL; + fetc.dwAspect = DVASPECT_CONTENT; + fetc.lindex = -1; + fetc.tymed = TYMED_HGLOBAL; + + hr = selection->QueryGetData(&fetc); + if (FAILED(hr)) + return hr; + + + STGMEDIUM stgm = {sizeof(STGMEDIUM)}; + + hr = selection->GetData(&fetc, &stgm); + if (FAILED(hr)) + return hr; + + + DWORD pData = (DWORD)GlobalLock(stgm.hGlobal); + CIDA* pIDList = (CIDA*)pData; + + if (pIDList->cidl >= 1) { + //UINT folderOffset = pIDList->aoffset[0]; + //LPITEMIDLIST folder = (LPITEMIDLIST)(pData+folderOffset); + + UINT firstOffset = pIDList->aoffset[1]; + LPITEMIDLIST pidl = (LPITEMIDLIST)(pData+firstOffset); + + //HTREEITEM hitem_sel = TreeView_GetSelection(_left_hwnd); + + if (_last_sel) { + ShellDirectory* parent = (ShellDirectory*)TreeView_GetItemData(_left_hwnd, _last_sel); + + if (parent) { + parent->smart_scan(); + + Entry* entry = parent->find_entry(pidl); + + if (entry && (entry->_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)) + if (expand_folder(static_cast(entry))) + ret = S_OK; + } + } + } + + GlobalUnlock(stgm.hGlobal); + ReleaseStgMedium(&stgm); + + selection->Release(); + + return ret; +} + +bool ShellBrowserChild::expand_folder(ShellDirectory* entry) +{ + //HTREEITEM hitem_sel = TreeView_GetSelection(_left_hwnd); + 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) && + TreeView_Expand(_left_hwnd, hitem, TVE_EXPAND)) + return true; + + break; + } + } + + return false; +} diff --git a/reactos/subsys/system/explorer/shell/shellbrowser.h b/reactos/subsys/system/explorer/shell/shellbrowser.h index 464f3658625..37ca13eb4be 100644 --- a/reactos/subsys/system/explorer/shell/shellbrowser.h +++ b/reactos/subsys/system/explorer/shell/shellbrowser.h @@ -84,7 +84,7 @@ struct ShellBrowserChild : public ChildWindow, public IShellBrowserImpl return E_NOTIMPL; } - STDMETHOD(SendControlMsg)(UINT id, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *pret) + STDMETHOD(SendControlMsg)(UINT id, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT* pret) { if (!pret) return E_POINTER; @@ -99,6 +99,8 @@ struct ShellBrowserChild : public ChildWindow, public IShellBrowserImpl return E_NOTIMPL; } + STDMETHOD(OnDefaultCommand)(IShellView* ppshv); + protected: Root _root; @@ -109,6 +111,8 @@ protected: // HIMAGELIST _himlLarge; // shell image TreeDropTarget* _pDropTarget; + HTREEITEM _last_sel; + LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam); int Notify(int id, NMHDR* pnmh); @@ -123,4 +127,5 @@ protected: void OnTreeItemSelected(int idCtrl, LPNMTREEVIEW pnmtv); void Tree_DoItemMenu(HWND hwndTreeView, HTREEITEM hItem, LPPOINT pptScreen); + bool expand_folder(ShellDirectory* entry); }; diff --git a/reactos/subsys/system/explorer/utility/shellbrowserimpl.h b/reactos/subsys/system/explorer/utility/shellbrowserimpl.h index d558383572c..f33d0fc1978 100644 --- a/reactos/subsys/system/explorer/utility/shellbrowserimpl.h +++ b/reactos/subsys/system/explorer/utility/shellbrowserimpl.h @@ -63,17 +63,17 @@ struct IShellBrowserImpl : public IShellBrowser, public ICommDlgBrowser STDMETHOD(ContextSensitiveHelp)(BOOL fEnterMode) {return E_NOTIMPL;} // *** ICommDlgBrowser methods *** - STDMETHOD(OnDefaultCommand)(THIS_ struct IShellView* ppshv) - { //handle double click and ENTER key if needed + STDMETHOD(OnDefaultCommand)(struct IShellView* ppshv) + { return E_NOTIMPL; } - STDMETHOD(OnStateChange)(THIS_ struct IShellView* ppshv, ULONG uChange) + STDMETHOD(OnStateChange)(struct IShellView* ppshv, ULONG uChange) { //handle selection, rename, focus if needed return E_NOTIMPL; } - STDMETHOD(IncludeObject)(THIS_ struct IShellView* ppshv, LPCITEMIDLIST pidl) + STDMETHOD(IncludeObject)(struct IShellView* ppshv, LPCITEMIDLIST pidl) { //filter files if needed return S_OK; }