Я делаю хлебную крошку в Delphi и имею некоторые проблемы с сортировкой раскрывающихся хлебных крошек.Сортировка элементов оболочки, таких как windows explorer
Как ни странно, даже Vista не является следствием при показе этих предметов.
Я пробовал много способов выяснить, что такое системные папки, что такое zip-файлы и что такое обычные папки. Это кажется легкой задачей, но до сих пор я не нашел хорошего способа сделать это.
Один из способов - использовать TypeDisplayName из TSHFileinfo, но это локализованные имена, поэтому я не могу быть уверенным, что они будут в правильном порядке на каждом языке.
Вот код, я использую, чтобы заполнить меню:
bool:= IsDesktop(SelectedPIDL);
if bool then
OleCheck(SHGetDesktopFolder(CurFolder))
else
OleCheck(DesktopShellFolder.BindToObject(SelectedPIDL, nil, IID_IShellFolder, Pointer(CurFolder)));
if CurFolder.EnumObjects(0, SHCONTF_FOLDERS, EnumIDList) = NOERROR then
begin
while EnumIDList.Next(1, CurPidl, Fetched) = S_OK do
begin
FName:= GetDisplayName(CurFolder, CurPidl, SHGDN_NORMAL);
Text:= GetPIDLNameForAddressBar(CurFolder, CurPidl);
if bool then
Text:= PSpecialFolderItem(SpecialFolders[0]).Name + '\' + Text;
if Text[Length(Text)] <> '\' then
Text:= Text + '\';
NewPidl:= ConcatPIDLs(SelectedPIDL, CurPidl);
SHGetFileInfo(PChar(NewPidl), 0, SFI, SizeOf(SFI), SHGFI_ATTRIBUTES or SHGFI_PIDL or
SHGFI_SYSICONINDEX or SHGFI_TYPENAME);
n:= SFI.dwAttributes;
MenuList.Add(GetAttr(n) + FName);
AddMenuItem(Text, FName, SFI.iIcon);
CoTaskMemFree(CurPidl);
CoTaskMemFree(NewPidl);
end;
end;
CoTaskMemFree(SelectedPIDL);
Любое решение, как получить правильный порядок сортировки? Странно, что в dwAttributes TSHFileInfo нет способа определить, является ли папка системной папкой.
Благодаря Keith Гиддингсом мне удалось придумать с этим решением:
PidlList:= TList.Create;
// Add PIDLs for sorting
bool:= IsDesktop(SelectedPIDL);
if bool then
OleCheck(SHGetDesktopFolder(IShellFld))
else
OleCheck(DesktopShellFolder.BindToObject(SelectedPIDL, nil, IID_IShellFolder, Pointer(IShellFld)));
if IShellFld.EnumObjects(0, SHCONTF_FOLDERS, EnumIDList) = NOERROR then
while EnumIDList.Next(1, CurPidl, Fetched) = S_OK do
PidlList.Add(CurPidl);
// Sort it ...
PidlList.Sort(ComparePIDLs);
// Get display name and icon for item
for i:= 0 to PidlList.Count - 1 do
begin
CurPidl:= PidlList[i];
FName:= GetDisplayName(IShellFld, CurPidl, SHGDN_NORMAL);
Text:= GetPIDLNameForAddressBar(IShellFld, CurPidl);
if bool then
Text:= PSpecialFolderItem(SpecialFolders[0]).Name + '\' + Text;
if Text[Length(Text)] <> '\' then
Text:= Text + '\';
NewPidl:= ConcatPIDLs(SelectedPIDL, CurPidl);
SHGetFileInfo(PChar(NewPidl), 0, SFI, SizeOf(SFI), SHGFI_ATTRIBUTES or SHGFI_PIDL or
SHGFI_SYSICONINDEX or SHGFI_TYPENAME);
AddMenuItem(Text, FName, SFI.iIcon);
CoTaskMemFree(NewPidl);
end;
CoTaskMemFree(SelectedPIDL);
for i:= PidlList.Count - 1 downto 0 do
begin
CoTaskMemFree(PidlList[i]);
PidlList.Delete(i);
end;
// We are done free it
PidlList.Free;
function ComparePIDLs(Item1, item2: Pointer): Integer;
begin
Result:= SmallInt(IShellFld.CompareIDs(0, Item1, Item2));
end;
Рой M Клевер
Не могли бы вы объяснить поведение сортировки \ функции, которые вы хотите, возможно, с примером. –
Hi chibacity, Я хочу, чтобы он сортировался, поэтому я получаю тот же результат, что и при нажатии на тот же элемент палитры в Vista Explorer. Но поскольку Vista не является следствием, я хочу иметь системные папки сверху, а затем обычные папки и внизу zip-файлы (папки) ... Я хочу иметь более организованный вид выпадающих меню. Теперь это выглядит немного испорченным. Я вижу, могу ли я добавить изображение к моему вопросу ... –
Я не знаком с этим использованием «последовательного», и словарь не помогает мне это понять. Можете ли вы разъяснить? –