diff --git a/reactos/subsys/system/explorer/Makefile.MinGW b/reactos/subsys/system/explorer/Makefile.MinGW index a95dd3fac0a..ba05df8bcb7 100644 --- a/reactos/subsys/system/explorer/Makefile.MinGW +++ b/reactos/subsys/system/explorer/Makefile.MinGW @@ -44,6 +44,7 @@ OBJECTS = \ utility.o \ window.o \ dragdropimpl.o \ + shellbrowserimpl.o \ explorer.o \ entries.o \ winfs.o \ diff --git a/reactos/subsys/system/explorer/Makefile.Wine b/reactos/subsys/system/explorer/Makefile.Wine index f1b26c805f6..1bcb4f23ead 100644 --- a/reactos/subsys/system/explorer/Makefile.Wine +++ b/reactos/subsys/system/explorer/Makefile.Wine @@ -20,6 +20,7 @@ CPP_SRCS = \ utility/utility.cpp \ utility/window.cpp \ utility/dragdropimpl.cpp \ + utility/shellbrowserimpl.cpp \ shell/entries.cpp \ shell/winfs.cpp \ shell/unixfs.cpp \ diff --git a/reactos/subsys/system/explorer/desktop/desktop.cpp b/reactos/subsys/system/explorer/desktop/desktop.cpp index a02c60a312a..d5ad92a7d20 100644 --- a/reactos/subsys/system/explorer/desktop/desktop.cpp +++ b/reactos/subsys/system/explorer/desktop/desktop.cpp @@ -33,6 +33,7 @@ #include "desktop.h" #include "../taskbar/desktopbar.h" +#include "../shell/mainframe.h" // for MainFrame::Create() #include "../externals.h" #include "../explorer_intres.h" @@ -262,3 +263,27 @@ LRESULT DesktopWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) return 0; } + + +HRESULT DesktopWindow::OnDefaultCommand(LPIDA pIDList) +{ + HRESULT ret = E_NOTIMPL; + int cnt = pIDList->cidl; + + for(int i=0; ++i<=cnt; ) { + /* We know, the parent folder is the desktop, so we do not need to look at pIDList->aoffset[0] + UINT folderOffset = pIDList->aoffset[0]; + LPITEMIDLIST pidlFolder = (LPITEMIDLIST)((LPBYTE)pIDList+folderOffset); + */ + LPCITEMIDLIST pidl = (LPCITEMIDLIST)((LPBYTE)pIDList+pIDList->aoffset[i]); + + SFGAOF attribs = SFGAO_FOLDER; + HRESULT hr = Desktop()->GetAttributesOf(1, &pidl, &attribs); + + if (SUCCEEDED(hr) && (attribs&SFGAO_FOLDER)) + if (MainFrame::Create(pidl, FALSE)) + ret = S_OK; + } + + return ret; +} diff --git a/reactos/subsys/system/explorer/desktop/desktop.h b/reactos/subsys/system/explorer/desktop/desktop.h index cf699ee9f4e..cb819a8e64d 100644 --- a/reactos/subsys/system/explorer/desktop/desktop.h +++ b/reactos/subsys/system/explorer/desktop/desktop.h @@ -75,4 +75,6 @@ protected: IShellView* _pShellView; WindowHandle _desktopBar; + + virtual HRESULT OnDefaultCommand(LPIDA pIDList); }; diff --git a/reactos/subsys/system/explorer/doc/changes.txt b/reactos/subsys/system/explorer/doc/changes.txt index aba5767015e..2aa02add339 100644 --- a/reactos/subsys/system/explorer/doc/changes.txt +++ b/reactos/subsys/system/explorer/doc/changes.txt @@ -39,3 +39,4 @@ eliminated all warnings displayed when using -Wall activated option for compiling as UNICODE version merged start menus of the same name (e.g. "All Users\Startup" with "\Startup") +28.09.2003 m. fuchs open cabinet windows then clicking on desktop folders diff --git a/reactos/subsys/system/explorer/explorer.cpp b/reactos/subsys/system/explorer/explorer.cpp index 1fabfe93cd3..f350761dbc6 100644 --- a/reactos/subsys/system/explorer/explorer.cpp +++ b/reactos/subsys/system/explorer/explorer.cpp @@ -99,7 +99,7 @@ void explorer_show_frame(HWND hwndDesktop, int cmdshow) UpdateWindow(hMainFrame); // Open the first child window after initializing the whole application - PostMessage(hMainFrame, PM_OPEN_WINDOW, TRUE/*mode_explore*/, 0); + PostMessage(hMainFrame, PM_OPEN_WINDOW, OWM_EXPLORE|OWM_DETAILS, 0); } } diff --git a/reactos/subsys/system/explorer/explorer.dsp b/reactos/subsys/system/explorer/explorer.dsp index d621bde6cbc..72bac2d209b 100644 --- a/reactos/subsys/system/explorer/explorer.dsp +++ b/reactos/subsys/system/explorer/explorer.dsp @@ -210,6 +210,10 @@ SOURCE=.\utility\dragdropimpl.h # End Source File # Begin Source File +SOURCE=.\utility\shellbrowserimpl.cpp +# End Source File +# Begin Source File + SOURCE=.\utility\shellbrowserimpl.h # End Source File # Begin Source File diff --git a/reactos/subsys/system/explorer/explorer.h b/reactos/subsys/system/explorer/explorer.h index 8e1f2c790c6..adb3346410a 100644 --- a/reactos/subsys/system/explorer/explorer.h +++ b/reactos/subsys/system/explorer/explorer.h @@ -48,8 +48,6 @@ #define PM_FRM_CALC_CLIENT (WM_APP+0x04) #define Frame_CalcFrameClient(hwnd, prt) ((BOOL)SNDMSG(hwnd, PM_FRM_CALC_CLIENT, 0, (LPARAM)(PRECT)prt)) -#define PM_OPEN_WINDOW (WM_APP+0x05) - #define PM_GET_CONTROLWINDOW (WM_APP+0x06) diff --git a/reactos/subsys/system/explorer/makefile_rex b/reactos/subsys/system/explorer/makefile_rex index 2bd51b7651c..c81f358b944 100644 --- a/reactos/subsys/system/explorer/makefile_rex +++ b/reactos/subsys/system/explorer/makefile_rex @@ -56,6 +56,7 @@ TARGET_OBJECTS = \ utility.o \ window.o \ dragdropimpl.o \ + shellbrowserimpl.o \ explorer.o \ entries.o \ winfs.o \ diff --git a/reactos/subsys/system/explorer/shell/filechild.cpp b/reactos/subsys/system/explorer/shell/filechild.cpp index 548009944ab..8ee4c32e8d2 100644 --- a/reactos/subsys/system/explorer/shell/filechild.cpp +++ b/reactos/subsys/system/explorer/shell/filechild.cpp @@ -53,13 +53,13 @@ FileChildWndInfo::FileChildWndInfo(LPCTSTR path) _pos.rcNormalPosition.right = CW_USEDEFAULT; _pos.rcNormalPosition.bottom = CW_USEDEFAULT; - _mode_explore = true; + _open_mode = OWM_EXPLORE|OWM_DETAILS; } ShellChildWndInfo::ShellChildWndInfo(LPCTSTR path, const ShellPath& root_shell_path) : FileChildWndInfo(path), - _shell_path(path), + _shell_path(path? path: root_shell_path), _root_shell_path(root_shell_path) { _etype = ET_SHELL; @@ -121,7 +121,7 @@ FileChildWindow::FileChildWindow(HWND hwnd, const FileChildWndInfo& info) _root._entry->_data.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY; - if (info._mode_explore) //TODO: Is not-explore-mode for FileChildWindow completely implemented? + if (info._open_mode & OWM_EXPLORE) //TODO: Is not-explore-mode for FileChildWindow completely implemented? _left_hwnd = *(_left=new Pane(_hwnd, IDW_TREE_LEFT, IDW_HEADER_LEFT, _root._entry, true, 0)); _right_hwnd = *(_right=new Pane(_hwnd, IDW_TREE_RIGHT, IDW_HEADER_RIGHT, NULL, false, COL_SIZE|COL_DATE|COL_TIME|COL_ATTRIBUTES|COL_INDEX|COL_LINKS)); diff --git a/reactos/subsys/system/explorer/shell/filechild.h b/reactos/subsys/system/explorer/shell/filechild.h index e952e3d9022..ebfc97ed659 100644 --- a/reactos/subsys/system/explorer/shell/filechild.h +++ b/reactos/subsys/system/explorer/shell/filechild.h @@ -34,7 +34,7 @@ struct FileChildWndInfo LPCTSTR _path; WINDOWPLACEMENT _pos; - bool _mode_explore; + int _open_mode; //OPEN_WINDOW_MODE }; struct ShellChildWndInfo : public FileChildWndInfo diff --git a/reactos/subsys/system/explorer/shell/mainframe.cpp b/reactos/subsys/system/explorer/shell/mainframe.cpp index 5796a34492a..8bedeb831b8 100644 --- a/reactos/subsys/system/explorer/shell/mainframe.cpp +++ b/reactos/subsys/system/explorer/shell/mainframe.cpp @@ -167,7 +167,7 @@ HWND MainFrame::Create() 0/*hwndDesktop*/, hMenuFrame); } -HWND MainFrame::Create(LPCTSTR path, BOOL mode_explore) +HWND MainFrame::Create(LPCTSTR path, int mode) { HWND hMainFrame = Create(); if (!hMainFrame) @@ -178,15 +178,36 @@ HWND MainFrame::Create(LPCTSTR path, BOOL mode_explore) MainFrame* pMainFrame = GET_WINDOW(MainFrame, hMainFrame); if (pMainFrame) - pMainFrame->CreateChild(path, mode_explore); + pMainFrame->CreateChild(path, mode); + + return hMainFrame; +} + +HWND MainFrame::Create(LPCITEMIDLIST pidl, int mode) +{ + HWND hMainFrame = Create(); + if (!hMainFrame) + return 0; + + ShowWindow(hMainFrame, SW_SHOW); + + MainFrame* pMainFrame = GET_WINDOW(MainFrame, hMainFrame); + + if (pMainFrame) + pMainFrame->CreateChild(pidl, mode); return hMainFrame; } -ChildWindow* MainFrame::CreateChild(LPCTSTR path, BOOL mode_explore) +ChildWindow* MainFrame::CreateChild(LPCTSTR path, int mode) { - return reinterpret_cast(SendMessage(_hwnd, PM_OPEN_WINDOW, mode_explore, (LPARAM)path)); + return reinterpret_cast(SendMessage(_hwnd, PM_OPEN_WINDOW, mode, (LPARAM)path)); +} + +ChildWindow* MainFrame::CreateChild(LPCITEMIDLIST pidl, int mode) +{ + return reinterpret_cast(SendMessage(_hwnd, PM_OPEN_WINDOW, mode|OWM_PIDL, (LPARAM)pidl)); } @@ -238,9 +259,15 @@ LRESULT MainFrame::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) ShellPath shell_path = DesktopFolder(); if (lparam) { - // take over path from lparam - path = (LPCTSTR)lparam; - shell_path = path; // create as "rooted" window + if (wparam & OWM_PIDL) { + // take over PIDL from lparam + shell_path.assign((LPCITEMIDLIST)lparam); // create as "rooted" window + path = FileSysShellPath(shell_path); + } else { + // take over path from lparam + path = (LPCTSTR)lparam; + shell_path = path; // create as "rooted" window + } } else { //TODO: read paths and window placements from registry GetCurrentDirectory(MAX_PATH, buffer); @@ -256,7 +283,7 @@ LRESULT MainFrame::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) create_info._pos.rcNormalPosition.right = 600; create_info._pos.rcNormalPosition.bottom = 280; - create_info._mode_explore = wparam? true: false; + create_info._open_mode = (OPEN_WINDOW_MODE)wparam; // FileChildWindow::create(_hmdiclient, create_info); return (LRESULT)ShellBrowserChild::create(_hmdiclient, create_info);} diff --git a/reactos/subsys/system/explorer/shell/mainframe.h b/reactos/subsys/system/explorer/shell/mainframe.h index 31abb208e63..8f91a4073f6 100644 --- a/reactos/subsys/system/explorer/shell/mainframe.h +++ b/reactos/subsys/system/explorer/shell/mainframe.h @@ -26,6 +26,10 @@ // +#define PM_OPEN_WINDOW (WM_APP+0x05) +enum OPEN_WINDOW_MODE {OWM_EXPLORE=1, OWM_DETAILS=2, OWM_PIDL=4}; + + struct MainFrame : public PreTranslateWindow { typedef PreTranslateWindow super; @@ -34,9 +38,11 @@ struct MainFrame : public PreTranslateWindow ~MainFrame(); static HWND Create(); - static HWND Create(LPCTSTR path, BOOL mode_explore=TRUE); + static HWND Create(LPCTSTR path, int mode=OWM_EXPLORE|OWM_DETAILS); + static HWND Create(LPCITEMIDLIST pidl, int mode=OWM_EXPLORE|OWM_DETAILS|OWM_PIDL); - ChildWindow* CreateChild(LPCTSTR path=NULL, BOOL mode_explore=TRUE); + ChildWindow* CreateChild(LPCTSTR path=NULL, int mode=OWM_EXPLORE|OWM_DETAILS); + ChildWindow* CreateChild(LPCITEMIDLIST pidl, int mode=OWM_EXPLORE|OWM_DETAILS|OWM_PIDL); protected: FullScreenParameters _fullscreen; diff --git a/reactos/subsys/system/explorer/shell/shellbrowser.cpp b/reactos/subsys/system/explorer/shell/shellbrowser.cpp index bf08ab4efbd..b83fee369bc 100644 --- a/reactos/subsys/system/explorer/shell/shellbrowser.cpp +++ b/reactos/subsys/system/explorer/shell/shellbrowser.cpp @@ -86,7 +86,7 @@ LRESULT ShellBrowserChild::Init(LPCREATESTRUCT pcs) // create explorer treeview - if (_create_info._mode_explore) + if (_create_info._open_mode & OWM_EXPLORE) _left_hwnd = CreateWindowEx(0, WC_TREEVIEW, NULL, 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, @@ -283,21 +283,22 @@ void ShellBrowserChild::OnTreeGetDispInfo(int idCtrl, LPNMHDR pnmh) } if (lpdi->item.mask & (TVIF_IMAGE|TVIF_SELECTEDIMAGE)) { - LPITEMIDLIST pidl = entry->create_absolute_pidl(_hwnd); + ShellPath pidl_abs = entry->create_absolute_pidl(_hwnd); // Caching of absolute PIDLs could enhance performance. + LPCITEMIDLIST pidl = pidl_abs; + SHFILEINFO sfi; - if (lpdi->item.mask & TVIF_IMAGE) { - if (SHGetFileInfo((LPCTSTR)pidl, 0, &sfi, sizeof(sfi), SHGFI_PIDL|SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_LINKOVERLAY)) + 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; - if (lpdi->item.mask & TVIF_SELECTEDIMAGE) { - if (SHGetFileInfo((LPCTSTR)pidl, 0, &sfi, sizeof(sfi), SHGFI_PIDL|SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_OPENICON)) + 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; - } - - if (pidl != &*entry->_pidl) - ShellMalloc()->Free(pidl); + else + lpdi->item.iSelectedImage = -1; } } @@ -387,7 +388,7 @@ void ShellBrowserChild::UpdateFolderView(IShellFolder* folder) if (pLastShellView) pLastShellView->GetCurrentInfo(&fs); else { - fs.ViewMode = _left_hwnd? FVM_DETAILS: FVM_ICON; + fs.ViewMode = _create_info._open_mode&OWM_DETAILS? FVM_DETAILS: FVM_ICON; fs.fFlags = FWF_NOCLIENTEDGE; } @@ -442,77 +443,36 @@ int ShellBrowserChild::Notify(int id, NMHDR* pnmh) } - // process default command: look for folders and traverse into them -HRESULT ShellBrowserChild::OnDefaultCommand(IShellView* ppshv) +HRESULT ShellBrowserChild::OnDefaultCommand(LPIDA pIDList) { - static UINT CF_IDLIST = RegisterClipboardFormat(CFSTR_SHELLIDLIST); + if (pIDList->cidl>=1 && _last_sel) { + ShellDirectory* parent = (ShellDirectory*)TreeView_GetItemData(_left_hwnd, _last_sel); - 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), {0}, 0}; - - 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) { - try { - parent->smart_scan(); - } catch(COMException& e) { - return e.Error(); - } - - Entry* entry = parent->find_entry(pidl); - - if (entry && (entry->_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)) - if (expand_folder(static_cast(entry))) - ret = S_OK; + if (parent) { + try { + parent->smart_scan(); + } catch(COMException& e) { + return e.Error(); } + + //UINT folderOffset = pIDList->aoffset[0]; + //LPITEMIDLIST pidlFolder = (LPITEMIDLIST)((LPBYTE)pIDList+folderOffset); + + UINT firstOffset = pIDList->aoffset[1]; + LPITEMIDLIST pidl = (LPITEMIDLIST)((LPBYTE)pIDList+firstOffset); + + Entry* entry = parent->find_entry(pidl); + + if (entry && (entry->_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)) + if (expand_folder(static_cast(entry))) + return S_OK; } } - GlobalUnlock(stgm.hGlobal); - ReleaseStgMedium(&stgm); - - selection->Release(); - - return ret; + return E_NOTIMPL; } + bool ShellBrowserChild::expand_folder(ShellDirectory* entry) { //HTREEITEM hitem_sel = TreeView_GetSelection(_left_hwnd); diff --git a/reactos/subsys/system/explorer/shell/shellbrowser.h b/reactos/subsys/system/explorer/shell/shellbrowser.h index 8d33cf9ecab..e379e58fef8 100644 --- a/reactos/subsys/system/explorer/shell/shellbrowser.h +++ b/reactos/subsys/system/explorer/shell/shellbrowser.h @@ -100,8 +100,6 @@ struct ShellBrowserChild : public ChildWindow, public IShellBrowserImpl return E_NOTIMPL; } - STDMETHOD(OnDefaultCommand)(IShellView* ppshv); - protected: Root _root; @@ -123,6 +121,8 @@ protected: void InsertSubitems(HTREEITEM hParentItem, Entry* entry, IShellFolder* pParentFolder); bool InitDragDrop(); + HRESULT OnDefaultCommand(LPIDA pIDList); + void OnTreeGetDispInfo(int idCtrl, LPNMHDR pnmh); void OnTreeItemExpanding(int idCtrl, LPNMTREEVIEW pnmtv); void OnTreeItemRClick(int idCtrl, LPNMHDR pnmh); diff --git a/reactos/subsys/system/explorer/shell/shellfs.cpp b/reactos/subsys/system/explorer/shell/shellfs.cpp index be02f4dc597..fda2fd26951 100644 --- a/reactos/subsys/system/explorer/shell/shellfs.cpp +++ b/reactos/subsys/system/explorer/shell/shellfs.cpp @@ -102,15 +102,16 @@ bool ShellDirectory::fill_w32fdata_shell(LPCITEMIDLIST pidl, SFGAOF attribs, WIN } -LPITEMIDLIST ShellEntry::create_absolute_pidl(HWND hwnd) +ShellPath ShellEntry::create_absolute_pidl(HWND hwnd) { if (_up/* && _up->_etype==ET_SHELL*/) { ShellDirectory* dir = static_cast(_up); - return _pidl.create_absolute_pidl(dir->_pidl, hwnd); + if (dir->_pidl->mkid.cb) // Caching of absolute PIDLs could enhance performance. + return _pidl.create_absolute_pidl(dir->create_absolute_pidl(hwnd), hwnd); } - return &*_pidl; + return _pidl; } @@ -143,6 +144,8 @@ BOOL ShellEntry::launch_entry(HWND hwnd, UINT nCmdShow) { BOOL ret = TRUE; + ShellPath shell_path = create_absolute_pidl(hwnd); + SHELLEXECUTEINFO shexinfo; shexinfo.cbSize = sizeof(SHELLEXECUTEINFO); @@ -153,16 +156,13 @@ BOOL ShellEntry::launch_entry(HWND hwnd, UINT nCmdShow) shexinfo.lpParameters = NULL; shexinfo.lpDirectory = NULL; shexinfo.nShow = nCmdShow; - shexinfo.lpIDList = create_absolute_pidl(hwnd); + shexinfo.lpIDList = &*shell_path; if (!ShellExecuteEx(&shexinfo)) { display_error(hwnd, GetLastError()); ret = FALSE; } - if (shexinfo.lpIDList != &*_pidl) - ShellMalloc()->Free(shexinfo.lpIDList); - return ret; } diff --git a/reactos/subsys/system/explorer/shell/shellfs.h b/reactos/subsys/system/explorer/shell/shellfs.h index 9229dddbf81..9a5d4939dd6 100644 --- a/reactos/subsys/system/explorer/shell/shellfs.h +++ b/reactos/subsys/system/explorer/shell/shellfs.h @@ -35,9 +35,9 @@ struct ShellEntry : public Entry virtual BOOL launch_entry(HWND hwnd, UINT nCmdShow=SW_SHOWNORMAL); IShellFolder* get_parent_folder() const; - LPITEMIDLIST create_absolute_pidl(HWND hwnd); + ShellPath create_absolute_pidl(HWND hwnd); - ShellPath _pidl; + ShellPath _pidl; // parent relative PIDL protected: ShellEntry(LPITEMIDLIST shell_path) : Entry(ET_SHELL), _pidl(shell_path) {}