From: Giannis Adamopoulos Date: Mon, 26 Oct 2015 15:07:44 +0000 (+0000) Subject: [SHELL32] X-Git-Tag: ReactOS-0.4.0~343 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=3328daaf08531e474a4558aaae340d8544da53f7 [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 --- diff --git a/reactos/dll/win32/shell32/CDefView.cpp b/reactos/dll/win32/shell32/CDefView.cpp index 558c8e15754..a553cdde5f9 100644 --- a/reactos/dll/win32/shell32/CDefView.cpp +++ b/reactos/dll/win32/shell32/CDefView.cpp @@ -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(lpData); - PCUIDLIST_RELATIVE pidl1 = reinterpret_cast(lParam1); - PCUIDLIST_RELATIVE pidl2 = reinterpret_cast(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(lParam1); PCUIDLIST_RELATIVE pidl2 = reinterpret_cast(lParam2); - LISTVIEW_SORT_INFO *pSortInfo = reinterpret_cast(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(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(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: diff --git a/reactos/dll/win32/shell32/folders/CControlPanelFolder.cpp b/reactos/dll/win32/shell32/folders/CControlPanelFolder.cpp index 59a4561d9d4..35db9c294e1 100644 --- a/reactos/dll/win32/shell32/folders/CControlPanelFolder.cpp +++ b/reactos/dll/win32/shell32/folders/CControlPanelFolder.cpp @@ -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); } /************************************************************************** diff --git a/reactos/dll/win32/shell32/folders/CDesktopFolder.cpp b/reactos/dll/win32/shell32/folders/CDesktopFolder.cpp index 65aad593478..b9127d4b83f 100644 --- a/reactos/dll/win32/shell32/folders/CDesktopFolder.cpp +++ b/reactos/dll/win32/shell32/folders/CDesktopFolder.cpp @@ -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); } diff --git a/reactos/dll/win32/shell32/folders/CDrivesFolder.cpp b/reactos/dll/win32/shell32/folders/CDrivesFolder.cpp index 40fe2090300..a3b30a39c71 100644 --- a/reactos/dll/win32/shell32/folders/CDrivesFolder.cpp +++ b/reactos/dll/win32/shell32/folders/CDrivesFolder.cpp @@ -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; } /************************************************************************** diff --git a/reactos/dll/win32/shell32/folders/CFSFolder.cpp b/reactos/dll/win32/shell32/folders/CFSFolder.cpp index 3b2157d1ff2..d32a42ecb67 100644 --- a/reactos/dll/win32/shell32/folders/CFSFolder.cpp +++ b/reactos/dll/win32/shell32/folders/CFSFolder.cpp @@ -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); } /************************************************************************** diff --git a/reactos/dll/win32/shell32/folders/CPrinterFolder.cpp b/reactos/dll/win32/shell32/folders/CPrinterFolder.cpp index 49ab6234b4d..717638376d9 100644 --- a/reactos/dll/win32/shell32/folders/CPrinterFolder.cpp +++ b/reactos/dll/win32/shell32/folders/CPrinterFolder.cpp @@ -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); } /************************************************************************** diff --git a/reactos/dll/win32/shell32/folders/CRecycleBin.cpp b/reactos/dll/win32/shell32/folders/CRecycleBin.cpp index 374cd1af236..67cd4dee51a 100644 --- a/reactos/dll/win32/shell32/folders/CRecycleBin.cpp +++ b/reactos/dll/win32/shell32/folders/CRecycleBin.cpp @@ -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) diff --git a/reactos/dll/win32/shell32/shfldr.h b/reactos/dll/win32/shell32/shfldr.h index 8169c749647..b496b08ff91 100644 --- a/reactos/dll/win32/shell32/shfldr.h +++ b/reactos/dll/win32/shell32/shfldr.h @@ -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); diff --git a/reactos/dll/win32/shell32/shlfolder.cpp b/reactos/dll/win32/shell32/shlfolder.cpp index f8380ea7ad2..7cc24cb700b 100644 --- a/reactos/dll/win32/shell32/shlfolder.cpp +++ b/reactos/dll/win32/shell32/shlfolder.cpp @@ -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 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, diff --git a/reactos/include/reactos/shellutils.h b/reactos/include/reactos/shellutils.h index 56b8ff824f2..d89094f18b7 100644 --- a/reactos/include/reactos/shellutils.h +++ b/reactos/include/reactos/shellutils.h @@ -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 */