[SHELL32]
authorGiannis Adamopoulos <gadamopoulos@reactos.org>
Mon, 26 Oct 2015 15:07:44 +0000 (15:07 +0000)
committerGiannis Adamopoulos <gadamopoulos@reactos.org>
Mon, 26 Oct 2015 15:07:44 +0000 (15:07 +0000)
- 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

reactos/dll/win32/shell32/CDefView.cpp
reactos/dll/win32/shell32/folders/CControlPanelFolder.cpp
reactos/dll/win32/shell32/folders/CDesktopFolder.cpp
reactos/dll/win32/shell32/folders/CDrivesFolder.cpp
reactos/dll/win32/shell32/folders/CFSFolder.cpp
reactos/dll/win32/shell32/folders/CPrinterFolder.cpp
reactos/dll/win32/shell32/folders/CRecycleBin.cpp
reactos/dll/win32/shell32/shfldr.h
reactos/dll/win32/shell32/shlfolder.cpp
reactos/include/reactos/shellutils.h

index 558c8e1..a553cdd 100644 (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);
-
-
-    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 */
+    CDefView *pThis = reinterpret_cast<CDefView*>(lpData);
 
-        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);
-    }
+    HRESULT hres = pThis->m_pSFParent->CompareIDs(pThis->m_sortInfo.nHeaderID, pidl1, pidl2);
+    if (FAILED_UNEXPECTEDLY(hres))
+        return 0;
 
-    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:
index 59a4561..35db9c2 100644 (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);
+
+    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;
+    }
 
-    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 MAKE_COMPARE_HRESULT(result);
 }
 
 /**************************************************************************
index 65aad59..b9127d4 100644 (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);
 }
index 40fe209..a3b30a3 100644 (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;
 }
 
 /**************************************************************************
index 3b2157d..d32a42e 100644 (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;
+
+    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);
+    }
 
-    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;
+    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);
 }
 
 /**************************************************************************
index 49ab623..7176383 100644 (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);
 }
 
 /**************************************************************************
index 374cd1a..67cd4de 100644 (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)
index 8169c74..b496b08 100644 (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);
 
index f8380ea..7cc24cb 100644 (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)
+{
+    SHELLDETAILS sd;
+    WCHAR wszItem1[MAX_PATH], wszItem2[MAX_PATH];
+
+    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);
+
+    return MAKE_COMPARE_HRESULT(ret);
+}
+
+HRESULT SHELL32_CompareGuidItems(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;
-
-    /* test for empty pidls */
-    BOOL isEmpty1 = _ILIsDesktop(pidl1);
-    BOOL isEmpty2 = _ILIsDesktop(pidl2);
-
-    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);
-
-    /* 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) 
+    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 */
-    }
-    else if (SUCCEEDED(iface->BindToObject(firstpidl, NULL, IID_PPV_ARG(IShellFolder, &psf)))) {
-        nReturn = psf->CompareIDs(lParam, nextpidl1, nextpidl2);
+        return SHELL32_CompareDetails(isf, lParam, pidl1, pidl2);
     }
-    ILFree(firstpidl);
-    return nReturn;
+
+    /* Guid folders come first compared to everything else */
+    return MAKE_COMPARE_HRESULT(bIsGuidFolder1 ? -1 : 1);
 }
 
 HRESULT SH_ParseGuidDisplayName(IShellFolder2 * pFolder,
index 56b8ff8..d89094f 100644 (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 */