Приветствую, разработчики Delphi! В этой статье мы поговорим о том, как можно реализовать перетаскивание файлов из вашего приложения в другие программы, которые поддерживают эту функциональность. Основываясь на вопросе пользователя, мы разберемся с проблемой, связанной с неправильной реализацией интерфейса IDataObject, и приведем пример кода, который поможет в решении этой задачи.
Оригинальная проблема
Пользователь столкнулся с проблемой, когда, реализовав интерфейс IDropSource для своего компонента, обнаружил, что перетаскивание файлов работает только в Проводнике Windows, но не в других приложениях, таких как Firefox, Yahoo Messenger, Photoshop и т.д. Он предполагает, что проблема может быть связана с неправильной настройкой IDataObject.
Описание компонента
Компонент, реализованный пользователем, представляет собой список файлов, из которого можно перетаскивать файлы в другие приложения, работающие с файлами. Пользователь привел примерный код, который можно воспроизвести для демонстрации проблемы.
Прежде чем приступить к решению
Перед тем как перейти к решению, стоит отметить, что важно убедиться, что все файлы находятся в одной директории, чтобы избежать дополнительных сложностей с перетаскиванием файлов из разных папок.
Решение проблемы
Проблема заключается в том, что функция GetUIObjectOf вызывает с некоторыми некорректными данными. При вызове GetUIObjectOf элементы должны быть дочерними элементами каталога, но в коде пользователя это не так. В качестве альтернативы, пользователю предлагается использовать следующий подход:
Получение интерфейса IShellFolder для рабочего стола.
Парсинг пути к папке, содержащей файлы.
Получение IShellFolder для этой папки.
Парсинг каждого файла в рамках этой папки.
Получение IDataObject для списка файлов в рамках этой папки.
type
PPItemIDList = ^PItemIDList;
function GetFileListDataObject(AParentWnd: HWND; const APath: string; AFileNames: TStrings): IDataObject;
var
Desktop: IShellFolder;
Eaten, Attr: ULONG;
i: Integer;
PathIDList: PItemIDList;
PathShellFolder: IShellFolder;
IDLists: PPItemIDList;
IDListsSize: Integer;
Pos: PPItemIDList;
begin
Result := nil;
if AFileNames.Count < 1 then Exit;
if Failed(SHGetDesktopFolder(Desktop)) then Exit;
try
Attr := 0;
if Failed(Desktop.ParseDisplayName(AParentWnd, nil, PWideChar(APath), Eaten, PathIDList, Attr)) then Exit;
try
if Failed(Desktop.BindToStorage(PathIDList, nil, IShellFolder, PathShellFolder)) then Exit;
try
IDListsSize := SizeOf(PItemIDList) * AFileNames.Count;
GetMem(IDLists, IDListsSize);
try
ZeroMemory(IDLists, IDListsSize);
Pos := IDLists;
for i := 0 to AFileNames.Count - 1 do
begin
Attr := 0;
if Failed(PathShellFolder.ParseDisplayName(0, nil, PWideChar(AFileNames[i]), Eaten, Pos^, Attr)) then Exit;
Inc(Pos);
end;
PathShellFolder.GetUIObjectOf(0, AFileNames.Count, IDLists^, IDataObject, nil, Result);
finally
Pos := IDLists;
for i := 0 to AFileNames.Count - 1 do
begin
if Assigned(Pos^) then
CoTaskMemFree(Pos^);
Inc(Pos);
end;
FreeMem(IDLists);
end;
finally
PathShellFolder := nil;
end;
finally
CoTaskMemFree(PathIDList);
end;
finally
Desktop := nil;
end;
end;
Заключение и рекомендации
Применение вышеуказанных изменений позволит корректно настроить IDataObject и решить проблему с перетаскиванием файлов в другие приложения. Не забывайте также о том, что важно провести отладку вашего приложения, чтобы убедиться в корректности работы всех компонентов.
Если вы сталкиваетесь с трудностями в понимании более сложных решений, таких как Drag'n'Drop Suite от Anders Melander, не бойтесь изучать и анализировать рабочие примеры, что может значительно ускорить ваш процесс обучения и разработки. Удачи в реализации перетаскивания файлов в вашем приложении на Delphi!
Статья помогает разработчикам Delphi решить проблему перетаскивания файлов, связанную с некорректной настройкой интерфейса `IDataObject`.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.