Как скопировать произвольные данные в буфер обмена в виде файла?

Мы разрабатываем приложение базы данных. Пользователь запрашивает новую функцию: скопируйте капли в буфер обмена так, чтобы проводник Windows мог вставлять их в виде новых файлов. Одним из решений является сохранение капли во временную папку и добавление этих временных файлов в буфер обмена.

Но я ищу лучшее решение. Можно ли связать действие вставки в проводнике Windows и сохранить капли по пути назначения самостоятельно?

Ответ 1

Я бы сказал, что explorer выполняет копирование в файлы назначения, поэтому нет возможности напрямую писать файлы назначения. Это имеет смысл, потому что имена исходных файлов могут поступать только из приложения, которое копирует данные в буфер обмена, которые не должны быть проводниками. OTOH имена целевых файлов могут фактически отличаться, поскольку файлы с тем же именем уже могут существовать в целевой папке, и только исследователь может создавать измененные имена для целевых файлов (например, путем добавления "Копии" или путем добавления "( 2)" к имени базового файла).

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

Вы могли бы попытаться сделать процесс как можно более легким. Обычно, когда пользователь копирует данные в буфер обмена, он помещается туда немедленно, независимо от того, будет ли он использоваться для операции вставки. Для вашего приложения это означало бы, что вам нужно будет создавать файлы и каждый раз помещать список имен файлов в буфер обмена. Однако Windows поддерживает режим Delayed Rendering, который используется именно для таких случаев. В основном вы помещаете только пустой заглушку данных в буфер обмена и только тогда, когда другое приложение пытается получить доступ к данным, которые будут запрошены в вашем приложении. Таким образом, вы можете реализовать это так, что только когда пользователь попытается вставить файлы в проводник, вы сохраните их на диск и вернете список имен файлов.

Ответ 2

Я никогда не пробовал, но я думаю, что это действительно возможно. Пожалуйста, взгляните на документацию MSDN для Форматы оболочки буфера обмена. CFSTR_FILECONTENTS и CFSTR_FILEDESCRIPTOR - это форматы, которые вы, вероятно, должны обрабатывать.

Кроме того, я нашел статью в Code Project, которая предоставляет демонстрационную программу: Как перетащить виртуальный файл из вашего приложения в проводник Windows.

Обновление: пример, написанный в .NET:

Ответ 3

Из статьи MSDN Обработка сценариев переноса данных Shell

  • Существующие файлы должны быть представлены в формате CF_HDROP.
  • Предложить файлоподобные данные с CFSTR_FILECONTENTS/CFSTR_FILEDESCRIPTOR форматы. Такой подход позволяет target для создания файла из данных объект без необходимости знать ничего о базовых данных место хранения. Вы должны нормально представлять данные как интерфейс IStream. Эта механизм передачи данных больше гибкий, чем глобальный объект памяти и использует гораздо меньше памяти.

Две другие хорошие статьи для чтения из MSDN:

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

Работа с интерфейсами может быть довольно сложной. Я нашел две хорошие библиотеки, чтобы помочь с этим.

Набор компонентов перетаскивания для Delphi. Если вы прокрутите страницу вниз, вы увидите, что некоторые часто задаваемые вопросы - хорошее чтение. Также есть множество примеров приложений с загрузкой. Я думаю, что демоны AsyncSource должны быть полезны для того, что вы ищете. Люкс является бесплатным с исходным кодом. Код, кажется, хорошо прокомментирован.

В настоящее время я использую компонент Transfer @Once из Quasidata. Это не бесплатно, а очень недорого. Первоначально я использовал Transfer @Once, потому что в то время он был лучше поддержан, чем набор компонентов Drag and Drop. Однако эта ситуация полностью изменилась. Transfer @Once еще не поддерживает Delphi 2009. Когда я перейду к перемещению своего приложения, я, вероятно, переключу компоненты. Код Transfer @Once включен в покупку. Лично я обнаружил, что код перетаскивания намного проще читать и следовать.

Ответ 4

Прошло некоторое время с тех пор, как я играл с копией/вставкой, но я уверен, что вы можете делать то, что вы предлагаете (вставьте blob как новый файл в буфер обмена).

Кажется, я помню, что в зависимости от того, как вы добавляете в буфер обмена, вы можете указать, какие данные вы копируете. Я думаю, что если вы получите этот тип данных правильно, вы сможете вставить, как если бы вы скопировали из обозревателя Windows.

Я попробую и выкажу несколько подробностей этим вечером, если у меня будет шанс (у меня нет всех моих закладок здесь на работе)...

[Изменить] Посмотрите документацию wxWidgets на перетаскивание. Это то, с чем я работал, и дает некоторые подсказки о типах данных.

На что вы пишете? Delphi?

[Edit2] Я думаю, что это может быть ограничение Windows (?). Это может быть только документация wxWidgets, но там предположение, что вы копируете только имена файлов, а не сами файлы. Если это произойдет, вам нужно сначала указать первоначальное предложение о создании временного файла: - (