In my Shell Namespace Extension I am using SHCreateShellFolderView
to obtain IShellView
when it is requested:
IFACEMETHODIMP ShellFolder::CreateViewObject(HWND hwnd, REFIID riid, void** ppv)
{
if (IsEqualIID(riid, IID_IShellView))
{
HRESULT hr = S_OK;
// Use default shell folder view
SFV_CREATE sfvContext = { sizeof(sfvContext), 0 };
// Query IShellFolder interface from this and put it into csfv.pshf
hr = QueryInterface(IID_PPV_ARGS(&sfvContext.pshf));
// Add IShellFolderViewCB for various callbacks
ShellFolderViewCBHandler* pfvcb = new ShellFolderViewCBHandler(p_folder);
hr = pfvcb->QueryInterface(IID_PPV_ARGS(&sfvContext.psfvcb));
return ::SHCreateShellFolderView(&sfvContext, (IShellView**)ppv);
}
Here ShellFolderViewCBHandler
is implementing the only interface IShellFolderViewCB
with the only intention to set third column as default for sorting in descending order:
IFACEMETHODIMP ShellFolderViewCBHandler::MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case SFVM_GETSORTDEFAULTS:
{
int* const iDirection = reinterpret_cast<int*>(wParam);
int* const iColumn = reinterpret_cast<int*>(lParam);
*iDirection = -1;
*iColumn = 2;
return S_OK;
}
default:
return E_NOTIMPL;
}
}
What currently happens is:
SFVM_GETSORTDEFAULTS
switch case is getting executed and column and direction are set successfully. I can see that in debugger plus because p.2ShellFolder::MapColumnToSCID
with column equal to 2 is called (I guess explorer is querying information about default sorting column).ShellFolder::CompareIDs
is start being called with valid pidls but lParam set to 32761
(Applying int column = lParam & SHCIDS_COLUMNMASK
returns same 32761
for column index).
It does not matter what value I will set for iColumn
in SFVM_GETSORTDEFAULTS
switch case, it will always sort with this magic column index.In the end I don't see that items were sort by column, they are always displayed sorted by display name in ascending order.
So my question is: how to set default sorting column and order?
P.S. I have removed clean up (like Release()
calls) and error checking code to make code samples in question more readable.
I don't see CompareIDs
being called with a crazy number. In my hacked up minimal NSE I can confirm that SFVM_GETSORTDEFAULTS
is called but DefView ignores its values.
There is a undocumented SFVM value that seems to work:
STDMETHODIMP MessageSFVCB(UINT uMsg, WPARAM wp, LPARAM lp)
{
switch (uMsg)
{
case 27:
return (*((int*)lp) = FVM_DETAILS, S_OK);
case 53:
{
int*const iDirection = reinterpret_cast<int*>(wp), *const iColumn = reinterpret_cast<int*>(lp);
*iDirection = 1, *iColumn = 1;
}
return S_OK;
case 92: // When was this added? XP? 2003? Vista?
UINT*data = (UINT*) lp;
MessageSFVCB(27, 0, (SIZE_T) &data[0]); // SFVM_DEFVIEWMODE
data[1] = 0;
MessageSFVCB(53, (SIZE_T) &data[3], (SIZE_T) &data[2]); // SFVM_GETSORTDEFAULTS
return S_OK;
}
return E_NOTIMPL;
}
Another alternative is calling IShellFolderView::Rearrange
but it is hard to control the sort direction if you do this.