Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Определение источника файла: TDropPIDLTarget и виртуальное расположение в Delphi

Delphi , ОС и Железо , Windows

Вопрос пользователя связан с использованием компонента TDropPIDLTarget из набора компонентов для перетаскивания файлов от Angus Johnson & Anders Melander, который позволяет добавлять вложения путем перетаскивания их на форму. Основная проблема заключается в необходимости определения, происходит ли доступ к файлу из виртуального расположения (например, из камеры или iPhone) или из обычной файловой системы.

Проблема и код

Пользователь использует следующий код для определения атрибутов файлов:

procedure TfrmForm.dftFileDropDrop(...);
var
  I: Integer;
  pItem: PItemIDList;
  Desktop: IShellFolder;
  FileName: TStrRet;
  Attr: UINT;
begin
  // ... (инициализация и цикл по элементам PIDL)
  Attr := SFGAO_FileSystem;
  if Succeeded(Desktop.GetAttributesOf(1, pItem, Attr)) then
  begin
    if (Attr or SFGAO_FILESYSTEM) = Attr then
      // ... (получение имени файла)
    else
      // ... (получение имени файла для адресной строки)
  end;
end;

Константа SFGAO_FileSystem предполагает, что указанные папки или файлы являются частью файловой системы. Однако пользователь сталкивается с трудностями при получении корректных результатов из функции GetAttributesOf.

Подход к решению

Для корректного определения принадлежности файла к файловой системе необходимо использовать побитовое И (And), а не побитовое ИЛИ (Or):

if (Attr and SFGAO_FILESYSTEM) <> 0 then
  // Файл принадлежит файловой системе

Также важно проверять результат функции на ошибки перед доступом к данным и освобождать ресурсы, выделенные для STRRET, используя функции StrRetTo...().

Вот исправленный пример кода:

procedure TfrmForm.dftFileDropDrop(...);
var
  I: Integer;
  pItem: PItemIDList;
  Desktop: IShellFolder;
  FileName: TStrRet;
  Attr: UINT;
  hr: HRESULT;
  szFileName: array[0..MAX_PATH] of Char;
begin
  // ... (инициализация и цикл по элементам PIDL)
  if Succeeded(Desktop.GetAttributesOf(1, pItem, Attr)) then
  begin
    if (Attr and SFGAO_FILESYSTEM) <> 0 then
    begin
      hr := Desktop.GetDisplayNameOf(pItem, SHGDN_NORMAL Or SHGDN_FORPARSING, Filename);
    end
    else
    begin
      hr := Desktop.GetDisplayNameOf(pItem, SHGDN_NORMAL Or SHGDN_FORADDRESSBAR, Filename);
    end;
    if Succeeded(hr) then
    begin
      if Succeeded(StrRetToBuf(@Filename, pItem, szFileName, MAX_PATH)) then
        mResults.Lines.Add(szFileName);
    end;
  end;
end;

Альтернативное решение

Пользователь также обнаружил, что можно использовать флаги SHGDN_NORMAL, SHGDN_FORPARSING и SHGDN_FORADDRESSBAR вместе для получения правильного имени файла независимо от его расположения. Важно не забывать освобождать ресурсы STRRET.

Вывод

Для корректной работы с виртуальными расположениями и файловой системой в Delphi, необходимо правильно использовать побитовые операции и обрабатывать результаты функций, а также освобождать выделенные ресурсы. Использование комбинации флагов SHGDN_... может упростить процесс получения имен файлов.

Создано по материалам из источника по ссылке.

Вопрос пользователя касается правильного определения источника файла, перетащенного на компонент TDropPIDLTarget в Delphi, и различий в обработке файлов из виртуального расположения и обычной файловой системы.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Windows ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-06-16 02:21:53/0.0051131248474121/1