where : ibrtses delphi

Delphi - dragging and dropping


the source code of this page may not appear correctly in certain browsers
due to special characters. Have a look at the source of this HTML page
with notepad instead

The text was copy-pasted from the Delphi 2 online help, where it is spread over several chapters

Dragging and dropping of items on a form can be a handy way to enable users 
to manipulate objects in a form. You can let users drag entire components, 
or let them drag items out of components such as list boxes into other components.
There are four essential elements to drag-and-drop operations:

1. Starting a drag operation
2. Accepting dragged items
3. Dropping items
4. Ending a drag operation

Starting a drag operation

Every control has a property called DragMode that controls how the component responds when a user begins dragging the component at run time. If DragMode is dmAutomatic, dragging begins automatically when the user presses a mouse button on the control. A more common usage is to set DragMode to dmManual (which is the default) and start the dragging by handling mouse-down events. To start dragging a control manually, call the control's BeginDrag method. BeginDrag takes a Boolean parameter called Immediate. If you pass True, dragging begins immediately, much as if DragMode were dmAutomatic. If you pass False, dragging does not begin until the user actually moves the mouse a short distance. Calling BeginDrag(False) allows the control to accept mouse clicks without beginning a drag operation. You can also place conditions on whether to begin dragging, such as checking which button the user pressed, by testing the parameters of the mouse-down event before calling BeginDrag.


The following code handles a mouse-down event on a file list box by beginning dragging only if it was the left mouse button pressed: procedure TFMForm.FileListBox1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if Button = mbLeft then { only drag if left button pressed } with Sender as TFileListBox do { treat Sender as TFileListBox } begin if ItemAtPos(Point(X, Y), True) >= 0 then { is there an item here? } BeginDrag(True); { if so, drag it } end; end;

Accepting dragged items

When a user drags something over a control, that control receives an OnDragOver event, at which time it must indicate whether it can accept the item if the user drops it there. Delphi changes the drag cursor to indicate whether the control can accept the dragged item. To accept items dragged over a control, attach an event handler to the control's OnDragOver event. The drag-over event has a variable parameter called Accept that the event handler can set to True if it will accept the item. Setting Accept to True specifies that if the user releases the mouse button at that point, dropping the dragged item, the application can then send a drag-drop event to the same control. Setting Accept to False specifies that the application will not drop the item on that control. This means that a control should never have to handle a drag-drop event for an item it does not know how to handle. The drag-over event includes several parameters, including the source of the dragging and the current location of the mouse cursor. The event handler can use those parameters to determine whether to accept the drop. Most often, a control accepts or rejects a dragged item based on the type of the sender, but it can also accept items only from specific instances.


In the following example, a directory outline accepts dragged items only if they come from a file list box: procedure TFMForm.DirectoryOutline1DragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean); begin if Source is TFileListBox then Accept := True; end;

Dropping items

Once a control indicates that it can accept a dragged item, it should then also define some way to handle the item should it be dropped. If a user sees the mouse cursor change to indicate that a control will accept the item being dragged, it is reasonable for the user to then expect that dropping the item there will accomplish some task. To handle dropped items, attach an event handler to the OnDragDrop event of the control accepting the dropped item. Like the drag-over event, the drag-drop event indicates the source of the dragged item and the coordinates of the mouse cursor over the accepting control. These parameters enable the drag-drop handler to get any needed information from the source of the drag and determine how to handle it.


In the following code, a directory outline accepting items dragged from a file list box can move the file from its current location to the directory dropped on: procedure TFMForm.DirectoryOutline1DragDrop(Sender, Source: TObject; X, Y: Integer); begin if Source is TFileListBox then with DirectoryOutline do ConfirmChange('Move', FileList.FileName, Items[GetItem(X, Y)].FullPath); end;

Ending a drag operation

When a dragging operation ends, either by dropping the dragged item or by the user releasing the mouse button over a control that does not accept the dragged item, Delphi sends an end-drag event back to the control the user dragged. To enable a control to respond when items have been dragged from it, attach an event handler to the OnEndDrag event of the control. The most important parameter in an OnEndDrag event is called Target, which indicates which control, if any, accepted the drop. If Target is nil, it means no control accepted the dragged item. Otherwise, Target is the control that accepted the item. The OnEndDrag event also includes the x- and y-coordinates on the receiving control where the drop occurred.


In this example, a file list box handles an end-drag event by refreshing its file list, assuming that dragging a file from the list changed the contents of the current directory: procedure TFMForm.FileListBox1EndDrag(Sender, Target: TObject; X, Y: Integer); begin if Target <> nil then FileList.Update; end;

Feedback is welcome


last updated: 23.june.99

sponsored links

Copyright (99,2000) Ing.Büro R.Tschaggelar