[SHELL32]
[reactos.git] / reactos / dll / win32 / shell32 / CDefView.cpp
index 1bb5b49..035d73e 100644 (file)
  * built according to the columns shown.
  *
  * FIXME: CheckToolbar: handle the "new folder" and "folder up" button
- *
- * FIXME: ShellView_FillList: consider sort orders
  */
 
 /*
 TODO:
-1. Load/Save the view state from/into the stream provided by the ShellBrowser.
-2. Let the shell folder sort items.
-3. Code to merge menus in the shellbrowser is incorrect.
-4. Move the background context menu creation into shell view. It should store the
-    shell view HWND to send commands.
-5. Send init, measure, and draw messages to context menu during tracking.
-6. Shell view should do SetCommandTarget on internet toolbar.
-7. When editing starts on item, set edit text to for editing value.
-8. When shell view is called back for item info, let listview save the value.
-9. Shell view should update status bar.
-10. Fix shell view to handle view mode popup exec.
-11. The background context menu should have a pidl just like foreground menus. This
-    causes crashes when dynamic handlers try to use the NULL pidl.
-12. The SHELLDLL_DefView should not be filled with blue unconditionally. This causes
-    annoying flashing of blue even on XP, and is not correct.
-13. Reorder of columns doesn't work - might be bug in comctl32
+- Load/Save the view state from/into the stream provided by the ShellBrowser.
+- Code to merge menus in the shellbrowser is incorrect.
+- Move the background context menu creation into shell view. It should store the
+   shell view HWND to send commands.
+- Shell view should do SetCommandTarget on internet toolbar.
+- When editing starts on item, set edit text to for editing value.
+- When shell view is called back for item info, let listview save the value.
+- Fix shell view to handle view mode popup exec.
+- The background context menu should have a pidl just like foreground menus. This
+   causes crashes when dynamic handlers try to use the NULL pidl.
+- The SHELLDLL_DefView should not be filled with blue unconditionally. This causes
+   annoying flashing of blue even on XP, and is not correct.
+- Reorder of columns doesn't work - might be bug in comctl32
 */
 
 #include "precomp.h"
@@ -131,7 +126,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);
@@ -272,7 +266,7 @@ class CDefView :
             {
                 {   sizeof(WNDCLASSEX), 0, StartWindowProc,
                     0, 0, NULL, NULL,
-                    LoadCursor(NULL, IDC_ARROW), (HBRUSH)(COLOR_BACKGROUND + 1), NULL, SV_CLASS_NAME, NULL
+                    LoadCursor(NULL, IDC_ARROW), (HBRUSH)(COLOR_WINDOW + 1), NULL, SV_CLASS_NAME, NULL
                 },
                 NULL, NULL, IDC_ARROW, TRUE, 0, _T("")
             };
@@ -335,13 +329,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 +635,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 +649,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 */
-
-        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 */
+    CDefView *pThis = reinterpret_cast<CDefView*>(lpData);
 
-    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;
 }
 
@@ -855,11 +749,13 @@ BOOLEAN CDefView::LV_RenameItem(PCUITEMID_CHILD pidlOld, PCUITEMID_CHILD pidlNew
     {
         lvItem.mask = LVIF_PARAM;        /* only the pidl */
         lvItem.iItem = nItem;
+        lvItem.iSubItem = 0;
         m_ListView.GetItem(&lvItem);
 
         SHFree(reinterpret_cast<LPVOID>(lvItem.lParam));
         lvItem.mask = LVIF_PARAM|LVIF_IMAGE;
         lvItem.iItem = nItem;
+        lvItem.iSubItem = 0;
         lvItem.lParam = reinterpret_cast<LPARAM>(ILClone(pidlNew));    /* set the item's data */
         lvItem.iImage = SHMapPIDLToSystemImageListIndex(m_pSFParent, pidlNew, 0);
         m_ListView.SetItem(&lvItem);
@@ -886,6 +782,7 @@ BOOLEAN CDefView::LV_ProdItem(PCUITEMID_CHILD pidl)
     {
         lvItem.mask = LVIF_IMAGE;
         lvItem.iItem = nItem;
+        lvItem.iSubItem = 0;
         lvItem.iImage = SHMapPIDLToSystemImageListIndex(m_pSFParent, pidl, 0);
         m_ListView.SetItem(&lvItem);
         m_ListView.Update(nItem);
@@ -972,14 +869,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);
 
@@ -1655,7 +1555,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:
@@ -1785,7 +1685,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:
@@ -1913,6 +1813,7 @@ LRESULT CDefView::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandl
                 {
                     lvItem.mask = LVIF_PARAM|LVIF_IMAGE;
                     lvItem.iItem = lpdi->item.iItem;
+                    lvItem.iSubItem = 0;
                     lvItem.lParam = reinterpret_cast<LPARAM>(pidlNew);
                     lvItem.iImage = SHMapPIDLToSystemImageListIndex(m_pSFParent, pidlNew, 0);
                     m_ListView.SetItem(&lvItem);