EDN Admin
Well-known member
This is a follow up to a question I had posted earlier :
http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/c1cd6993-9018-47b6-b04d-304795a7aecc
I have written a namespace extension that uses the System Folder View Object, as indicated in the previous post. I have never gotten the contents of Explorer to refresh programatically. I have tried every permutation of things I can think of.
In this specific instance, I would like explorer to refresh after a user right clicks an item and deletes it. The delete function is implemented in my own class that implements IContextMenu, but only for items in the view, not the view itself.
The closest I can get to making the Explorer window do any kind of refreshing is to have it repaint the Icons when I right click on one of them, and select the "Delete" menu item. From inside the Delete() function, I call :
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST | SHCNF_FLUSH, m_parent, NULL);
where m_parent is the PIDL for the clicked items parent folder. This repaints all of the icons.
The only other thing I have been able to accomplish, again, from inside the Delete() function, is to call
SHChangeNotify(SHCNE_DELETE, SHCNF_IDLIST | SHCNF_FLUSH, m_pidl, 0);
where m_pidl is the PIDL for the item that was right clicked, and selected for deletion.
This causes the view to revert back to "Computer" after removing the right clicked item from the view.
The functionality I am attempting to duplicate is the refresh that happens when a user right clicks on the system folder view and selects "Refresh". This causes the view to refresh its contents entirely, via the EnumObjects function on the IShellFolder
interface of the views folder.
I have tried everything I can think of to try to do this programatically, but havent been able to make it work.
Does anybody know what series of events happens when a user right clicks on "Refresh" from the default context menu that is shown for the system folder view object ? I have created my own Context Menu (IContextMenu) implementation for the items in the view,
but I still use the default context menu for the view itself, for which Refresh is a default menu item. As a side note: The refrsh functionality from the status bar works too (Im running on 64-bit Windows 7).
I have tried using Spy++ (The 64-bit version) to reverse engineer whats happening, but I havent found anything of use from that either.
As a point of reference, I have attached the code from inside my Delete() function.
The bottom of this code has some attempts at messaging the window to refresh, but that didnt work either.
Many thanks in advance for any insights into this problem.
JT.
<pre class="prettyprint VOID CContextMenu:elete( VOID )
{
CoInitialize(NULL);
// Do some COM Stuff to update the database with the deleted item
// Now, try to refresh the view
// m_pidl is the PIDL for the deleted item
// m_parent is the PIDL for the items parent folder
// m_pidlFullPath is the fully qualified absolute PIDL for the items parent folder. This is the same as m_parent, but I re-built the PIDL as m_pidlFullPath just for good measure in case m_parent was somehow corrupted.
// These are just debugging statements to make sure we have selected what we think weve selected
PWCHAR location;
location = m_pPidlMgr->GetData(m_pidl);
MessageBox(NULL,location,_T("m_pidl"),MB_OK);
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST | SHCNF_FLUSH, m_parent, NULL);
SHChangeNotify(SHCNE_ALLEVENTS, SHCNF_IDLIST | SHCNF_FLUSH, m_parent, NULL);
PWCHAR parent;
parent = m_pPidlMgr->GetData(m_parent);
MessageBox(NULL,parent,_T("m_parent"),MB_OK);
PWCHAR path;
path = m_pPidlMgr->GetData(m_pidlFullPath);
MessageBox(NULL,path,_T("m_pidlFullPath"),MB_OK);
MessageBox(NULL,_T("Refreshing"),_T("m_pidl"),MB_OK);
// THis causes the view to go back to My Computer:
SHChangeNotify(SHCNE_DELETE, SHCNF_IDLIST | CHCNF_FLUSH, m_pidl, 0);
// ShChangeNotify didnt work, so lets try messaging ( this didnt work either )
MessageBox(NULL, _T("Send Message: FM_REFRESH_WINDOWS"), _T("ContextMenu"), MB_OK);
::SendMessage(m_hWnd, FM_REFRESH_WINDOWS, 0, TRUE);
::UpdateWindow(m_hWnd);
MessageBox(NULL, _T("Send Message: FMEVENT_USER_REFRESH 0"), _T("ContextMenu"), MB_OK);
::SendMessage(m_hWnd, FMEVENT_USER_REFRESH, 0, 0);
MessageBox(NULL, _T("Done sending Message"), _T("ContextMenu"), MB_OK);
return;
}[/code]
<br/>
<br/>
<span class="x_x_Apple-tab-span" style="white-spacere
<span class="x_x_Apple-tab-span" style="white-spacere
<span class="x_x_Apple-tab-span" style="white-spacere
<span class="x_x_Apple-tab-span" style="white-spacere
<br/>
View the full article
http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/c1cd6993-9018-47b6-b04d-304795a7aecc
I have written a namespace extension that uses the System Folder View Object, as indicated in the previous post. I have never gotten the contents of Explorer to refresh programatically. I have tried every permutation of things I can think of.
In this specific instance, I would like explorer to refresh after a user right clicks an item and deletes it. The delete function is implemented in my own class that implements IContextMenu, but only for items in the view, not the view itself.
The closest I can get to making the Explorer window do any kind of refreshing is to have it repaint the Icons when I right click on one of them, and select the "Delete" menu item. From inside the Delete() function, I call :
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST | SHCNF_FLUSH, m_parent, NULL);
where m_parent is the PIDL for the clicked items parent folder. This repaints all of the icons.
The only other thing I have been able to accomplish, again, from inside the Delete() function, is to call
SHChangeNotify(SHCNE_DELETE, SHCNF_IDLIST | SHCNF_FLUSH, m_pidl, 0);
where m_pidl is the PIDL for the item that was right clicked, and selected for deletion.
This causes the view to revert back to "Computer" after removing the right clicked item from the view.
The functionality I am attempting to duplicate is the refresh that happens when a user right clicks on the system folder view and selects "Refresh". This causes the view to refresh its contents entirely, via the EnumObjects function on the IShellFolder
interface of the views folder.
I have tried everything I can think of to try to do this programatically, but havent been able to make it work.
Does anybody know what series of events happens when a user right clicks on "Refresh" from the default context menu that is shown for the system folder view object ? I have created my own Context Menu (IContextMenu) implementation for the items in the view,
but I still use the default context menu for the view itself, for which Refresh is a default menu item. As a side note: The refrsh functionality from the status bar works too (Im running on 64-bit Windows 7).
I have tried using Spy++ (The 64-bit version) to reverse engineer whats happening, but I havent found anything of use from that either.
As a point of reference, I have attached the code from inside my Delete() function.
The bottom of this code has some attempts at messaging the window to refresh, but that didnt work either.
Many thanks in advance for any insights into this problem.
JT.
<pre class="prettyprint VOID CContextMenu:elete( VOID )
{
CoInitialize(NULL);
// Do some COM Stuff to update the database with the deleted item
// Now, try to refresh the view
// m_pidl is the PIDL for the deleted item
// m_parent is the PIDL for the items parent folder
// m_pidlFullPath is the fully qualified absolute PIDL for the items parent folder. This is the same as m_parent, but I re-built the PIDL as m_pidlFullPath just for good measure in case m_parent was somehow corrupted.
// These are just debugging statements to make sure we have selected what we think weve selected
PWCHAR location;
location = m_pPidlMgr->GetData(m_pidl);
MessageBox(NULL,location,_T("m_pidl"),MB_OK);
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST | SHCNF_FLUSH, m_parent, NULL);
SHChangeNotify(SHCNE_ALLEVENTS, SHCNF_IDLIST | SHCNF_FLUSH, m_parent, NULL);
PWCHAR parent;
parent = m_pPidlMgr->GetData(m_parent);
MessageBox(NULL,parent,_T("m_parent"),MB_OK);
PWCHAR path;
path = m_pPidlMgr->GetData(m_pidlFullPath);
MessageBox(NULL,path,_T("m_pidlFullPath"),MB_OK);
MessageBox(NULL,_T("Refreshing"),_T("m_pidl"),MB_OK);
// THis causes the view to go back to My Computer:
SHChangeNotify(SHCNE_DELETE, SHCNF_IDLIST | CHCNF_FLUSH, m_pidl, 0);
// ShChangeNotify didnt work, so lets try messaging ( this didnt work either )
MessageBox(NULL, _T("Send Message: FM_REFRESH_WINDOWS"), _T("ContextMenu"), MB_OK);
::SendMessage(m_hWnd, FM_REFRESH_WINDOWS, 0, TRUE);
::UpdateWindow(m_hWnd);
MessageBox(NULL, _T("Send Message: FMEVENT_USER_REFRESH 0"), _T("ContextMenu"), MB_OK);
::SendMessage(m_hWnd, FMEVENT_USER_REFRESH, 0, 0);
MessageBox(NULL, _T("Done sending Message"), _T("ContextMenu"), MB_OK);
return;
}[/code]
<br/>
<br/>
<span class="x_x_Apple-tab-span" style="white-spacere
<span class="x_x_Apple-tab-span" style="white-spacere
<span class="x_x_Apple-tab-span" style="white-spacere
<span class="x_x_Apple-tab-span" style="white-spacere
<br/>
View the full article