17.8. ИНТЕРФЕЙС DRAG&DROP
Операционная система Windows широко использует специальный прием связывания программ с данными, который называется Drag&Drop (перетащи и отпусти). Такой прием в Проводнике windows используется для копирования или перемещения файлов, а также для запуска обрабатывающей программы. Если, например, файл с расширением doc “перетащить” на пиктограмму WinWord, автоматически запустится текстовый редактор word for windows и в его окне появится текст из этого файла.
В Delphi реализован собственный интерфейс Drag&Drop, позволяющий компонентам обмениваться данными путем “перетаскивания” их мышью. Этот интерфейс определяется двумя свойствами и тремя событиями, доступными каждому видимому компоненту.[ В Delphi б события могут дублировать сложные свойства и наоборот. Сложными в данном случае называются свойства, ссылающиеся на внутренние объекты. ]
Свойство
TDragMode = (dmManual, dmAutomatic);
property DragMode: TDragMode;
определяет, как будет выполняться весь комплекс действий, связанных С Drag&Drop: dmManual - Вручную (программой); dmAutomatic -автоматически (свойствами и методами компонентов). Значение dmManual означает, что все необходимые для обслуживания интерфейса события генерируются программой, dmAutomatic - события инициируются свойствами и методами компонентов. Во всех случаях программист должен написать обработчики этих событий (см. ниже).
Свойство property DragCursor: TCursor;
определяет вид указателя мыши в момент, когда над компонентом “протаскиваются данные”. Если компонент готов принять данные, он устанавливает в это свойство значение crDrag l3, в противном случае - crNoDrag 0. Установка этих свойств осуществляется автоматически, если DragMode = dmAutomatic. Событие TDragState = (dsDragEnter, dsDragLeave, dsDragMove) ;
TDragOverEvent = procedure(Sender, Source: TObject;
X, Y: Integer; State: TDragState; var Accept: Boolean)
of object; property OnDragOver: TDragOverEvent;
возникает в момент перемещения указателя мыши “с грузом” над компонентом. Здесь sender - компонент, который возбудил событие (обычно это Self - сам компонент-получатель; при ручном управлении механизмом Drag&Drop это может быть не так); source - компонент-отправитель “груза”; х, y - текущие координаты указателя мыши в пикселях клиентской области компонента; State - состояние указателя (dsDragEnter - только что появился на компонентом; dsDragLeave -только что покинул компонент или бьша отпущена кнопка мыши;
dsDragMove - перемещается над компонентом). В параметре Accept обработчик сообщает, готов ли компонент принять данные (т rue - готов).
Событие
TDragDropEvent = procedure(Sender, Source: TObject;
X, Y: Integer) of object;
property OnDragDrop: TDragDropEvent;
означает, что пользователь “бросил” данные на компонент. Параметры обработчика совпадают по назначению с одноименными параметрами OnDragOver.
Наконец, при завершении перетаскивания (вне зависимости от того, приняты данные или нет) возникает событие TEndDragEveht = procedure(Sender, Target: TObject;X, Y: Integer) of objects; property OnEndDrag: TEndDragEvent;
где sender - отправитель данных; Target - получатель данных или nil, если никто не принял “посылку”; X, Y - координаты мыши в момент отпускания левой кнопки.
Чтобы проиллюстрировать использование механизма Drag&Drop, загрузите описанную в гл. 5 учебную программу, установите во всех ее компонентах в свойство DragMode значение dmAutomatic и создайте такой обработчик события OnDragOver для метки:
procedure TfmExample.IbOutputDragOver(Sender, Source: TObject;
X, Y: Integer; State: TDragState;
var Accept: Boolean);
begin
Accept := True;
lbOutput.Caption := (Source as TComponent).Name
end;
Теперь перетаскивание любого компонента на метку IbOutput заставит ее показать имя перетаскиваемого компонента (рис. 17.5).
Рис. 17.5. Метка IbOutput показывает имя перетаскиваемого компонента
Для ручного (программного) управления механизмом Drag&Drop используются следующие методы, доступные любому потомку TControl:
procedure BeginDrag (Immediate: Boolean); |
Используется источником для инициализации процесса Drag&Drop. Если Immediate =True, процесс начинается немедленно, в противном случае - после смещения указателя мыши на 5 пикселей в любом направлении |
procedure DragDrop (Source: TObject; X, Y: Integer); |
Вызывает обработчик события OnDragDrop |
procedure EndDrag(Drop: Boolean); |
Вызывает обработчик события OnEndDrag и в параметре Drop сообщает о том, были ли приняты данные |