Author: gadamopoulos Date: Mon Mar 16 16:30:24 2015 New Revision: 66737 URL: http://svn.reactos.org/svn/reactos?rev=66737&view=rev Log: [RSHELL] - Implement sorting shell menu items - Patch by David Quintana
Modified: trunk/reactos/base/shell/rshell/CMenuToolbars.cpp Modified: trunk/reactos/base/shell/rshell/CMenuToolbars.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/rshell/CMenuToolbars.cpp?rev=66737&r1=66736&r2=66737&view=diff ============================================================================== --- trunk/reactos/base/shell/rshell/CMenuToolbars.cpp [iso-8859-1] (original) +++ trunk/reactos/base/shell/rshell/CMenuToolbars.cpp [iso-8859-1] Mon Mar 16 16:30:24 2015 @@ -1273,62 +1273,88 @@ { } +int CALLBACK PidlListSort(void* item1, void* item2, LPARAM lParam) +{ + IShellFolder * psf = (IShellFolder*) lParam; + PCUIDLIST_RELATIVE pidl1 = (PCUIDLIST_RELATIVE) item1; + PCUIDLIST_RELATIVE pidl2 = (PCUIDLIST_RELATIVE) item2; + HRESULT hr = psf->CompareIDs(0, pidl1, pidl2); + if (FAILED(hr)) + { + // No way to cancel, so sort to equal. + return 0; + } + return (int)(short)LOWORD(hr); +} + HRESULT CMenuSFToolbar::FillToolbar(BOOL clearFirst) { HRESULT hr; - int i = 0; - PWSTR MenuString; - - IEnumIDList * eidl; - m_shellFolder->EnumObjects(GetToolbar(), SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &eidl); + + CComPtr<IEnumIDList> eidl; + hr = m_shellFolder->EnumObjects(GetToolbar(), SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &eidl); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + + HDPA dpaSort = DPA_Create(10); LPITEMIDLIST item = NULL; hr = eidl->Next(1, &item, NULL); while (hr == S_OK) { + if (m_menuBand->_CallCBWithItemPidl(item, 0x10000000, 0, 0) == S_FALSE) + { + DPA_AppendPtr(dpaSort, ILClone(item)); + } + + hr = eidl->Next(1, &item, NULL); + } + + // If no items were added, show the "empty" placeholder + if (DPA_GetPtrCount(dpaSort) == 0) + { + return AddPlaceholder(); + } + + TRACE("FillToolbar added %d items to the DPA\n", DPA_GetPtrCount(dpaSort)); + + DPA_Sort(dpaSort, PidlListSort, (LPARAM) m_shellFolder.p); + + for (int i = 0; i<DPA_GetPtrCount(dpaSort);) + { + PWSTR MenuString; + INT index = 0; INT indexOpen = 0; - if (m_menuBand->_CallCBWithItemPidl(item, 0x10000000, 0, 0) == S_FALSE) - { - STRRET sr = { STRRET_CSTR, { 0 } }; - - hr = m_shellFolder->GetDisplayNameOf(item, SIGDN_NORMALDISPLAY, &sr); - if (FAILED_UNEXPECTEDLY(hr)) - return hr; - - StrRetToStr(&sr, NULL, &MenuString); - - index = SHMapPIDLToSystemImageListIndex(m_shellFolder, item, &indexOpen); - - LPCITEMIDLIST itemc = item; - - SFGAOF attrs = SFGAO_FOLDER; - hr = m_shellFolder->GetAttributesOf(1, &itemc, &attrs); - - DWORD_PTR dwData = reinterpret_cast<DWORD_PTR>(ILClone(item)); - - // Fetch next item already, so we know if the current one is the last - hr = eidl->Next(1, &item, NULL); - - AddButton(++i, MenuString, attrs & SFGAO_FOLDER, index, dwData, hr != S_OK); - - CoTaskMemFree(MenuString); - } - else - { - // Fetch next item here also - hr = eidl->Next(1, &item, NULL); - } - } - ILFree(item); - - // If no items were added, show the "empty" placeholder - if (i == 0) - { - return AddPlaceholder(); - } - + STRRET sr = { STRRET_CSTR, { 0 } }; + + item = (LPITEMIDLIST)DPA_GetPtr(dpaSort, i); + + hr = m_shellFolder->GetDisplayNameOf(item, SIGDN_NORMALDISPLAY, &sr); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + + StrRetToStr(&sr, NULL, &MenuString); + + index = SHMapPIDLToSystemImageListIndex(m_shellFolder, item, &indexOpen); + + LPCITEMIDLIST itemc = item; + + SFGAOF attrs = SFGAO_FOLDER; + hr = m_shellFolder->GetAttributesOf(1, &itemc, &attrs); + + DWORD_PTR dwData = reinterpret_cast<DWORD_PTR>(item); + + // Fetch next item already, so we know if the current one is the last + i++; + + AddButton(i, MenuString, attrs & SFGAO_FOLDER, index, dwData, i >= DPA_GetPtrCount(dpaSort)); + + CoTaskMemFree(MenuString); + } + + DPA_Destroy(dpaSort); return hr; }