[SHELL32]

- Implement CompareIDs for the folders in the shell namespace. The previous implementation was a generic solution that just compared names.
- CDefView: Implement using CompareIDs method from the IShellFolder. Remove the previous implementation that was hardcoded in the CDefView and worked mostly for file items.

svn path=/trunk/; revision=69712
This commit is contained in:
Giannis Adamopoulos 2015-10-26 15:07:44 +00:00
parent 07ca1a7a5c
commit 3328daaf08
10 changed files with 213 additions and 220 deletions

View file

@ -131,7 +131,6 @@ class CDefView :
BOOL CreateList();
void UpdateListColors();
BOOL InitList();
static INT CALLBACK CompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData);
static INT CALLBACK ListViewCompareItems(LPARAM lParam1, LPARAM lParam2, LPARAM lpData);
PCUITEMID_CHILD _PidlByItem(int i);
@ -335,13 +334,6 @@ class CDefView :
END_COM_MAP()
};
/* ListView Header ID's */
#define LISTVIEW_COLUMN_NAME 0
#define LISTVIEW_COLUMN_SIZE 1
#define LISTVIEW_COLUMN_TYPE 2
#define LISTVIEW_COLUMN_TIME 3
#define LISTVIEW_COLUMN_ATTRIB 4
/*menu items */
#define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
#define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
@ -648,30 +640,6 @@ BOOL CDefView::InitList()
return TRUE;
}
/**********************************************************
* ShellView_CompareItems()
*
* NOTES
* internal, CALLBACK for DSA_Sort
*/
INT CALLBACK CDefView::CompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData)
{
int ret;
TRACE("pidl1=%p pidl2=%p lpsf=%p\n", lParam1, lParam2, (LPVOID) lpData);
if (!lpData)
return 0;
IShellFolder* psf = reinterpret_cast<IShellFolder*>(lpData);
PCUIDLIST_RELATIVE pidl1 = reinterpret_cast<PCUIDLIST_RELATIVE>(lParam1);
PCUIDLIST_RELATIVE pidl2 = reinterpret_cast<PCUIDLIST_RELATIVE>(lParam2);
ret = (SHORT)SCODE_CODE(psf->CompareIDs(0, pidl1, pidl2));
TRACE("ret=%i\n", ret);
return ret;
}
/*************************************************************************
* ShellView_ListViewCompareItems
*
@ -686,89 +654,20 @@ INT CALLBACK CDefView::CompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpDat
* A negative value if the first item should precede the second,
* a positive value if the first item should follow the second,
* or zero if the two items are equivalent
*
* NOTES
* FIXME: function does what ShellView_CompareItems is supposed to do.
* unify it and figure out how to use the undocumented first parameter
* of IShellFolder_CompareIDs to do the job this function does and
* move this code to IShellFolder.
* make LISTVIEW_SORT_INFO obsolete
* the way this function works is only usable if we had only
* filesystemfolders (25/10/99 jsch)
*/
INT CALLBACK CDefView::ListViewCompareItems(LPARAM lParam1, LPARAM lParam2, LPARAM lpData)
{
INT nDiff = 0;
FILETIME fd1, fd2;
char strName1[MAX_PATH], strName2[MAX_PATH];
BOOL bIsFolder1, bIsFolder2, bIsBothFolder;
PCUIDLIST_RELATIVE pidl1 = reinterpret_cast<PCUIDLIST_RELATIVE>(lParam1);
PCUIDLIST_RELATIVE pidl2 = reinterpret_cast<PCUIDLIST_RELATIVE>(lParam2);
LISTVIEW_SORT_INFO *pSortInfo = reinterpret_cast<LPLISTVIEW_SORT_INFO>(lpData);
CDefView *pThis = reinterpret_cast<CDefView*>(lpData);
HRESULT hres = pThis->m_pSFParent->CompareIDs(pThis->m_sortInfo.nHeaderID, pidl1, pidl2);
if (FAILED_UNEXPECTEDLY(hres))
return 0;
bIsFolder1 = _ILIsFolder(pidl1);
bIsFolder2 = _ILIsFolder(pidl2);
bIsBothFolder = bIsFolder1 && bIsFolder2;
/* When sorting between a File and a Folder, the Folder gets sorted first */
if ( (bIsFolder1 || bIsFolder2) && !bIsBothFolder)
{
nDiff = bIsFolder1 ? -1 : 1;
}
else
{
/* Sort by Time: Folders or Files can be sorted */
if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_TIME)
{
_ILGetFileDateTime(pidl1, &fd1);
_ILGetFileDateTime(pidl2, &fd2);
nDiff = CompareFileTime(&fd2, &fd1);
}
/* Sort by Attribute: Folder or Files can be sorted */
else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_ATTRIB)
{
_ILGetFileAttributes(pidl1, strName1, MAX_PATH);
_ILGetFileAttributes(pidl2, strName2, MAX_PATH);
nDiff = lstrcmpiA(strName1, strName2);
}
/* Sort by FileName: Folder or Files can be sorted */
else if (pSortInfo->nHeaderID == LISTVIEW_COLUMN_NAME || bIsBothFolder)
{
/* Sort by Text */
_ILSimpleGetText(pidl1, strName1, MAX_PATH);
_ILSimpleGetText(pidl2, strName2, MAX_PATH);
nDiff = lstrcmpiA(strName1, strName2);
}
/* Sort by File Size, Only valid for Files */
else if (pSortInfo->nHeaderID == LISTVIEW_COLUMN_SIZE)
{
nDiff = (INT)(_ILGetFileSize(pidl1, NULL, 0) - _ILGetFileSize(pidl2, NULL, 0));
}
/* Sort by File Type, Only valid for Files */
else if (pSortInfo->nHeaderID == LISTVIEW_COLUMN_TYPE)
{
/* Sort by Type */
_ILGetFileType(pidl1, strName1, MAX_PATH);
_ILGetFileType(pidl2, strName2, MAX_PATH);
nDiff = lstrcmpiA(strName1, strName2);
}
}
/* If the Date, FileSize, FileType, Attrib was the same, sort by FileName */
if (nDiff == 0)
{
_ILSimpleGetText(pidl1, strName1, MAX_PATH);
_ILSimpleGetText(pidl2, strName2, MAX_PATH);
nDiff = lstrcmpiA(strName1, strName2);
}
if (!pSortInfo->bIsAscending)
{
SHORT nDiff = HRESULT_CODE(hres);
if (!pThis->m_sortInfo.bIsAscending)
nDiff = -nDiff;
}
return nDiff;
}
@ -975,14 +874,17 @@ HRESULT CDefView::FillList()
}
}
/* sort the array */
DPA_Sort(hdpa, CompareItems, reinterpret_cast<LPARAM>(m_pSFParent.p));
/*turn the listview's redrawing off*/
m_ListView.SetRedraw(FALSE);
DPA_DestroyCallback( hdpa, fill_list, this);
/* sort the array */
m_pSF2Parent->GetDefaultColumn(NULL, (ULONG*)&m_sortInfo.nHeaderID, NULL);
m_sortInfo.bIsAscending = TRUE;
m_sortInfo.nLastHeaderID = m_sortInfo.nHeaderID;
m_ListView.SortItems(ListViewCompareItems, this);
/*turn the listview's redrawing back on and force it to draw*/
m_ListView.SetRedraw(TRUE);
@ -1658,7 +1560,7 @@ LRESULT CDefView::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHand
m_sortInfo.nHeaderID = dwCmdID - 0x30;
m_sortInfo.bIsAscending = TRUE;
m_sortInfo.nLastHeaderID = m_sortInfo.nHeaderID;
m_ListView.SortItems(ListViewCompareItems, &m_sortInfo);
m_ListView.SortItems(ListViewCompareItems, this);
break;
case FCIDM_SHVIEW_SELECTALL:
@ -1788,7 +1690,7 @@ LRESULT CDefView::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandl
m_sortInfo.bIsAscending = TRUE;
m_sortInfo.nLastHeaderID = m_sortInfo.nHeaderID;
m_ListView.SortItems(ListViewCompareItems, &m_sortInfo);
m_ListView.SortItems(ListViewCompareItems, this);
break;
case LVN_GETDISPINFOA:

View file

@ -49,7 +49,7 @@ class CControlPanelEnum :
*/
static const shvheader ControlPanelSFHeader[] = {
{IDS_SHV_COLUMN8, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 15},/*FIXME*/
{IDS_SHV_COLUMN8, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 20},/*FIXME*/
{IDS_SHV_COLUMN9, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 80},/*FIXME*/
};
@ -336,15 +336,34 @@ HRESULT WINAPI CControlPanelFolder::BindToStorage(
/**************************************************************************
* CControlPanelFolder::CompareIDs
*/
HRESULT WINAPI CControlPanelFolder::CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2)
{
int nReturn;
/* Dont use SHELL32_CompareGuidItems because it would cause guid items to come first */
if (_ILIsSpecialFolder(pidl1) || _ILIsSpecialFolder(pidl2))
{
return SHELL32_CompareDetails(this, lParam, pidl1, pidl2);
}
PIDLCPanelStruct *pData1 = _ILGetCPanelPointer(pidl1);
PIDLCPanelStruct *pData2 = _ILGetCPanelPointer(pidl2);
TRACE("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n", this, lParam, pidl1, pidl2);
nReturn = SHELL32_CompareIDs(this, lParam, pidl1, pidl2);
TRACE("-- %i\n", nReturn);
return nReturn;
if (!pData1 || !pData2 || LOWORD(lParam)>= CONROLPANELSHELLVIEWCOLUMNS)
return E_INVALIDARG;
int result;
switch(LOWORD(lParam))
{
case 0: /* name */
result = wcsicmp(pData1->szName + pData1->offsDispName, pData2->szName + pData2->offsDispName);
break;
case 1: /* comment */
result = wcsicmp(pData1->szName + pData1->offsComment, pData2->szName + pData2->offsComment);
break;
default:
ERR("Got wrong lParam!\n");
return E_INVALIDARG;
}
return MAKE_COMPARE_HRESULT(result);
}
/**************************************************************************

View file

@ -63,14 +63,13 @@ class CDesktopFolderEnum :
int SHELL_ConfirmMsgBox(HWND hWnd, LPWSTR lpszText, LPWSTR lpszCaption, HICON hIcon, BOOL bYesToAll);
static const shvheader DesktopSFHeader[] = {
{IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15},
{IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 15},
{IDS_SHV_COLUMN2, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
{IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
{IDS_SHV_COLUMN4, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 12},
{IDS_SHV_COLUMN5, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 5}
{IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 10},
{IDS_SHV_COLUMN4, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 12},
};
#define DESKTOPSHELLVIEWCOLUMNS 5
#define DESKTOPSHELLVIEWCOLUMNS 4
static const DWORD dwDesktopAttributes =
SFGAO_HASSUBFOLDER | SFGAO_FILESYSTEM | SFGAO_FOLDER | SFGAO_FILESYSANCESTOR |
@ -465,7 +464,7 @@ HRESULT WINAPI CDesktopFolder::BindToStorage(
HRESULT WINAPI CDesktopFolder::CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2)
{
if (_ILIsSpecialFolder(pidl1) || _ILIsSpecialFolder(pidl2))
return SHELL32_CompareIDs ((IShellFolder *)this, lParam, pidl1, pidl2);
return SHELL32_CompareGuidItems(this, lParam, pidl1, pidl2);
return m_DesktopFSFolder->CompareIDs(lParam, pidl1, pidl2);
}

View file

@ -58,8 +58,8 @@ class CDrivesFolderEnum :
*/
static const shvheader MyComputerSFHeader[] = {
{IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15},
{IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
{IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 15},
{IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 10},
{IDS_SHV_COLUMN6, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
{IDS_SHV_COLUMN7, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
};
@ -298,12 +298,52 @@ HRESULT WINAPI CDrivesFolder::BindToStorage(PCUIDLIST_RELATIVE pidl, LPBC pbcRes
HRESULT WINAPI CDrivesFolder::CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2)
{
int nReturn;
if (_ILIsSpecialFolder(pidl1) || _ILIsSpecialFolder(pidl2))
return SHELL32_CompareGuidItems(this, lParam, pidl1, pidl2);
TRACE("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n", this, lParam, pidl1, pidl2);
nReturn = SHELL32_CompareIDs (this, lParam, pidl1, pidl2);
TRACE("-- %i\n", nReturn);
return nReturn;
if (!_ILIsDrive(pidl1) || !_ILIsDrive(pidl2) || LOWORD(lParam) >= MYCOMPUTERSHELLVIEWCOLUMNS)
return E_INVALIDARG;
CHAR* pszDrive1 = _ILGetDataPointer(pidl1)->u.drive.szDriveName;
CHAR* pszDrive2 = _ILGetDataPointer(pidl2)->u.drive.szDriveName;
int result;
switch(LOWORD(lParam))
{
case 0: /* name */
{
result = stricmp(pszDrive1, pszDrive2);
return MAKE_COMPARE_HRESULT(result);
}
case 1: /* Type */
{
return SHELL32_CompareDetails(this, lParam, pidl1, pidl2);
}
case 2: /* Size */
case 3: /* Size Available */
{
ULARGE_INTEGER Drive1Available, Drive1Total, Drive2Available, Drive2Total;
if (GetVolumeInformationA(pszDrive1, NULL, 0, NULL, NULL, NULL, NULL, 0))
GetDiskFreeSpaceExA(pszDrive1, &Drive1Available, &Drive1Total, NULL);
else
Drive1Available.QuadPart = Drive1Total.QuadPart = 0;
if (GetVolumeInformationA(pszDrive2, NULL, 0, NULL, NULL, NULL, NULL, 0))
GetDiskFreeSpaceExA(pszDrive2, &Drive2Available, &Drive2Total, NULL);
else
Drive2Available.QuadPart = Drive2Total.QuadPart = 0;
LARGE_INTEGER Diff;
if (lParam == 2) /* Size */
Diff.QuadPart = Drive1Total.QuadPart - Drive2Total.QuadPart;
else /* Size available */
Diff.QuadPart = Drive1Available.QuadPart - Drive2Available.QuadPart;
return MAKE_COMPARE_HRESULT(Diff.QuadPart);
}
}
return E_INVALIDARG;
}
/**************************************************************************

View file

@ -94,11 +94,11 @@ CFSFolder::~CFSFolder()
static const shvheader GenericSFHeader[] = {
{IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15},
{IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 15},
{IDS_SHV_COLUMN2, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
{IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
{IDS_SHV_COLUMN4, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 12},
{IDS_SHV_COLUMN5, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 5}
{IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 10},
{IDS_SHV_COLUMN4, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 12},
{IDS_SHV_COLUMN5, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 10}
};
#define GENERICSHELLVIEWCOLUMNS 5
@ -319,12 +319,46 @@ HRESULT WINAPI CFSFolder::CompareIDs(LPARAM lParam,
PCUIDLIST_RELATIVE pidl1,
PCUIDLIST_RELATIVE pidl2)
{
int nReturn;
LPPIDLDATA pData1 = _ILGetDataPointer(pidl1);
LPPIDLDATA pData2 = _ILGetDataPointer(pidl2);
FileStructW* pDataW1 = _ILGetFileStructW(pidl1);
FileStructW* pDataW2 = _ILGetFileStructW(pidl2);
BOOL bIsFolder1 = _ILIsFolder(pidl1);
BOOL bIsFolder2 = _ILIsFolder(pidl2);
LPWSTR pExtension1, pExtension2;
TRACE("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n", this, lParam, pidl1, pidl2);
nReturn = SHELL32_CompareIDs(this, lParam, pidl1, pidl2);
TRACE("-- %i\n", nReturn);
return nReturn;
if (!pDataW1 || !pDataW2 || LOWORD(lParam) >= GENERICSHELLVIEWCOLUMNS)
return E_INVALIDARG;
/* When sorting between a File and a Folder, the Folder gets sorted first */
if (bIsFolder1 != bIsFolder2)
{
return MAKE_COMPARE_HRESULT(bIsFolder1 ? -1 : 1);
}
int result;
switch (LOWORD(lParam))
{
case 0: /* Name */
result = wcsicmp(pDataW1->wszName, pDataW2->wszName);
break;
case 2: /* Type */
pExtension1 = PathFindExtensionW(pDataW1->wszName);
pExtension2 = PathFindExtensionW(pDataW2->wszName);
result = wcsicmp(pExtension1, pExtension2);
break;
case 1: /* Size */
result = pData1->u.file.dwFileSize - pData2->u.file.dwFileSize;
break;
case 3: /* Modified */
result = pData1->u.file.uFileDate - pData2->u.file.uFileDate;
if (result == 0)
result = pData1->u.file.uFileTime - pData2->u.file.uFileTime;
break;
case 4: /* Attributes */
return SHELL32_CompareDetails(this, lParam, pidl1, pidl2);
}
return MAKE_COMPARE_HRESULT(result);
}
/**************************************************************************

View file

@ -57,12 +57,12 @@ class CPrintersExtractIconW :
};
static shvheader PrinterSFHeader[] = {
{IDS_SHV_COLUMN8, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15},
{IDS_SHV_COLUMN_DOCUMENTS , SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15},
{IDS_SHV_COLUMN_STATUS, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15},
{IDS_SHV_COLUMN_COMMENTS, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15},
{IDS_SHV_COLUMN_LOCATION, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15},
{IDS_SHV_COLUMN_MODEL, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15}
{IDS_SHV_COLUMN8, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 15},
{IDS_SHV_COLUMN_DOCUMENTS , SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 15},
{IDS_SHV_COLUMN_STATUS, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 15},
{IDS_SHV_COLUMN_COMMENTS, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 15},
{IDS_SHV_COLUMN_LOCATION, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 15},
{IDS_SHV_COLUMN_MODEL, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 15}
};
#define COLUMN_NAME 0
@ -390,12 +390,7 @@ HRESULT WINAPI CPrinterFolder::BindToStorage(PCUIDLIST_RELATIVE pidl, LPBC pbcRe
*/
HRESULT WINAPI CPrinterFolder::CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2)
{
int nReturn;
TRACE ("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n", this, lParam, pidl1, pidl2);
nReturn = SHELL32_CompareIDs (this, lParam, pidl1, pidl2);
TRACE ("-- %i\n", nReturn);
return nReturn;
return SHELL32_CompareDetails(this, lParam, pidl1, pidl2);
}
/**************************************************************************

View file

@ -492,11 +492,41 @@ HRESULT WINAPI CRecycleBin::BindToStorage(PCUIDLIST_RELATIVE pidl, LPBC pbc, REF
HRESULT WINAPI CRecycleBin::CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2)
{
/* TODO */
TRACE("(%p, %p, %p, %p)\n", this, (void *)lParam, pidl1, pidl2);
if (pidl1->mkid.cb != pidl2->mkid.cb)
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, pidl1->mkid.cb - pidl2->mkid.cb);
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, (unsigned short)memcmp(pidl1->mkid.abID, pidl2->mkid.abID, pidl1->mkid.cb));
PIDLRecycleStruct* pData1 = _ILGetRecycleStruct(pidl1);
PIDLRecycleStruct* pData2 = _ILGetRecycleStruct(pidl2);
LPWSTR pName1, pName2;
if(!pData1 || !pData2 || LOWORD(lParam) >= COLUMNS_COUNT)
return E_INVALIDARG;
SHORT result;
LONGLONG diff;
switch (LOWORD(lParam))
{
case 0: /* Name */
pName1 = PathFindFileNameW(pData1->szName);
pName2 = PathFindFileNameW(pData2->szName);
result = wcsicmp(pName1, pName2);
break;
case 1: /* Orig. Location */
result = wcsicmp(pData1->szName, pData2->szName);
break;
case 2: /* Date Deleted */
result = CompareFileTime(&pData1->DeletionTime, &pData2->DeletionTime);
break;
case 3: /* Size */
diff = pData1->FileSize.QuadPart - pData2->FileSize.QuadPart;
return MAKE_COMPARE_HRESULT(diff);
case 4: /* Type */
pName1 = PathFindExtensionW(pData1->szName);
pName2 = PathFindExtensionW(pData2->szName);
result = wcsicmp(pName1, pName2);
break;
case 5: /* Modified */
result = CompareFileTime(&pData1->LastModification, &pData2->LastModification);
break;
}
return MAKE_COMPARE_HRESULT(result);
}
HRESULT WINAPI CRecycleBin::CreateViewObject(HWND hwndOwner, REFIID riid, void **ppv)

View file

@ -47,7 +47,6 @@ HRESULT SHELL32_GetDisplayNameOfChild (IShellFolder2 * psf, LPCITEMIDLIST pidl,
HRESULT SHELL32_BindToFS (LPCITEMIDLIST pidlRoot,
LPCWSTR pathRoot, LPCITEMIDLIST pidlComplete, REFIID riid, LPVOID * ppvOut);
HRESULT SHELL32_CompareIDs (IShellFolder * iface, LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2);
LPITEMIDLIST SHELL32_CreatePidlFromBindCtx(IBindCtx *pbc, LPCWSTR path);
HRESULT SHELL32_BindToGuidItem(LPCITEMIDLIST pidlRoot,
@ -74,6 +73,10 @@ HRESULT SH_ParseGuidDisplayName(IShellFolder2 * pFolder,
PIDLIST_RELATIVE *ppidl,
DWORD *pdwAttributes);
HRESULT SHELL32_CompareDetails(IShellFolder2* isf, LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2);
HRESULT SHELL32_CompareGuidItems(IShellFolder2* isf, LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2);
extern "C"
BOOL HCR_RegOpenClassIDKey(REFIID riid, HKEY *hkey);

View file

@ -609,77 +609,43 @@ HRESULT SHELL32_GetFSItemAttributes(IShellFolder * psf, LPCITEMIDLIST pidl, LPDW
return S_OK;
}
/***********************************************************************
* SHELL32_CompareIDs
*/
HRESULT SHELL32_CompareIDs(IShellFolder * iface, LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
HRESULT SHELL32_CompareDetails(IShellFolder2* isf, LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
{
int type1,
type2;
char szTemp1[MAX_PATH];
char szTemp2[MAX_PATH];
HRESULT nReturn;
LPITEMIDLIST firstpidl;
LPITEMIDLIST nextpidl1;
LPITEMIDLIST nextpidl2;
CComPtr<IShellFolder> psf;
SHELLDETAILS sd;
WCHAR wszItem1[MAX_PATH], wszItem2[MAX_PATH];
/* test for empty pidls */
BOOL isEmpty1 = _ILIsDesktop(pidl1);
BOOL isEmpty2 = _ILIsDesktop(pidl2);
isf->GetDetailsOf(pidl1, lParam, &sd);
StrRetToBufW(&sd.str, pidl1, wszItem1, MAX_PATH);
isf->GetDetailsOf(pidl2, lParam, &sd);
StrRetToBufW(&sd.str, pidl2, wszItem2, MAX_PATH);
int ret = wcsicmp(wszItem1, wszItem2);
if (isEmpty1 && isEmpty2)
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, 0);
if (isEmpty1)
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, (WORD) -1);
if (isEmpty2)
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, 1);
return MAKE_COMPARE_HRESULT(ret);
}
/* test for different types. Sort order is the PT_* constant */
type1 = _ILGetDataPointer(pidl1)->type;
type2 = _ILGetDataPointer(pidl2)->type;
if (type1 < type2)
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, (WORD) -1);
else if (type1 > type2)
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, 1);
/* test for name of pidl */
_ILSimpleGetText(pidl1, szTemp1, MAX_PATH);
_ILSimpleGetText(pidl2, szTemp2, MAX_PATH);
nReturn = lstrcmpiA(szTemp1, szTemp2);
if (nReturn < 0)
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, (WORD) -1);
else if (nReturn > 0)
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, 1);
/* test of complex pidls */
firstpidl = ILCloneFirst(pidl1);
nextpidl1 = ILGetNext(pidl1);
nextpidl2 = ILGetNext(pidl2);
/* optimizing: test special cases and bind not deeper */
/* the deeper shellfolder would do the same */
isEmpty1 = _ILIsDesktop(nextpidl1);
isEmpty2 = _ILIsDesktop(nextpidl2);
if (isEmpty1 && isEmpty2)
HRESULT SHELL32_CompareGuidItems(IShellFolder2* isf, LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
{
if (pidl1->mkid.cb == 0 || pidl2->mkid.cb == 0)
{
nReturn = MAKE_HRESULT( SEVERITY_SUCCESS, 0, 0 );
ERR("Got an empty pidl!\n");
return E_INVALIDARG;
}
else if (isEmpty1)
BOOL bIsGuidFolder1 = _ILIsSpecialFolder(pidl1);
BOOL bIsGuidFolder2 = _ILIsSpecialFolder(pidl2);
if (!bIsGuidFolder1 && !bIsGuidFolder2)
{
nReturn = MAKE_HRESULT( SEVERITY_SUCCESS, 0, (WORD)-1 );
ERR("Got no guid pidl!\n");
return E_INVALIDARG;
}
else if (isEmpty2)
else if (bIsGuidFolder1 && bIsGuidFolder2)
{
nReturn = MAKE_HRESULT( SEVERITY_SUCCESS, 0, 1 );
/* optimizing end */
return SHELL32_CompareDetails(isf, lParam, pidl1, pidl2);
}
else if (SUCCEEDED(iface->BindToObject(firstpidl, NULL, IID_PPV_ARG(IShellFolder, &psf)))) {
nReturn = psf->CompareIDs(lParam, nextpidl1, nextpidl2);
}
ILFree(firstpidl);
return nReturn;
/* Guid folders come first compared to everything else */
return MAKE_COMPARE_HRESULT(bIsGuidFolder1 ? -1 : 1);
}
HRESULT SH_ParseGuidDisplayName(IShellFolder2 * pFolder,

View file

@ -514,4 +514,9 @@ HRESULT inline SHSetStrRet(LPSTRRET pStrRet, HINSTANCE hInstance, DWORD resId)
#endif /* __cplusplus */
#define S_LESSTHAN 0xffff
#define S_EQUAL S_OK
#define S_GREATERTHAN S_FALSE
#define MAKE_COMPARE_HRESULT(x) ((x)>0 ? S_GREATERTHAN : ((x)<0 ? S_LESSTHAN : S_EQUAL))
#endif /* __ROS_SHELL_UTILS_H */