https://git.reactos.org/?p=reactos.git;a=commitdiff;h=f1a66daeeb474d81ec7e4b486f5f341b91ee3c16
commit f1a66daeeb474d81ec7e4b486f5f341b91ee3c16 Author: Whindmar Saksit <whinds...@proton.me> AuthorDate: Sun Mar 2 13:07:23 2025 +0100 Commit: GitHub <nore...@github.com> CommitDate: Sun Mar 2 13:07:23 2025 +0100 [SHELL32] Display cut items as ghosted (#7739) - When Ctrl+X is pressed on a selected item, it will appear ghosted until another clipboard action takes place. - Generate SHCNE_UPDATE* notifications when file attributes change. - When an items hidden attribute is changed (filesystem notification), we must update the ghosted state. CORE-9465 --- dll/shellext/netshell/shfldr_netconnect.cpp | 2 +- dll/win32/shell32/CDefView.cpp | 143 +++++++++++++++------ dll/win32/shell32/CDefViewBckgrndMenu.cpp | 4 +- dll/win32/shell32/CDefaultContextMenu.cpp | 8 +- dll/win32/shell32/CNewMenu.cpp | 2 +- dll/win32/shell32/droptargets/CFSDropTarget.cpp | 2 +- dll/win32/shell32/folders/CRecycleBin.cpp | 2 +- dll/win32/shell32/precomp.h | 2 +- .../shell32/shelldesktop/CDirectoryWatcher.cpp | 3 +- dll/win32/shell32/utils.h | 34 +++++ sdk/include/psdk/shobjidl.idl | 1 + sdk/include/reactos/shlguid_undoc.h | 1 - 12 files changed, 158 insertions(+), 46 deletions(-) diff --git a/dll/shellext/netshell/shfldr_netconnect.cpp b/dll/shellext/netshell/shfldr_netconnect.cpp index f7358065054..30689990fcd 100644 --- a/dll/shellext/netshell/shfldr_netconnect.cpp +++ b/dll/shellext/netshell/shfldr_netconnect.cpp @@ -661,7 +661,7 @@ HRESULT WINAPI CNetConUiObject::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi) { HRESULT hr; CComPtr<IShellView> psv; - hr = IUnknown_QueryService(m_pUnknown, SID_IFolderView, IID_PPV_ARG(IShellView, &psv)); + hr = IUnknown_QueryService(m_pUnknown, SID_SFolderView, IID_PPV_ARG(IShellView, &psv)); if (SUCCEEDED(hr)) { SVSIF selFlags = SVSI_DESELECTOTHERS | SVSI_EDIT | SVSI_ENSUREVISIBLE | SVSI_FOCUSED | SVSI_SELECT; diff --git a/dll/win32/shell32/CDefView.cpp b/dll/win32/shell32/CDefView.cpp index 55c99e6f7ad..d78feeb7f86 100644 --- a/dll/win32/shell32/CDefView.cpp +++ b/dll/win32/shell32/CDefView.cpp @@ -238,6 +238,7 @@ private: CComPtr<ICommDlgBrowser> m_pCommDlgBrowser; CComPtr<IFolderFilter> m_pFolderFilter; CComPtr<IShellFolderViewDual> m_pShellFolderViewDual; + ClipboardViewerChain m_ClipboardChain; CListView m_ListView; HWND m_hWndParent; FOLDERSETTINGS m_FolderSettings; @@ -274,6 +275,7 @@ private: BOOL m_isEditing; BOOL m_isParentFolderSpecial; bool m_ScheduledStatusbarUpdate; + bool m_HasCutItems; CLSID m_Category; BOOL m_Destroyed; @@ -313,6 +315,9 @@ public: HRESULT LoadColumn(UINT FoldCol, UINT ListCol, BOOL Insert, UINT ForceWidth = 0); HRESULT LoadColumns(SIZE_T *pColList = NULL, UINT ColListCount = 0); void ColumnListChanged(); + SFGAOF GetItemAttributes(PCUITEMID_CHILD pidl, UINT Query); + SFGAOF GetItemAttributes(int i, UINT Query); + void RefreshGhostedState(); PCUITEMID_CHILD _PidlByItem(int i); PCUITEMID_CHILD _PidlByItem(LVITEM& lvItem); int LV_FindItemByPidl(PCUITEMID_CHILD pidl); @@ -485,6 +490,8 @@ public: LRESULT OnCustomItem(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); LRESULT OnSettingChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); LRESULT OnInitMenuPopup(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); + LRESULT OnChangeCBChain(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); + LRESULT OnDrawClipboard(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); virtual VOID OnFinalMessage(HWND) override; @@ -542,6 +549,8 @@ public: MESSAGE_HANDLER(CWM_GETISHELLBROWSER, OnGetShellBrowser) MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange) MESSAGE_HANDLER(WM_INITMENUPOPUP, OnInitMenuPopup) + MESSAGE_HANDLER(WM_CHANGECBCHAIN, OnChangeCBChain) + MESSAGE_HANDLER(WM_DRAWCLIPBOARD, OnDrawClipboard) END_MSG_MAP() BEGIN_COM_MAP(CDefView) @@ -592,6 +601,7 @@ CDefView::CDefView() : m_isEditing(FALSE), m_isParentFolderSpecial(FALSE), m_ScheduledStatusbarUpdate(false), + m_HasCutItems(false), m_Destroyed(FALSE) { ZeroMemory(&m_FolderSettings, sizeof(m_FolderSettings)); @@ -1287,6 +1297,18 @@ BOOL CDefView::_Sort(int Col) return m_ListView.SortItems(ListViewCompareItems, this); } +SFGAOF CDefView::GetItemAttributes(PCUITEMID_CHILD pidl, UINT Query) +{ + SFGAOF Attr = (SFGAOF)Query; + return SUCCEEDED(m_pSFParent->GetAttributesOf(1, &pidl, &Attr)) ? (Attr & Query) : 0; +} + +SFGAOF CDefView::GetItemAttributes(int i, UINT Query) +{ + PCUITEMID_CHILD pItem = _PidlByItem(i); + return pItem ? GetItemAttributes(pItem, Query) : 0; +} + PCUITEMID_CHILD CDefView::_PidlByItem(int i) { if (!m_ListView) @@ -1342,13 +1364,15 @@ int CDefView::LV_AddItem(PCUITEMID_CHILD pidl) if (_DoFolderViewCB(SFVM_ADDINGOBJECT, 0, (LPARAM)pidl) == S_FALSE) return -1; - lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; // set mask + lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE; lvItem.iItem = m_ListView.GetItemCount(); // add item to lists end lvItem.iSubItem = 0; lvItem.lParam = reinterpret_cast<LPARAM>(ILClone(pidl)); // set item's data lvItem.pszText = LPSTR_TEXTCALLBACKW; // get text on a callback basis lvItem.iImage = I_IMAGECALLBACK; // get image on a callback basis lvItem.stateMask = LVIS_CUT; + if (m_HasCutItems) + lvItem.state = GetItemAttributes(pidl, SFGAO_HIDDEN | SFGAO_GHOSTED) ? LVIS_CUT : 0; return m_ListView.InsertItem(&lvItem); } @@ -1422,14 +1446,21 @@ BOOLEAN CDefView::LV_UpdateItem(PCUITEMID_CHILD pidl) if (-1 != nItem) { - _DoFolderViewCB(SFVM_UPDATINGOBJECT, 0, (LPARAM)pidl); + _DoFolderViewCB(SFVM_UPDATINGOBJECT, nItem, (LPARAM)pidl); - lvItem.mask = LVIF_IMAGE; + lvItem.mask = LVIF_IMAGE | LVIF_STATE; lvItem.iItem = nItem; lvItem.iSubItem = 0; lvItem.iImage = SHMapPIDLToSystemImageListIndex(m_pSFParent, pidl, 0); - m_ListView.SetItem(&lvItem); - m_ListView.Update(nItem); + lvItem.stateMask = LVIS_CUT; + if (m_HasCutItems) + lvItem.state = GetItemAttributes(pidl, SFGAO_HIDDEN | SFGAO_GHOSTED) ? LVIS_CUT : 0; + PCUITEMID_CHILD pidlOld = _PidlByItem(nItem); + if (pidlOld && (lvItem.lParam = reinterpret_cast<LPARAM>(ILClone(pidl))) != NULL) + lvItem.mask |= LVIF_PARAM; + if (m_ListView.SetItem(&lvItem) && lvItem.lParam && pidlOld) + ILFree(const_cast<PUITEMID_CHILD>(pidlOld)); + for (UINT i = 0; m_ListView.SetItemText(nItem, i, LPSTR_TEXTCALLBACK); ++i) {} // Update all columns return TRUE; } @@ -1597,6 +1628,8 @@ LRESULT CDefView::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHand m_Destroyed = TRUE; RevokeDragDrop(m_hWnd); SHChangeNotifyDeregister(m_hNotify); + m_hNotify = NULL; + m_ClipboardChain.Unhook(m_hWnd); if (m_pFileMenu) { IUnknown_SetSite(m_pFileMenu, NULL); @@ -1607,7 +1640,6 @@ LRESULT CDefView::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHand DestroyMenu(m_hMenu); m_hMenu = NULL; } - m_hNotify = NULL; SHFree(m_pidlParent); m_pidlParent = NULL; } @@ -2672,18 +2704,14 @@ LRESULT CDefView::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandl TRACE("-- text=%s\n", debugstr_w(lpdi->item.pszText)); } } - if(lpdi->item.mask & LVIF_IMAGE) /* image requested */ + if (lpdi->item.mask & LVIF_IMAGE) { lpdi->item.iImage = SHMapPIDLToSystemImageListIndex(m_pSFParent, pidl, 0); } - if(lpdi->item.mask & LVIF_STATE) + if (lpdi->item.mask & LVIF_STATE) { - ULONG attributes = SFGAO_HIDDEN; - if (SUCCEEDED(m_pSFParent->GetAttributesOf(1, &pidl, &attributes))) - { - if (attributes & SFGAO_HIDDEN) - lpdi->item.state |= LVIS_CUT; - } + if ((lpdi->item.stateMask & LVIS_CUT) && GetItemAttributes(pidl, SFGAO_HIDDEN | SFGAO_GHOSTED)) + lpdi->item.state |= LVIS_CUT; } lpdi->item.mask |= LVIF_DI_SETITEM; break; @@ -2924,7 +2952,10 @@ LRESULT CDefView::OnChangeNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & break; case SHCNE_UPDATEDIR: case SHCNE_ATTRIBUTES: - Refresh(); + if (child0) + LV_UpdateItem(child0); + else + Refresh(); UpdateStatusbar(); break; case SHCNE_FREESPACE: @@ -3029,6 +3060,31 @@ LRESULT CDefView::OnInitMenuPopup(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL return FALSE; } +LRESULT CDefView::OnChangeCBChain(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) +{ + bHandled = TRUE; + return m_ClipboardChain.HandleChangeCBChain(wParam, lParam); +} + +LRESULT CDefView::OnDrawClipboard(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) +{ + bHandled = TRUE; + const LRESULT res = m_ClipboardChain.HandleDrawClipboard(wParam, lParam); + if (m_HasCutItems) + { + m_ClipboardChain.Unhook(m_hWnd); + m_HasCutItems = false; + m_ListView.SetItemState(-1, 0, LVIS_CUT); // Somebody copied or pasted, nothing can be "cut" anymore + m_ListView.SendMessageW(LVM_SETCALLBACKMASK, m_ListView.SendMessageW(LVM_GETCALLBACKMASK, 0, 0) | LVIS_CUT, 0); + } + return res; +} + +void CDefView::RefreshGhostedState() +{ + for (UINT i = 0, c = m_ListView.GetItemCount(); i < c; ++i) + m_ListView.SetItemState(i, GetItemAttributes(i, SFGAO_HIDDEN | SFGAO_GHOSTED) ? LVIS_CUT : 0, LVIS_CUT); +} // The INTERFACE of the IShellView object @@ -3563,12 +3619,12 @@ HRESULT STDMETHODCALLTYPE CDefView::Item(int iItemIndex, PITEMID_CHILD *ppidl) HRESULT STDMETHODCALLTYPE CDefView::ItemCount(UINT uFlags, int *pcItems) { TRACE("(%p)->(%u %p)\n", this, uFlags, pcItems); - - if (uFlags != SVGIO_ALLVIEW) - FIXME("some flags unsupported, %x\n", uFlags & ~SVGIO_ALLVIEW); - - *pcItems = m_ListView.GetItemCount(); - + if (uFlags != SVGIO_ALLVIEW && uFlags != SVGIO_SELECTION) + FIXME("some flags unsupported, %x\n", uFlags & ~(SVGIO_ALLVIEW | SVGIO_SELECTION)); + if ((uFlags & SVGIO_TYPE_MASK) == SVGIO_SELECTION) + *pcItems = m_ListView.GetSelectedCount(); + else + *pcItems = m_ListView.GetItemCount(); return S_OK; } @@ -3827,14 +3883,15 @@ HRESULT STDMETHODCALLTYPE CDefView::SelectAndPositionItem(LPCITEMIDLIST item, UI HRESULT STDMETHODCALLTYPE CDefView::Rearrange(LPARAM sort) { - FIXME("(%p)->(%ld) stub\n", this, sort); - return E_NOTIMPL; + _Sort(LOWORD(sort & SHCIDS_COLUMNMASK)); + return S_OK; } HRESULT STDMETHODCALLTYPE CDefView::GetArrangeParam(LPARAM *sort) { - FIXME("(%p)->(%p) stub\n", this, sort); - return E_NOTIMPL; + int col = m_sortInfo.ListColumn; + *sort = col != LISTVIEW_SORT_INFO::UNSPECIFIEDCOLUMN ? col : 0; + return col != LISTVIEW_SORT_INFO::UNSPECIFIEDCOLUMN ? S_OK : S_FALSE; } HRESULT STDMETHODCALLTYPE CDefView::ArrangeGrid() @@ -3927,8 +3984,8 @@ HRESULT STDMETHODCALLTYPE CDefView::SetRedraw(BOOL redraw) HRESULT STDMETHODCALLTYPE CDefView::GetSelectedCount(UINT *count) { - FIXME("(%p)->(%p) stub\n", this, count); - return E_NOTIMPL; + *count = m_ListView.GetSelectedCount(); + return S_OK; } HRESULT STDMETHODCALLTYPE CDefView::GetSelectedObjects(PCUITEMID_CHILD **pidl, UINT *items) @@ -3998,8 +4055,26 @@ HRESULT STDMETHODCALLTYPE CDefView::IsBkDropTarget(IDropTarget *drop_target) HRESULT STDMETHODCALLTYPE CDefView::SetClipboard(BOOL move) { - FIXME("(%p)->(%d) stub\n", this, move); - return E_NOTIMPL; + if (!move) + return S_OK; + + UINT CutCount = 0; + for (int i = -1; (i = m_ListView.GetNextItem(i, LVNI_SELECTED)) != -1;) + { + if (!CutCount++) + { + // Turn off the LVIS_CUT LVM_SETCALLBACKMASK optimization + m_ListView.SendMessageW(LVM_SETCALLBACKMASK, m_ListView.SendMessageW(LVM_GETCALLBACKMASK, 0, 0) & ~LVIS_CUT, 0); + RefreshGhostedState(); + } + m_ListView.SetItemState(i, LVIS_CUT, LVIS_CUT); + } + if (CutCount) + { + m_ClipboardChain.Hook(m_hWnd); + m_HasCutItems = true; + } + return S_OK; } HRESULT STDMETHODCALLTYPE CDefView::SetPoints(IDataObject *obj) @@ -4622,12 +4697,9 @@ HRESULT WINAPI CDefView::GetAdvise(DWORD *pAspects, DWORD *pAdvf, IAdviseSink ** HRESULT STDMETHODCALLTYPE CDefView::QueryService(REFGUID guidService, REFIID riid, void **ppvObject) { - if (IsEqualIID(guidService, SID_IShellBrowser) && m_pShellBrowser) - return m_pShellBrowser->QueryInterface(riid, ppvObject); - else if (IsEqualIID(guidService, SID_IFolderView)) + if (IsEqualIID(guidService, SID_SFolderView)) return QueryInterface(riid, ppvObject); - - return E_NOINTERFACE; + return m_pShellBrowser ? IUnknown_QueryService(m_pShellBrowser, guidService, riid, ppvObject) : E_NOINTERFACE; } HRESULT CDefView::_MergeToolbar() @@ -4674,8 +4746,7 @@ HRESULT CDefView_CreateInstance(IShellFolder *pFolder, REFIID riid, LPVOID * ppv return ShellObjectCreatorInit<CDefView>(pFolder, riid, ppvOut); } -HRESULT WINAPI SHCreateShellFolderView(const SFV_CREATE *pcsfv, - IShellView **ppsv) +HRESULT WINAPI SHCreateShellFolderView(const SFV_CREATE *pcsfv, IShellView **ppsv) { CComPtr<IShellView> psv; HRESULT hRes; diff --git a/dll/win32/shell32/CDefViewBckgrndMenu.cpp b/dll/win32/shell32/CDefViewBckgrndMenu.cpp index 740b917f072..ad567c58293 100644 --- a/dll/win32/shell32/CDefViewBckgrndMenu.cpp +++ b/dll/win32/shell32/CDefViewBckgrndMenu.cpp @@ -70,7 +70,7 @@ BOOL CDefViewBckgrndMenu::_bIsDesktopBrowserMenu() /* Get a pointer to the shell browser */ CComPtr<IShellView> psv; - HRESULT hr = IUnknown_QueryService(m_site, SID_IFolderView, IID_PPV_ARG(IShellView, &psv)); + HRESULT hr = IUnknown_QueryService(m_site, SID_SFolderView, IID_PPV_ARG(IShellView, &psv)); if (FAILED_UNEXPECTEDLY(hr)) return FALSE; @@ -265,7 +265,7 @@ CDefViewBckgrndMenu::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi) /* Get a pointer to the shell browser */ CComPtr<IShellView> psv; - HRESULT hr = IUnknown_QueryService(m_site, SID_IFolderView, IID_PPV_ARG(IShellView, &psv)); + HRESULT hr = IUnknown_QueryService(m_site, SID_SFolderView, IID_PPV_ARG(IShellView, &psv)); if (FAILED_UNEXPECTEDLY(hr)) return hr; diff --git a/dll/win32/shell32/CDefaultContextMenu.cpp b/dll/win32/shell32/CDefaultContextMenu.cpp index b076980e7b6..17cffeef96f 100644 --- a/dll/win32/shell32/CDefaultContextMenu.cpp +++ b/dll/win32/shell32/CDefaultContextMenu.cpp @@ -1031,10 +1031,16 @@ HRESULT CDefaultContextMenu::DoCopyOrCut(LPCMINVOKECOMMANDINFOEX lpcmi, BOOL bCo GlobalUnlock(medium.hGlobal); m_pDataObj->SetData(&formatetc, &medium, TRUE); + CComPtr<IShellFolderView> psfv; + if (SUCCEEDED(IUnknown_QueryService(m_site, SID_SFolderView, IID_PPV_ARG(IShellFolderView, &psfv)))) + psfv->SetPoints(m_pDataObj); + HRESULT hr = OleSetClipboard(m_pDataObj); if (FAILED_UNEXPECTEDLY(hr)) return hr; + if (psfv) + psfv->SetClipboard(!bCopy); return S_OK; } @@ -1161,7 +1167,7 @@ CDefaultContextMenu::DoCreateNewFolder( return S_OK; /* Get a pointer to the shell view */ - hr = IUnknown_QueryService(m_site, SID_IFolderView, IID_PPV_ARG(IShellView, &psv)); + hr = IUnknown_QueryService(m_site, SID_SFolderView, IID_PPV_ARG(IShellView, &psv)); if (FAILED_UNEXPECTEDLY(hr)) return S_OK; diff --git a/dll/win32/shell32/CNewMenu.cpp b/dll/win32/shell32/CNewMenu.cpp index bef93ea9860..f525bf4ada4 100644 --- a/dll/win32/shell32/CNewMenu.cpp +++ b/dll/win32/shell32/CNewMenu.cpp @@ -430,7 +430,7 @@ HRESULT CNewMenu::SelectNewItem(LONG wEventId, UINT uFlags, LPWSTR pszName, BOOL return S_OK; /* Get a pointer to the shell view */ - hr = IUnknown_QueryService(m_pSite, SID_IFolderView, IID_PPV_ARG(IShellView, &lpSV)); + hr = IUnknown_QueryService(m_pSite, SID_SFolderView, IID_PPV_ARG(IShellView, &lpSV)); if (FAILED_UNEXPECTEDLY(hr)) return S_OK; diff --git a/dll/win32/shell32/droptargets/CFSDropTarget.cpp b/dll/win32/shell32/droptargets/CFSDropTarget.cpp index e7b5927500e..bc84e7ec939 100644 --- a/dll/win32/shell32/droptargets/CFSDropTarget.cpp +++ b/dll/win32/shell32/droptargets/CFSDropTarget.cpp @@ -468,7 +468,7 @@ HRESULT WINAPI CFSDropTarget::Drop(IDataObject *pDataObject, if (*pdwEffect == DROPEFFECT_MOVE && m_site) { CComPtr<IShellFolderView> psfv; - HRESULT hr = IUnknown_QueryService(m_site, SID_IFolderView, IID_PPV_ARG(IShellFolderView, &psfv)); + HRESULT hr = IUnknown_QueryService(m_site, SID_SFolderView, IID_PPV_ARG(IShellFolderView, &psfv)); if (SUCCEEDED(hr) && psfv->IsDropOnSource(this) == S_OK) { _RepositionItems(psfv, pDataObject, pt); diff --git a/dll/win32/shell32/folders/CRecycleBin.cpp b/dll/win32/shell32/folders/CRecycleBin.cpp index 6508e071326..5051c619d7e 100644 --- a/dll/win32/shell32/folders/CRecycleBin.cpp +++ b/dll/win32/shell32/folders/CRecycleBin.cpp @@ -505,7 +505,7 @@ fail: return mem; } -typedef struct +typedef struct _FILEOPDATA { PCUITEMID_CHILD_ARRAY apidl; UINT cidl, index; diff --git a/dll/win32/shell32/precomp.h b/dll/win32/shell32/precomp.h index 2d9e2776d6a..c1ae067bb98 100644 --- a/dll/win32/shell32/precomp.h +++ b/dll/win32/shell32/precomp.h @@ -322,7 +322,7 @@ InvokeIExecuteCommandWithDataObject( _In_opt_ LPCMINVOKECOMMANDINFOEX pICI, _In_opt_ IUnknown *pSite); -typedef enum { +typedef enum _FILEOPCALLBACKEVENT { FOCE_STARTOPERATIONS, FOCE_FINISHOPERATIONS, FOCE_PREMOVEITEM, diff --git a/dll/win32/shell32/shelldesktop/CDirectoryWatcher.cpp b/dll/win32/shell32/shelldesktop/CDirectoryWatcher.cpp index 1bb7d80cb30..d24e1540a6e 100644 --- a/dll/win32/shell32/shelldesktop/CDirectoryWatcher.cpp +++ b/dll/win32/shell32/shelldesktop/CDirectoryWatcher.cpp @@ -299,7 +299,8 @@ GetFilterFromEvents(DWORD fEvents) return (FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_CREATION | - FILE_NOTIFY_CHANGE_SIZE); + FILE_NOTIFY_CHANGE_SIZE | + FILE_NOTIFY_CHANGE_ATTRIBUTES); } // Restart a watch by using ReadDirectoryChangesW function diff --git a/dll/win32/shell32/utils.h b/dll/win32/shell32/utils.h index a4effec8964..4f546fa483f 100644 --- a/dll/win32/shell32/utils.h +++ b/dll/win32/shell32/utils.h @@ -90,3 +90,37 @@ SHELL_CreateFallbackExtractIconForNoAssocFile(REFIID riid, LPVOID *ppvOut) const int id = IDI_SHELL_DOCUMENT; return SHELL_CreateShell32DefaultExtractIcon(id > 1 ? -id : 0, riid, ppvOut); } + +struct ClipboardViewerChain +{ + HWND m_hWndNext = HWND_BOTTOM; + + void Unhook(HWND hWnd) + { + if (m_hWndNext != HWND_BOTTOM) + ChangeClipboardChain(hWnd, m_hWndNext); + m_hWndNext = HWND_BOTTOM; + } + + void Hook(HWND hWnd) + { + if (m_hWndNext == HWND_BOTTOM) + m_hWndNext = SetClipboardViewer(hWnd); + } + + LRESULT HandleChangeCBChain(WPARAM wParam, LPARAM lParam) + { + if (m_hWndNext == (HWND)wParam) + return (LRESULT)(m_hWndNext = (HWND)lParam); + else if (m_hWndNext && m_hWndNext != HWND_BOTTOM) + return ::SendMessageW(m_hWndNext, WM_CHANGECBCHAIN, wParam, lParam); + return 0; + } + + LRESULT HandleDrawClipboard(WPARAM wParam, LPARAM lParam) + { + if (m_hWndNext && m_hWndNext != HWND_BOTTOM) + return ::SendMessageW(m_hWndNext, WM_DRAWCLIPBOARD, wParam, lParam); + return 0; + } +}; diff --git a/sdk/include/psdk/shobjidl.idl b/sdk/include/psdk/shobjidl.idl index 8738863eb55..777cfde2e4a 100644 --- a/sdk/include/psdk/shobjidl.idl +++ b/sdk/include/psdk/shobjidl.idl @@ -898,6 +898,7 @@ interface IFolderView : IUnknown [in] DWORD flags ); } +cpp_quote("#define SID_SFolderView IID_IFolderView") [v1_enum] enum tagSORTDIRECTION { diff --git a/sdk/include/reactos/shlguid_undoc.h b/sdk/include/reactos/shlguid_undoc.h index 01dbfda2fe2..52aad4a13fb 100644 --- a/sdk/include/reactos/shlguid_undoc.h +++ b/sdk/include/reactos/shlguid_undoc.h @@ -211,7 +211,6 @@ DEFINE_GUID(IID_IPinnedList, 0xBBD20037, 0xBC0E, 0x42F1, 0x91, 0x3 #define SID_STravelLogCursor IID_ITravelLogStg #define SID_IBandSite IID_IBandSite -#define SID_IFolderView IID_IFolderView #define SID_IShellBrowser IID_IShellBrowser #endif // __SHLGUID_UNDOC_H