Передача объектов оболочки с помощью перетаскивания и буфера обмена

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

Хотя файлы являются наиболее часто передаваемыми объектами оболочки, передача данных оболочки может включать любой из различных объектов в пространстве имен оболочки. Например, приложению может потребоваться перенести файл в виртуальную папку, например корзину, или принять объект из расширения пространства имен, отличного от Майкрософт. Если вы реализуете расширение пространства имен, оно должно правильно работать в качестве источника и целевого объекта удаления.

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

Принцип работы перетаскивания с объектами оболочки

Приложениям часто требуется предоставить пользователям способ передачи данных оболочки. Ниже приведены некоторые примеры.

  • Перетаскивание файла из windows Обозреватель или рабочего стола и его перетаскивание в приложение.
  • Копирование файла в буфер обмена в Windows Обозреватель и его вставка в приложение.
  • Перетаскивание файла из приложения в корзину.

Подробное описание обработки этих и других сценариев см. в разделе Обработка сценариев передачи данных оболочки. В этом документе рассматриваются общие принципы передачи данных оболочки.

Windows предоставляет два стандартных способа передачи данных оболочки для приложений:

  • Пользователь вырезает или копирует данные оболочки, например один или несколько файлов, в буфер обмена. Другое приложение извлекает данные из буфера обмена.
  • Пользователь перетаскивает значок, представляющий данные из исходного приложения, и перетаскивает его в окно, принадлежащее целевому объекту.

В обоих случаях передаваемые данные содержатся в объекте данных. Объекты данных — это com-объекты, которые предоставляют интерфейс IDataObject . Схематически существует три основных шага, которые должны выполнять все операции передачи данных оболочки.

  1. Источник создает объект данных, представляющий передаваемые данные.
  2. Целевой объект получает указатель на интерфейс IDataObject объекта данных.
  3. Целевой объект вызывает интерфейс IDataObject для извлечения данных из него.

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

Передача данных буфера обмена

Буфер обмена — это самый простой способ передачи данных оболочки. Базовая процедура аналогична стандартной передаче данных буфера обмена. Однако, так как вы передаете указатель на объект данных, а не сами данные, необходимо использовать API буфера обмена OLE вместо стандартного API буфера обмена. В следующей процедуре показано, как использовать API буфера обмена OLE для передачи данных оболочки с помощью буфера обмена.

  1. Источник данных создает объект данных для хранения данных.
  2. Источник данных вызывает OleSetClipboard, который помещает указатель на интерфейс IDataObject объекта данных в буфер обмена.
  3. Целевой объект вызывает OleGetClipboard для получения указателя на интерфейс IDataObject объекта данных.
  4. Целевой объект извлекает данные, вызывая метод IDataObject::GetData .
  5. При передаче некоторых данных оболочки целевому объекту также может потребоваться вызвать метод IDataObject::SetData объекта данных, чтобы обеспечить обратную связь с объектом данных о результатах передачи данных. Пример операции этого типа см. в разделе Обработка оптимизированных операций перемещения .

Перенос данных с перетаскиванием

Несмотря на несколько более сложную реализацию, перенос данных с перетаскиванием имеет некоторые существенные преимущества по сравнению с буфером обмена:

  • Перетаскивание можно выполнять с помощью простого перемещения мыши, что делает операцию более гибкой и интуитивно понятной, чем буфер обмена.
  • Функция перетаскивания предоставляет пользователю визуальное представление операции. Пользователь может следовать значку при перемещении от источника к целевому объекту.
  • Перетаскивание уведомляет целевой объект о доступности данных.

Операции перетаскивания также используют объекты данных для передачи данных. Однако источник удаления должен предоставлять функциональные возможности, превышающие необходимые для передачи буфера обмена:

  • Источник удаления также должен создать объект, предоставляющий интерфейс IDropSource . Система использует IDropSource для связи с источником во время выполнения операции.
  • Объект данных перетаскивания отвечает за отслеживание перемещения курсора и отображение значка для представления объекта данных.

Целевые объекты удаления также должны предоставлять больше функциональных возможностей, чем требуется для обработки передачи буфера обмена:

  • Целевой объект удаления должен предоставлять интерфейс IDropTarget . Когда курсор находится над целевым окном, система использует IDropTarget для предоставления целевому объекту таких сведений, как положение курсора, и для уведомления о том, что данные удаляются.
  • Целевой объект удаления должен зарегистрировать себя в системе, вызвав RegisterDragDrop. Эта функция предоставляет системе дескриптор целевого окна и указатель на интерфейс IDropTarget целевого приложения.

Примечание

Для операций перетаскивания приложение должно инициализировать COM с помощью OleInitialize, а не CoInitialize.

 

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

  1. Целевой объект вызывает RegisterDragDrop , чтобы предоставить системе указатель на интерфейс IDropTarget и зарегистрировать окно в качестве целевого объекта удаления.
  2. Когда пользователь запускает операцию перетаскивания, источник создает объект данных и инициирует цикл перетаскивания путем вызова DoDragDrop.
  3. Когда курсор находится на целевом окне, система уведомляет целевой объект, вызывая один из методов IDropTarget целевого объекта. Система вызывает IDropTarget::D ragEnter , когда курсор входит в целевое окно, и IDropTarget::D ragOver , когда курсор проходит через целевое окно. Оба метода предоставляют целевому объекту перетаскивания текущее положение курсора и состояние клавиш-модификаторов клавиатуры, таких как CTRL или ALT. Когда курсор покидает целевое окно, система уведомляет целевой объект, вызывая метод IDropTarget::D ragLeave. При возврате любого из этих методов система вызывает интерфейс IDropSource для передачи возвращаемого значения источнику.
  4. Когда пользователь отпускает кнопку мыши для удаления данных, система вызывает метод IDropTarget::D rop целевого объекта. Среди параметров метода — указатель на интерфейс IDataObject объекта данных.
  5. Целевой объект вызывает метод IDataObject::GetData объекта данных для извлечения данных.
  6. При некоторых передачах данных оболочки целевому объекту также может потребоваться вызвать метод IDataObject::SetData объекта данных, чтобы предоставить источнику обратную связь о результатах передачи данных.
  7. Когда целевой объект завершает работу с объектом данных, он возвращается из IDropTarget::D rop. Система возвращает вызов DoDragDrop источника, чтобы уведомить источник о завершении передачи данных.
  8. В зависимости от конкретного сценария передачи данных источнику может потребоваться выполнить дополнительные действия на основе значения, возвращаемого DoDragDrop , и значений, передаваемых целевому объекту данных. Например, при перемещении файла источник должен проверка эти значения, чтобы определить, нужно ли удалить исходный файл.
  9. Источник освобождает объект данных.

Хотя описанные выше процедуры предоставляют хорошую общую модель для передачи данных оболочки, существует множество различных типов данных, которые могут содержаться в объекте данных оболочки. Существует также ряд различных сценариев передачи данных, которые может потребоваться обрабатывать приложению. Для каждого типа данных и сценария требуется несколько другой подход к трем ключевым шагам в процедуре:

  • Как источник создает объект данных для размещения данных оболочки.
  • Как целевой объект извлекает данные оболочки из объекта данных.
  • Как источник завершает операцию передачи данных.

Объект данных оболочки содержит общее описание того, как источник создает объект данных оболочки и как объект данных может обрабатываться целевым объектом. В разделе Обработка сценариев передачи данных оболочки подробно рассматривается обработка ряда распространенных сценариев передачи данных оболочки.