Скачиваний:
37
Добавлен:
28.06.2014
Размер:
118.78 Кб
Скачать

Технология Drag-and-Drop Реализации Drag&DropвVcl

Drag&Drop («перетащи и положи») – это один из способов обмена данными между приложениями. Этим способом обмена пользуются многие программные приложения. Например, очень часто так перемещаются файлы и папки.

В библиотеке визуальных компонент - VCL реализована собственная версия Drag&Drop – технологии, которая обеспечивает прием и передачу любых управляющих элементов внутри одной и той же формы. При таком внутреннем использовании VCL не обращается к операционной системе, хотя для организации общения различных приложений нужно было бы использовать соответствующие функции API Windows.

Пользователь, нажав на левую кнопку мыши, может перетащить управляющий элемент (объект – источник) на другой элемент (объект-приемник). В моменты перетаскивания и отпускания генерируются события, которые должна обрабатывать программа (получателем событий является элемент, над которым находится курсор мыши). Свойство компонентов DragModeотвечает за их участие в процессе обмена данными.

DragMode = dmAutomatic - события срабатывают автоматически, программист пишет только коды, соответствующих обработчиков событий.

DragMode = dmManual -все вызовы программист должен организовать сам.

События, возникающие при перетаскивании

Событие OnDragOverвозникает во время перемещения курсора мыши над объектом-приемником, а также при отпускании кнопки на этом объекте.

Параметры события:

  • Sender- объект-приемник (над ним находится курсор);

  • Source - объект-источник;

  • X,Y- координаты мыши в системе клиентской области объекта Sender;

  • State- состояние (имеет одно из трех значенийdsDragEnter– курсор мыши появился над элементом;dsDragMoveкурсор перемещается над элементом;dsDragLeave– курсор ушел с элемента или над элементом была отпущена кнопка).

  • Accept– логическая переменная. В этой переменной обработчик должен вернуть свое решение принимать или не принимать объектSource.

Например, компонент класса Label(Name=Label1)должен принимать только компоненты классаShape(геометрические фигуры), тогда его обработчик будет содержать проверку переносимого объекта-источника(Source):

void __fastcall TForm1::Label1DragOver(TObject *Sender, TObject *Source,

int X, int Y, TDragState State, bool &Accept)

{

Accept=Source->ClassNameIs("TShape");

}

Событие OnDragDropвозникает при отпускании левой кнопки мыши над элементом, готовым к приему. Его параметрыSender,Source,XиYимеют тот же смысл, что и у предыдущего события. Содержимое этого обработчика зависит от того, какие функции программист разрешает выполнять пользователю путем перетаскивания. Это может быть изменение местоположения объектов, обмен информацией и т.д.

В следующем примере не происходит физического перемещения объектов; компонент Label1 получает указатель на перемещенный объект (геометрическая фигура) и считывает значения свойств (Height, Width) для вычисления периметра фигуры. Результат вычислений размещается в Label1 -> Caption.

void __fastcall TForm1::Label1DragDrop(TObject *Sender,

TObject *Source, int X, int Y)

{

float p, pi=3.14; int w, h, r, D;

if (String(Source->ClassName())=="TShape")

{

h=((TShape *)Source)->Height;

w= ((TShape *)Source)->Width ;

D = w; if ( D > h ) D = h;

switch ((( TShape *)Source) -> Shape)

{ case stRectangle:

Label2->Caption ="Прямоугольник";

p= 2*(w + h);

break;

case stSquare:

Label2->Caption = "Квадрат";

p= 4*D;

break;

case stCircle:

Label2->Caption = "Круг";

p= pi*D;

break;

case stEllipse:

Label2->Caption = "Эллипс";

p=pi*(3*(w+h)/4-sqrt(w*h)/2);

break;

case stRoundRect:

Label2->Caption = "Закругленный

прямоугольник";

r=(D-((TShape*)Source)->Pen->

Width +1)/4;

p=2*(w+h)-8*r+2*pi*r;

break;

case stRoundSquare:

Label2->Caption="Закругленный

квадрат";

r=(D-((TShape*)Source)->Pen->

Width+1)/4;

p=4*D-8*r+2*pi*r;

break;

}

p=p/(Form1->PixelsPerInch/2.54);

Label1->Caption = FloatToStr (p);

}

}

При завершении процесса перетаскивания вне зависимости от его результата исходный объект получает событие OnEndDrag. Его параметры:

  • Sender– указатель объекта - источника;

  • Target– указатель объекта - приемника;

  • X, Y– координаты курсора.

В следующем примере переносимый компонент Shape1 узнает имя объекта - приемника (если объект не принят передается NULL):

void __fastcall TForm1::Shape1EndDrag(TObject *Sender, TObject *Target,

int X, int Y)

{

if (Target != NULL)

Label2->Caption =(AnsiString) (( TComponent *) Target)->Name;

}