Для библиотеки VCL фирмой Borland реализована собственная версия интерфейса Drag&Drop (переводится как "перетащить"). Интерфейс этот внутренний — передавать и принимать можно любые управляющие элементы Delphi внутри формы' (кроме самой формы). Он реализован без использования соответствующих функций API Windows — их нужно применять при организации общения с другими задачами путем перетаскивания.

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

 

CancelDrag Отменяет текущую drag-and-drop или drag-and-dock операцию.

 

Функция FindDragTarget (const Pos: TPoint;AllowDisabled: Boolean ): TControl;

Функция возвращает объект базового класса TControl, к которому относится позиция экрана с координатами, определенными параметром Pos. Данная функция используется для определения потенциального получателя drag-and-drop или drag-and-dock операции. Если для указанной позиции не существует никакого оконного средства управления, то функция возвращает nil. Параметр AllowDisabled определяет, будут ли учитываться заблокированные (disabled) объекты.

 

Функция IsDragObject( Sender: TObject ): Boolean;

Функция определяет, является ли объект, определенный в параметре Sender, потомком класса TDragObject. Данную функцию можно использовать в качестве параметра Source в обработчиках событий OnDragOver и OnDockOver для того, чтобы определить будет ли принят перетаскиваемый объект. Также функцию IsDragObject можно использовать в качестве параметра Source в обработчиках событий OnDragDrop и OnDockDrop для того, чтобы правильно интерпретировать перетаскиваемый объект.

 

Code:

// In the PageControl's OnMouseDown event handler:

 

procedure TForm1.PageControl1MouseDown(Sender: TObject;

Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

begin

PageControl1.BeginDrag(False);

end;

 

 

// In the PageControl's OnDragDrop event handler:

 

procedure TForm1.PageControl1DragDrop(Sender, Source: TObject; X, Y: Integer);

const

TCM_GETITEMRECT = $130A;

var

i: Integer;

r: TRect;

begin

if not (Sender is TPageControl) then Exit;

with PageControl1 do

begin

   for i := 0 to PageCount - 1 do

   begin

     Perform(TCM_GETITEMRECT, i, lParam(@r));

     if PtInRect(r, Point(X, Y)) then

     begin

       if i <> ActivePage.PageIndex then

         ActivePage.PageIndex := i;

       Exit;

     end;

   end;

end;

end;

 

// In the PageControl's OnDragOver event handler:

 

procedure TForm1.PageControl1DragOver(Sender, Source: TObject; X,

Y: Integer; State: TDragState; var Accept: Boolean);

begin

if Sender is TPageControl then

   Accept := True;

end;

 

Взято с http://delphiworld.narod.ru

 

Интерфейс переноса и приема компонентов появился достаточно давно. Он обеспечивает взаимодействие двух элементов управления во время выполнения приложения. При этом могут выполняться любые необходимые операции. Несмотря на простоту реализации и давность разработки, многие программисты (особенно новички) считают этот механизм малопонятным и экзотическим. Тем не менее использование Drag-and-Drop может оказаться очень полезным и простым в реализации. Сейчас мы в этом убедимся.

 

Для того чтобы механизм заработал, требуется настроить соответствующим образом два элемента управления. Один должен быть источником (Source), второй — приемником (Target). При этом источник никуда не перемещается, а только регистрируется в качестве такового в механизме.

 

Данный способ позволяет не погружаясь глубоко в создание компонент осуществить операцию "drag and drop" выделенного текста.

 

Создайте новый компонент (TMyMemo), наследовав его от TMemo. И объявите его следующим образом:

Автор: Павел

Свойства DragMode, DragCursor, методы BeginDrag, OnDragOver, OnDragDrop, OnEndDrag, OnStartDrag, параметр Accept

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

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

Начало перетаскивания определяется свойством DragMode, которое может устанавливаться в процессе проектирования или программно равным dmManual или dmAutomatic. Значение dmAutomatic (автоматическое) определяет автоматическое начало процесса перетаскивания при нажатии пользователем кнопки мыши над компонентом. Однако в этом случае событие OnMouseDown, связанное с нажатием пользователем кнопки мыши, для этого компонента вообще не наступает.

 

 

Возьмите форму, бросьте на нее панель, на onMouseDown панели прицепите код:

 

Code:

procedure TForm1.Panel1MouseDown(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

{©Drkb v.3(2007): www.drkb.ru}

begin

ReleaseCapture;

Panel1.Perform(WM_SYSCOMMAND, $F012, 0);

end;

 

Теперь в run-time панель можно таскать как в дизайне...

 

Взято с Vingrad.ru http://forum.vingrad.ru

 

 

Автор: Neil

Поверьте, достаточно просто преобразовать X,Y координаты, передаваемые в параметрах событий OnDragOver и OnDragDrop, в координаты формы.

 

Работайте со свойствами Left и Top компонента, над которым перемещается курсор. Приведу простой пример. Поместите на форму компонент Memo и присвойте свойству Align значение alTop. Поместите на форму панель, также присвойсте свойству Align значение alTop и задайте небольшое значение свойству Height, скажем 6 или 7 пикселей. Установите DragMode на dmAutomatica и DragCursor на crVSplit. Поместите другой Memo-компонент и установите Align на alClient. Одновременно выберите оба Memo-компонента, панель и создайте общий обработчик события OnDragOver как показано ниже:

 

 

Code:

unit Unit1;

 

interface

 

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

ComCtrls;

 

type

TForm1 = class(TForm)

   TreeView1: TTreeView;

   procedure TreeView1DragDrop(Sender, Source: TObject; X, Y: Integer);

   procedure TreeView1DragOver(Sender, Source: TObject; X, Y: Integer;

     State: TDragState; var Accept: Boolean);

private

   procedure MoveNode(TargetNode, SourceNode: TTreeNode);

end;

 

var

Form1: TForm1;

 

implementation

 

{$R *.dfm}

 

procedure TForm1.MoveNode(TargetNode, SourceNode: TTreeNode);

var

NodeTmp: TTreeNode;

I: Integer;

begin

with TreeView1 do

begin

   // проверяем, является ли целевой элемент предком перетаскиваемого

   NodeTmp := TargetNode.Parent;

   while Assigned(NodeTmp) do

     if NodeTmp = SourceNode then

       Abort

     else

       NodeTmp := NodeTmp.Parent;

 

   // копируем перетаскиваемый элемент в новосозданный

   NodeTmp := Items.AddChild(TargetNode, SourceNode.Text);

   NodeTmp.Data := SourceNode.Data;

 

   for I := 0 to SourceNode.Count - 1 do

     MoveNode(NodeTmp, SourceNode.Item[I]);

 

   Selected := NodeTmp;

   TopItem := NodeTmp.getPrev;

   TargetNode.Expand(True);

end;

end;

 

procedure TForm1.TreeView1DragDrop(Sender, Source: TObject; X, Y: Integer);

var

TargetNode, SourceNode: TTreeNode;

begin

with TreeView1 do

begin

   TargetNode := GetNodeAt(X, Y);

   SourceNode := Selected;

 

   if (TargetNode = SourceNode) or (TargetNode = nil) then

   begin

     EndDrag(False);

     Exit;

   end;

   MoveNode(TargetNode, SourceNode);

   SourceNode.Free;

end;

end;

 

procedure TForm1.TreeView1DragOver(Sender, Source: TObject; X, Y: Integer;

State: TDragState; var Accept: Boolean);

var

SourceNode, TargetNode, NodeTmp: TTreeNode;

begin

if Sender = TreeView1 then

try

   // скроллинг дерева при перетаскивании

   if Y > TreeView1.Height - 10 then

   begin

     TreeView1.TopItem := TreeView1.TopItem.getNext;

     Sleep(100); // пауза

   end else

     if Y < 10 then

     begin

       TreeView1.TopItem := TreeView1.TopItem.getPrev;

       Sleep(100); // пауза

     end;

 

   TargetNode := TreeView1.GetNodeAt(X, Y);

   SourceNode := TreeView1.Selected;

 

   if (TargetNode = nil) or (TargetNode = SourceNode) then Abort;

 

   Accept := True;

   // проверяем, является ли целевой элемент предком перетаскиваемого

   NodeTmp := TargetNode.Parent;

   while Assigned(NodeTmp) do

     if NodeTmp = SourceNode then

       Abort

     else

       NodeTmp := NodeTmp.Parent;

except

   Accept := False;

end;

end;

 

end.

Автор: Smike

Взято из http://forum.sources.ru

Перетаскивание информации с помощью мыши стало стандартом для программ, работающих в Windows. Часто это бывает удобно и позволяет добиться более быстрой работы. В данной статье я постарался показать максимальное количество примеров использования данной технологии при разработке приложений в среде Delphi. Конечно, результат может быть достигнут различными путями, продемонстрированные приемы не являются единственными и, возможно, не всегда самые оптимальные, но вполне работоспособны, и указывают направление поиска. Надеюсь, что они побудят начинающих программистов к более широкому использованию Drag'n'Drop в своих программах, тем более что пользователи, особенно неопытные, быстро привыкают к перетаскивание и часто его применяют.

 

Проще всего делать Drag из тех компонентов, для которых однозначно ясно, что именно перетаскивать. Для этого устанавливаем у источника DragMode = dmAutomatic, а у приемника пишем обработчики событий OnDragOver - разрешение на прием, и OnDragDrop - действия, производимые при окончании перетаскивания.

 

  

Code:

procedure TForm1.TreeView1DragOver(Sender, Source: TObject; X, Y: Integer;

  State: TDragState; var Accept: Boolean);

begin

  if (y < 15) then {On the upper edge - should scroll up }

    SendMessage(TreeView1.Handle, WM_VSCROLL, SB_LINEUP, 0)

  else if (TreeView1.Height - y < 15) then { On the lower edge - should scroll down }

    SendMessage(TreeView1.Handle, WM_VSCROLL, SB_LINEDOWN, 0);

end;