mirror of
https://github.com/reactos/reactos.git
synced 2025-04-20 20:36:35 +00:00
[SHELL32]
- Correctly handle recursive change notifications in CDefView - Remove desktop folder hack from SHChangeNotify and move it to CDefView until we have ITranslateShellChangeNotify Fixes phantom files/folders on desktop. Based on a patch by Huw Campbell. CORE-8844 svn path=/trunk/; revision=66901
This commit is contained in:
parent
8114dd9fe0
commit
508a03733a
2 changed files with 54 additions and 31 deletions
|
@ -93,6 +93,7 @@ class CDefView :
|
||||||
UINT m_uState;
|
UINT m_uState;
|
||||||
UINT m_cidl;
|
UINT m_cidl;
|
||||||
PCUITEMID_CHILD_ARRAY m_apidl;
|
PCUITEMID_CHILD_ARRAY m_apidl;
|
||||||
|
PIDLIST_ABSOLUTE m_pidlParent;
|
||||||
LISTVIEW_SORT_INFO m_sortInfo;
|
LISTVIEW_SORT_INFO m_sortInfo;
|
||||||
ULONG m_hNotify; /* change notification handle */
|
ULONG m_hNotify; /* change notification handle */
|
||||||
HACCEL m_hAccel;
|
HACCEL m_hAccel;
|
||||||
|
@ -354,6 +355,7 @@ CDefView::CDefView() :
|
||||||
m_uState(0),
|
m_uState(0),
|
||||||
m_cidl(0),
|
m_cidl(0),
|
||||||
m_apidl(NULL),
|
m_apidl(NULL),
|
||||||
|
m_pidlParent(NULL),
|
||||||
m_hNotify(0),
|
m_hNotify(0),
|
||||||
m_hAccel(NULL),
|
m_hAccel(NULL),
|
||||||
m_dwAspects(0),
|
m_dwAspects(0),
|
||||||
|
@ -943,6 +945,7 @@ LRESULT CDefView::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHand
|
||||||
DestroyMenu(m_hMenu);
|
DestroyMenu(m_hMenu);
|
||||||
RevokeDragDrop(m_hWnd);
|
RevokeDragDrop(m_hWnd);
|
||||||
SHChangeNotifyDeregister(m_hNotify);
|
SHChangeNotifyDeregister(m_hNotify);
|
||||||
|
SHFree(m_pidlParent);
|
||||||
bHandled = FALSE;
|
bHandled = FALSE;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1000,12 +1003,10 @@ LRESULT CDefView::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandl
|
||||||
m_pSFParent->QueryInterface(IID_PPV_ARG(IPersistFolder2, &ppf2));
|
m_pSFParent->QueryInterface(IID_PPV_ARG(IPersistFolder2, &ppf2));
|
||||||
if (ppf2)
|
if (ppf2)
|
||||||
{
|
{
|
||||||
PIDLIST_ABSOLUTE pidlParent;
|
ppf2->GetCurFolder(&m_pidlParent);
|
||||||
ppf2->GetCurFolder(&pidlParent);
|
|
||||||
ntreg.fRecursive = TRUE;
|
ntreg.fRecursive = TRUE;
|
||||||
ntreg.pidl = pidlParent;
|
ntreg.pidl = m_pidlParent;
|
||||||
m_hNotify = SHChangeNotifyRegister(m_hWnd, SHCNF_IDLIST, SHCNE_ALLEVENTS, SHV_CHANGE_NOTIFY, 1, &ntreg);
|
m_hNotify = SHChangeNotifyRegister(m_hWnd, SHCNRF_InterruptLevel | SHCNRF_ShellLevel, SHCNE_ALLEVENTS, SHV_CHANGE_NOTIFY, 1, &ntreg);
|
||||||
SHFree(pidlParent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_hAccel = LoadAcceleratorsW(shell32_hInstance, MAKEINTRESOURCEW(IDA_SHELLVIEW));
|
m_hAccel = LoadAcceleratorsW(shell32_hInstance, MAKEINTRESOURCEW(IDA_SHELLVIEW));
|
||||||
|
@ -1848,12 +1849,48 @@ LRESULT CDefView::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandl
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is just a quick hack to make the desktop work correctly.
|
||||||
|
* ITranslateShellChangeNotify's IsChildID is undocumented, but most likely the way that
|
||||||
|
* a folder should know if it should update upon a change notification.
|
||||||
|
* It is exported by merged folders at a minimum.
|
||||||
|
*/
|
||||||
|
static BOOL ILIsParentOrSpecialParent(PCIDLIST_ABSOLUTE pidl1, PCIDLIST_ABSOLUTE pidl2)
|
||||||
|
{
|
||||||
|
if (!pidl1 || !pidl2)
|
||||||
|
return FALSE;
|
||||||
|
if (ILIsParent(pidl1, pidl2, TRUE))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (_ILIsDesktop(pidl1))
|
||||||
|
{
|
||||||
|
PIDLIST_ABSOLUTE deskpidl;
|
||||||
|
SHGetFolderLocation(NULL, CSIDL_DESKTOPDIRECTORY, NULL, 0, &deskpidl);
|
||||||
|
if (ILIsParent(deskpidl, pidl2, TRUE))
|
||||||
|
{
|
||||||
|
ILFree(deskpidl);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
ILFree(deskpidl);
|
||||||
|
SHGetFolderLocation(NULL, CSIDL_COMMON_DESKTOPDIRECTORY, NULL, 0, &deskpidl);
|
||||||
|
if (ILIsParent(deskpidl, pidl2, TRUE))
|
||||||
|
{
|
||||||
|
ILFree(deskpidl);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
ILFree(deskpidl);
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/**********************************************************
|
/**********************************************************
|
||||||
* ShellView_OnChange()
|
* ShellView_OnChange()
|
||||||
*/
|
*/
|
||||||
LRESULT CDefView::OnChangeNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
|
LRESULT CDefView::OnChangeNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
|
||||||
{
|
{
|
||||||
PCIDLIST_ABSOLUTE *Pidls = reinterpret_cast<PCIDLIST_ABSOLUTE*>(wParam);
|
PCIDLIST_ABSOLUTE *Pidls = reinterpret_cast<PCIDLIST_ABSOLUTE*>(wParam);
|
||||||
|
BOOL bParent0 = ILIsParentOrSpecialParent(m_pidlParent, Pidls[0]);
|
||||||
|
BOOL bParent1 = ILIsParentOrSpecialParent(m_pidlParent, Pidls[1]);
|
||||||
|
|
||||||
TRACE("(%p)(%p,%p,0x%08x)\n", this, Pidls[0], Pidls[1], lParam);
|
TRACE("(%p)(%p,%p,0x%08x)\n", this, Pidls[0], Pidls[1], lParam);
|
||||||
|
|
||||||
|
@ -1861,20 +1898,28 @@ LRESULT CDefView::OnChangeNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &
|
||||||
{
|
{
|
||||||
case SHCNE_MKDIR:
|
case SHCNE_MKDIR:
|
||||||
case SHCNE_CREATE:
|
case SHCNE_CREATE:
|
||||||
|
if (bParent0)
|
||||||
LV_AddItem(ILFindLastID(Pidls[0]));
|
LV_AddItem(ILFindLastID(Pidls[0]));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SHCNE_RMDIR:
|
case SHCNE_RMDIR:
|
||||||
case SHCNE_DELETE:
|
case SHCNE_DELETE:
|
||||||
|
if (bParent0)
|
||||||
LV_DeleteItem(ILFindLastID(Pidls[0]));
|
LV_DeleteItem(ILFindLastID(Pidls[0]));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SHCNE_RENAMEFOLDER:
|
case SHCNE_RENAMEFOLDER:
|
||||||
case SHCNE_RENAMEITEM:
|
case SHCNE_RENAMEITEM:
|
||||||
|
if (bParent0 && bParent1)
|
||||||
LV_RenameItem(ILFindLastID(Pidls[0]), ILFindLastID(Pidls[1]));
|
LV_RenameItem(ILFindLastID(Pidls[0]), ILFindLastID(Pidls[1]));
|
||||||
|
else if (bParent0)
|
||||||
|
LV_DeleteItem(ILFindLastID(Pidls[0]));
|
||||||
|
else if (bParent1)
|
||||||
|
LV_AddItem(ILFindLastID(Pidls[0]));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SHCNE_UPDATEITEM:
|
case SHCNE_UPDATEITEM:
|
||||||
|
if (bParent0)
|
||||||
LV_RenameItem(ILFindLastID(Pidls[0]), ILFindLastID(Pidls[0]));
|
LV_RenameItem(ILFindLastID(Pidls[0]), ILFindLastID(Pidls[0]));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -255,28 +255,6 @@ static BOOL should_notify( LPCITEMIDLIST changed, LPCITEMIDLIST watched, BOOL su
|
||||||
return TRUE;
|
return TRUE;
|
||||||
if( sub && ILIsParent( watched, changed, FALSE ) )
|
if( sub && ILIsParent( watched, changed, FALSE ) )
|
||||||
return TRUE;
|
return TRUE;
|
||||||
#ifdef __REACTOS__
|
|
||||||
if (sub && _ILIsDesktop(watched)) {
|
|
||||||
LPITEMIDLIST deskpidl;
|
|
||||||
WCHAR wszPath[MAX_PATH];
|
|
||||||
SHGetSpecialFolderPathW(0, wszPath, CSIDL_DESKTOPDIRECTORY, FALSE);
|
|
||||||
deskpidl = SHSimpleIDListFromPathW(wszPath);
|
|
||||||
if (ILIsParent(deskpidl, changed, TRUE))
|
|
||||||
{
|
|
||||||
ILFree(deskpidl);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
ILFree(deskpidl);
|
|
||||||
SHGetSpecialFolderPathW(0, wszPath, CSIDL_COMMON_DESKTOPDIRECTORY, FALSE);
|
|
||||||
deskpidl = SHSimpleIDListFromPathW(wszPath);
|
|
||||||
if (ILIsParent(deskpidl, changed, TRUE))
|
|
||||||
{
|
|
||||||
ILFree(deskpidl);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
ILFree(deskpidl);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue