diff --git a/reactos/subsys/system/explorer/desktop/desktop.cpp b/reactos/subsys/system/explorer/desktop/desktop.cpp index fec79994b6a..c9fd8e92d89 100644 --- a/reactos/subsys/system/explorer/desktop/desktop.cpp +++ b/reactos/subsys/system/explorer/desktop/desktop.cpp @@ -171,6 +171,9 @@ LRESULT DesktopWindow::Init(LPCREATESTRUCT pcs) ///@todo use IShellBrowser::GetViewStateStream() to restore previous view state -> see SHOpenRegStream() if (SUCCEEDED(hr)) { + // subclass shellview window + new DesktopShellView(hWndView, _pShellView); + _pShellView->UIActivate(SVUIA_ACTIVATE_FOCUS); /* @@ -207,6 +210,7 @@ LRESULT DesktopWindow::Init(LPCREATESTRUCT pcs) // Without this the desktop has mysteriously only a size of 800x600 pixels. MoveWindow(hwndFolderView, 0, 0, rect.right, rect.bottom, TRUE); + // subclass background window new BackgroundWindow(hwndFolderView); } } @@ -265,10 +269,75 @@ LRESULT DesktopWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) } -HRESULT DesktopWindow::OnDefaultCommand(LPIDA pIDList) +HRESULT DesktopWindow::OnDefaultCommand(LPIDA pida) { - if (MainFrame::OpenShellFolders(pIDList, 0)) + if (MainFrame::OpenShellFolders(pida, 0)) return S_OK; return E_NOTIMPL; } + + +DesktopShellView::DesktopShellView(HWND hwnd, IShellView* pShellView) + : super(hwnd), + _pShellView(pShellView) +{ +} + +LRESULT DesktopShellView::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) +{ + switch(nmsg) { + case WM_CONTEXTMENU: + if (!DoContextMenu(GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam))) + goto def; ///@todo desktop context menu + break; + + default: def: + return super::WndProc(nmsg, wparam, lparam); + } + + return 0; +} + +int DesktopShellView::Command(int id, int code) +{ + return super::Command(id, code); +} + +int DesktopShellView::Notify(int id, NMHDR* pnmh) +{ + return super::Notify(id, pnmh); +} + +bool DesktopShellView::DoContextMenu(int x, int y) +{ + IDataObject* selection; + + HRESULT hr = _pShellView->GetItemObject(SVGIO_SELECTION, IID_IDataObject, (void**)&selection); + if (FAILED(hr)) + return false; + + PIDList pidList; + + hr = pidList.GetData(selection); + if (FAILED(hr)) { + selection->Release(); + //CHECKERROR(hr); + return false; + } + + LPIDA pida = pidList; + + LPCITEMIDLIST parent_pidl = (LPCITEMIDLIST) ((LPBYTE)pida+pida->aoffset[0]); + LPCITEMIDLIST first_pidl = (LPCITEMIDLIST)((LPBYTE)pida+pida->aoffset[1]); + + ShellFolder folder(parent_pidl); + + hr = ShellFolderContextMenu(folder, _hwnd, pida->cidl, &first_pidl, x, y); + + selection->Release(); + + CHECKERROR(hr); + + return true; +} diff --git a/reactos/subsys/system/explorer/desktop/desktop.h b/reactos/subsys/system/explorer/desktop/desktop.h index 26781d5f4b6..26d02b65377 100644 --- a/reactos/subsys/system/explorer/desktop/desktop.h +++ b/reactos/subsys/system/explorer/desktop/desktop.h @@ -78,5 +78,23 @@ protected: IShellView* _pShellView; WindowHandle _desktopBar; - virtual HRESULT OnDefaultCommand(LPIDA pIDList); + virtual HRESULT OnDefaultCommand(LPIDA pida); +}; + + + /// subclassed ShellView window +struct DesktopShellView : public SubclassedWindow +{ + typedef SubclassedWindow super; + + DesktopShellView(HWND hwnd, IShellView* pShellView); + +protected: + IShellView* _pShellView; + + LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam); + int Command(int id, int code); + int Notify(int id, NMHDR* pnmh); + + bool DoContextMenu(int x, int y); }; diff --git a/reactos/subsys/system/explorer/doc/changes.txt b/reactos/subsys/system/explorer/doc/changes.txt index 0aae7a4fdeb..c50b6792522 100644 --- a/reactos/subsys/system/explorer/doc/changes.txt +++ b/reactos/subsys/system/explorer/doc/changes.txt @@ -48,3 +48,4 @@ If you search for more information, look into the CVS repository. 19.10.2003 m. fuchs implemented floating start menus 29.11.2003 m. fuchs implemented GDB stub for remote debugging 06.12.2003 m. fuchs basic support to display NTFS streams in winefile windows +20.12.2003 m. fuchs context menu implementation for desktop window diff --git a/reactos/subsys/system/explorer/doxy-footer.html b/reactos/subsys/system/explorer/doxy-footer.html index 237d894c3a0..f48c31e1db5 100644 --- a/reactos/subsys/system/explorer/doxy-footer.html +++ b/reactos/subsys/system/explorer/doxy-footer.html @@ -2,8 +2,8 @@ diff --git a/reactos/subsys/system/explorer/shell/mainframe.cpp b/reactos/subsys/system/explorer/shell/mainframe.cpp index 7177a33fc3c..942a01f48aa 100644 --- a/reactos/subsys/system/explorer/shell/mainframe.cpp +++ b/reactos/subsys/system/explorer/shell/mainframe.cpp @@ -211,15 +211,15 @@ ChildWindow* MainFrame::CreateChild(LPCITEMIDLIST pidl, int mode) } -int MainFrame::OpenShellFolders(LPIDA pIDList, HWND hFrameWnd) +int MainFrame::OpenShellFolders(LPIDA pida, HWND hFrameWnd) { int cnt = 0; - LPCITEMIDLIST parent_pidl = (LPCITEMIDLIST) ((LPBYTE)pIDList+pIDList->aoffset[0]); + LPCITEMIDLIST parent_pidl = (LPCITEMIDLIST) ((LPBYTE)pida+pida->aoffset[0]); ShellFolder folder(parent_pidl); - for(int i=pIDList->cidl; i>0; --i) { - LPCITEMIDLIST pidl = (LPCITEMIDLIST)((LPBYTE)pIDList+pIDList->aoffset[i]); + for(int i=pida->cidl; i>0; --i) { + LPCITEMIDLIST pidl = (LPCITEMIDLIST)((LPBYTE)pida+pida->aoffset[i]); SFGAOF attribs = SFGAO_FOLDER; HRESULT hr = folder->GetAttributesOf(1, &pidl, &attribs); diff --git a/reactos/subsys/system/explorer/shell/mainframe.h b/reactos/subsys/system/explorer/shell/mainframe.h index 3d7cb7917d9..21bee0ab85e 100644 --- a/reactos/subsys/system/explorer/shell/mainframe.h +++ b/reactos/subsys/system/explorer/shell/mainframe.h @@ -41,7 +41,7 @@ struct MainFrame : public PreTranslateWindow static HWND Create(); static HWND Create(LPCTSTR path, int mode=OWM_EXPLORE|OWM_DETAILS); static HWND Create(LPCITEMIDLIST pidl, int mode=OWM_EXPLORE|OWM_DETAILS|OWM_PIDL); - static int OpenShellFolders(LPIDA pIDList, HWND hFrameWnd); + static int OpenShellFolders(LPIDA pida, HWND hFrameWnd); ChildWindow* CreateChild(LPCTSTR path=NULL, int mode=OWM_EXPLORE|OWM_DETAILS); ChildWindow* CreateChild(LPCITEMIDLIST pidl, int mode=OWM_EXPLORE|OWM_DETAILS|OWM_PIDL); diff --git a/reactos/subsys/system/explorer/shell/shellbrowser.cpp b/reactos/subsys/system/explorer/shell/shellbrowser.cpp index 8df17dc1a94..4fb0b8c1f87 100644 --- a/reactos/subsys/system/explorer/shell/shellbrowser.cpp +++ b/reactos/subsys/system/explorer/shell/shellbrowser.cpp @@ -209,7 +209,6 @@ void ShellBrowserChild::Tree_DoItemMenu(HWND hwndTreeView, HTREEITEM hItem, LPPO LPARAM itemData = TreeView_GetItemData(hwndTreeView, hItem); if (itemData) { - HWND hwndParent = ::GetParent(hwndTreeView); Entry* entry = (Entry*)itemData; IShellFolder* shell_folder; @@ -228,55 +227,7 @@ void ShellBrowserChild::Tree_DoItemMenu(HWND hwndTreeView, HTREEITEM hItem, LPPO if (shell_folder) { LPCITEMIDLIST pidl = static_cast(entry)->_pidl; - IContextMenu* pcm; - - HRESULT hr = shell_folder->GetUIObjectOf(hwndParent, 1, &pidl, IID_IContextMenu, NULL, (LPVOID*)&pcm); -// HRESULT hr = CDefFolderMenu_Create2(dir?dir->_pidl:DesktopFolder(), hwndParent, 1, &pidl, shell_folder, NULL, 0, NULL, &pcm); - - if (SUCCEEDED(hr)) { - HMENU hPopup = CreatePopupMenu(); - - if (hPopup) { - hr = pcm->QueryContextMenu(hPopup, 0, 1, 0x7fff, CMF_NORMAL|CMF_EXPLORE); - - if (SUCCEEDED(hr)) { - IContextMenu2* pcm2; - - pcm->QueryInterface(IID_IContextMenu2, (LPVOID*)&pcm2); - - UINT idCmd = TrackPopupMenu(hPopup, - TPM_LEFTALIGN | TPM_RETURNCMD | TPM_RIGHTBUTTON, - pptScreen->x, - pptScreen->y, - 0, - hwndParent, - NULL); - - if (pcm2) { - pcm2->Release(); - pcm2 = NULL; - } - - if (idCmd) { - CMINVOKECOMMANDINFO cmi; - cmi.cbSize = sizeof(CMINVOKECOMMANDINFO); - cmi.fMask = 0; - cmi.hwnd = hwndParent; - cmi.lpVerb = (LPCSTR)(INT_PTR)(idCmd - 1); - cmi.lpParameters = NULL; - cmi.lpDirectory = NULL; - cmi.nShow = SW_SHOWNORMAL; - cmi.dwHotKey = 0; - cmi.hIcon = NULL; - hr = pcm->InvokeCommand(&cmi); - } - } - } - - pcm->Release(); - } - - shell_folder->Release(); + ShellFolderContextMenu(shell_folder, ::GetParent(hwndTreeView), 1, &pidl, pptScreen->x, pptScreen->y); } } } @@ -485,11 +436,11 @@ int ShellBrowserChild::Notify(int id, NMHDR* pnmh) } -HRESULT ShellBrowserChild::OnDefaultCommand(LPIDA pIDList) +HRESULT ShellBrowserChild::OnDefaultCommand(LPIDA pida) { CONTEXT("ShellBrowserChild::OnDefaultCommand()"); - if (pIDList->cidl>=1) { + if (pida->cidl>=1) { if (_left_hwnd) { // explorer mode if (_last_sel) { ShellDirectory* parent = (ShellDirectory*)TreeView_GetItemData(_left_hwnd, _last_sel); @@ -501,8 +452,8 @@ HRESULT ShellBrowserChild::OnDefaultCommand(LPIDA pIDList) return e.Error(); } - UINT firstOffset = pIDList->aoffset[1]; - LPITEMIDLIST pidl = (LPITEMIDLIST)((LPBYTE)pIDList+firstOffset); + UINT firstOffset = pida->aoffset[1]; + LPITEMIDLIST pidl = (LPITEMIDLIST)((LPBYTE)pida+firstOffset); Entry* entry = parent->find_entry(pidl); @@ -512,11 +463,11 @@ HRESULT ShellBrowserChild::OnDefaultCommand(LPIDA pIDList) } } } else { // no tree control - if (MainFrame::OpenShellFolders(pIDList, _hWndFrame)) + if (MainFrame::OpenShellFolders(pida, _hWndFrame)) return S_OK; /* create new Frame Window - if (MainFrame::OpenShellFolders(pIDList, 0)) + if (MainFrame::OpenShellFolders(pida, 0)) return S_OK; */ } diff --git a/reactos/subsys/system/explorer/shell/shellbrowser.h b/reactos/subsys/system/explorer/shell/shellbrowser.h index 49c500ff81e..e939900fe4c 100644 --- a/reactos/subsys/system/explorer/shell/shellbrowser.h +++ b/reactos/subsys/system/explorer/shell/shellbrowser.h @@ -123,7 +123,7 @@ protected: int InsertSubitems(HTREEITEM hParentItem, Entry* entry, IShellFolder* pParentFolder); bool InitDragDrop(); - HRESULT OnDefaultCommand(LPIDA pIDList); + HRESULT OnDefaultCommand(LPIDA pida); void OnTreeGetDispInfo(int idCtrl, LPNMHDR pnmh); void OnTreeItemExpanding(int idCtrl, LPNMTREEVIEW pnmtv); diff --git a/reactos/subsys/system/explorer/utility/shellbrowserimpl.cpp b/reactos/subsys/system/explorer/utility/shellbrowserimpl.cpp index 9634091c648..1f7eb74866e 100644 --- a/reactos/subsys/system/explorer/utility/shellbrowserimpl.cpp +++ b/reactos/subsys/system/explorer/utility/shellbrowserimpl.cpp @@ -58,42 +58,23 @@ HRESULT IShellBrowserImpl::QueryInterface(REFIID iid, void** ppvObject) // process default command: look for folders and traverse into them HRESULT IShellBrowserImpl::OnDefaultCommand(IShellView* ppshv) { - static UINT CF_IDLIST = RegisterClipboardFormat(CFSTR_SHELLIDLIST); - IDataObject* selection; + HRESULT hr = ppshv->GetItemObject(SVGIO_SELECTION, IID_IDataObject, (void**)&selection); if (FAILED(hr)) return hr; + PIDList pidList; - 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)) + hr = pidList.GetData(selection); + if (FAILED(hr)) { + selection->Release(); return hr; + } - - STGMEDIUM stgm = {sizeof(STGMEDIUM), {0}, 0}; - - hr = selection->GetData(&fetc, &stgm); - if (FAILED(hr)) - return hr; - - DWORD pData = (DWORD)GlobalLock(stgm.hGlobal); - LPIDA pIDList = (LPIDA)pData; - - HRESULT ret = OnDefaultCommand(pIDList); - - GlobalUnlock(stgm.hGlobal); - ReleaseStgMedium(&stgm); - + hr = OnDefaultCommand(pidList); selection->Release(); - return ret; + return hr; } diff --git a/reactos/subsys/system/explorer/utility/shellbrowserimpl.h b/reactos/subsys/system/explorer/utility/shellbrowserimpl.h index e1404319fb1..de3a0e80830 100644 --- a/reactos/subsys/system/explorer/utility/shellbrowserimpl.h +++ b/reactos/subsys/system/explorer/utility/shellbrowserimpl.h @@ -72,7 +72,7 @@ struct IShellBrowserImpl : public IShellBrowser, public ICommDlgBrowser protected: DWORD _dwRef; - virtual HRESULT OnDefaultCommand(LPIDA pIDList) {return E_NOTIMPL;} + virtual HRESULT OnDefaultCommand(LPIDA pida) {return E_NOTIMPL;} }; #ifndef WM_GETISHELLBROWSER diff --git a/reactos/subsys/system/explorer/utility/shellclasses.cpp b/reactos/subsys/system/explorer/utility/shellclasses.cpp index 1406f90858d..87892ca6312 100644 --- a/reactos/subsys/system/explorer/utility/shellclasses.cpp +++ b/reactos/subsys/system/explorer/utility/shellclasses.cpp @@ -421,3 +421,55 @@ UINT ILGetSize(LPCITEMIDLIST pidl) } #endif + + +HRESULT ShellFolderContextMenu(IShellFolder* shell_folder, HWND hwndParent, int cidl, LPCITEMIDLIST* apidl, int x, int y) +{ + IContextMenu* pcm; + + HRESULT hr = shell_folder->GetUIObjectOf(hwndParent, cidl, apidl, IID_IContextMenu, NULL, (LPVOID*)&pcm); +// HRESULT hr = CDefFolderMenu_Create2(dir?dir->_pidl:DesktopFolder(), hwndParent, 1, &pidl, shell_folder, NULL, 0, NULL, &pcm); + + if (SUCCEEDED(hr)) { + HMENU hPopup = CreatePopupMenu(); + + if (hPopup) { + hr = pcm->QueryContextMenu(hPopup, 0, 1, 0x7fff, CMF_NORMAL|CMF_EXPLORE); + + if (SUCCEEDED(hr)) { + IContextMenu2* pcm2; + + pcm->QueryInterface(IID_IContextMenu2, (LPVOID*)&pcm2); + + UINT idCmd = TrackPopupMenu(hPopup, TPM_LEFTALIGN|TPM_RETURNCMD|TPM_RIGHTBUTTON, x, y, 0, hwndParent, NULL); + + if (pcm2) { + pcm2->Release(); + pcm2 = NULL; + } + + if (idCmd) { + CMINVOKECOMMANDINFO cmi; + + cmi.cbSize = sizeof(CMINVOKECOMMANDINFO); + cmi.fMask = 0; + cmi.hwnd = hwndParent; + cmi.lpVerb = (LPCSTR)(INT_PTR)(idCmd - 1); + cmi.lpParameters = NULL; + cmi.lpDirectory = NULL; + cmi.nShow = SW_SHOWNORMAL; + cmi.dwHotKey = 0; + cmi.hIcon = NULL; + + hr = pcm->InvokeCommand(&cmi); + } + } + } + + pcm->Release(); + } + + shell_folder->Release(); + + return hr; +} diff --git a/reactos/subsys/system/explorer/utility/shellclasses.h b/reactos/subsys/system/explorer/utility/shellclasses.h index b37d623bd8c..bafd0bde600 100644 --- a/reactos/subsys/system/explorer/utility/shellclasses.h +++ b/reactos/subsys/system/explorer/utility/shellclasses.h @@ -937,3 +937,53 @@ struct ShellItemEnumerator : public SIfacePtr CHECKERROR(folder->EnumObjects(0, flags, &_p)); } }; + + + /// list of PIDLs +struct PIDList +{ + PIDList() + { + memset(&_stgm, 0, sizeof(STGMEDIUM)); + } + + ~PIDList() + { + if (_stgm.hGlobal) { + GlobalUnlock(_stgm.hGlobal); + ReleaseStgMedium(&_stgm); + } + } + + HRESULT GetData(IDataObject* selection) + { + static UINT CF_IDLIST = RegisterClipboardFormat(CFSTR_SHELLIDLIST); + + FORMATETC fetc; + fetc.cfFormat = CF_IDLIST; + fetc.ptd = NULL; + fetc.dwAspect = DVASPECT_CONTENT; + fetc.lindex = -1; + fetc.tymed = TYMED_HGLOBAL; + + HRESULT hr = selection->QueryGetData(&fetc); + if (FAILED(hr)) + return hr; + + hr = selection->GetData(&fetc, &_stgm); + if (FAILED(hr)) + return hr; + + _pIDList = (LPIDA)GlobalLock(_stgm.hGlobal); + + return hr; + } + + operator LPIDA() {return _pIDList;} + +protected: + STGMEDIUM _stgm; + LPIDA _pIDList; +}; + +extern HRESULT ShellFolderContextMenu(IShellFolder* shell_folder, HWND hwndParent, int cidl, LPCITEMIDLIST* ppidl, int x, int y); diff --git a/reactos/subsys/system/explorer/utility/window.cpp b/reactos/subsys/system/explorer/utility/window.cpp index 4c2ff12c6f3..623d2e1c845 100644 --- a/reactos/subsys/system/explorer/utility/window.cpp +++ b/reactos/subsys/system/explorer/utility/window.cpp @@ -257,7 +257,7 @@ LRESULT Window::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) int Window::Command(int id, int code) { - return 0; + return 1; // WM_COMMAND not yet handled } int Window::Notify(int id, NMHDR* pnmh) @@ -277,12 +277,42 @@ void Window::CancelModes(HWND hwnd) SubclassedWindow::SubclassedWindow(HWND hwnd) : super(hwnd) { - _orgWndProc = SubclassWindow(_hwnd, WindowWndProc); + _orgWndProc = SubclassWindow(_hwnd, SubclassedWndProc); if (!_orgWndProc) delete this; } +LRESULT CALLBACK SubclassedWindow::SubclassedWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam) +{ + SubclassedWindow* pThis = GET_WINDOW(SubclassedWindow, hwnd); + assert(pThis); + + if (pThis) { + switch(nmsg) { + case WM_COMMAND: + if (!pThis->Command(LOWORD(wparam), HIWORD(wparam))) + return 0; + break; + + case WM_NOTIFY: + return pThis->Notify(wparam, (NMHDR*)lparam); + + case WM_CREATE: + return pThis->Init((LPCREATESTRUCT)lparam); + + case WM_NCDESTROY: + delete pThis; + return 0; + + default: + return pThis->WndProc(nmsg, wparam, lparam); + } + } + + return CallWindowProc(pThis->_orgWndProc, hwnd, nmsg, wparam, lparam); +} + LRESULT SubclassedWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) { /*@@TODO: replaced by StartMenu::TrackStartmenu() @@ -294,6 +324,16 @@ LRESULT SubclassedWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) return CallWindowProc(_orgWndProc, _hwnd, nmsg, wparam, lparam); } +int SubclassedWindow::Command(int id, int code) +{ + return 1; // WM_COMMAND not yet handled +} + +int SubclassedWindow::Notify(int id, NMHDR* pnmh) +{ + return CallWindowProc(_orgWndProc, _hwnd, WM_NOTIFY, id, (LPARAM)pnmh); +} + ChildWindow::ChildWindow(HWND hwnd) : super(hwnd) diff --git a/reactos/subsys/system/explorer/utility/window.h b/reactos/subsys/system/explorer/utility/window.h index ccff844229f..0d077debef0 100644 --- a/reactos/subsys/system/explorer/utility/window.h +++ b/reactos/subsys/system/explorer/utility/window.h @@ -169,7 +169,11 @@ struct SubclassedWindow : public Window protected: WNDPROC _orgWndProc; - LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam); + static LRESULT CALLBACK SubclassedWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam); + + virtual LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam); + virtual int Command(int id, int code); + virtual int Notify(int id, NMHDR* pnmh); };
-ROS Explore Source Code Documentation -
generated on 06.12.2003 by +ROS Explorer Source Code Documentation +
generated on 20.12.2003 by
doxygen