9.2 General steps for developing drag and drop functions
Drag and drop is a function that facilitates the operation of objects provided by Windows, and can be easily developed in Delphi.
come out. According to the drag-and-drop operation process, the development steps can be divided into four stages, namely:
●Start drag operation
●Receive drag items
●Drop the drag item
●Stop dragging operation
During the introduction process, we will combine a TabSet (tagged set) drag and drop operation example. The interface design is shown in the figure.
When the user drags a tag to the position of another tag at runtime, the tag will move to that location and cause
Rearrangement of the tag set.
9.2.1 Start dragging
When DragMode is set to dmAutomatic, drag automatically when the user presses the mouse on the source control
Start; When set to dmManual, decide whether to start dragging by handling mouse events. If you want to start dragging
Use BeginDrag method.
In TabSet drag and drop, we use the MouseDown event processing below to start dragging a tag.
First, determine whether the pressed left button is the left button, and then determine whether the item is legal.
PRocedure TForm1.TabSet1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
DragItem: Integer;
Begin
if Button = mbLeft then
Begin
DragItem := TabSet1.ItemAtPos(Point(X, Y));
if (DragItem > -1) and (DragItem < TabSet1.Tabs.Count) then
TabSet1.BeginDrag(False);
end;
end;
9.2.2 Receive dragged items
Whether a control can receive drag items is determined by the OnDragOver event of the control. In TabSet dragging, the main thing is to use the mouse position to judge.
procedure TForm1.TabSet1DragOver(Sender, Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean);
var
DropPos: Integer;
Begin
if Source = TabSet1 then
Begin
DropPos := TabSet1.ItemAtPos(Point(X, Y));
Accept := (DropPos > -1) and (DropPos <> TabSet1.TabIndex) and
(DropPos < TabSet1.Tabs.Count);
end;
else
Accept := False;
end;
9.2.3 Put down the drag item
When the OnDragOver event processing returns Accept True and the item is dropped, the OnDragDrop event
The process of dragging and dropping the response. In the TabSet drag and drop instance, it is to change the position of the tag.
procedure TForm1.TabSet1DragDrop(Sender, Source: TObject; X, Y: Integer);
var
OldPos: Integer;
NewPos: Integer;
Begin
if Source = TabSet1 then
Begin
OldPos := TabSet1.TabIndex;
NewPos := TabSet1.ItemAtPos(Point(X, Y));
if (NewPos > -1) and (NewPos <> OldPos) then
TabSet1.Tabs.Move(OldPos, NewPos);
end;
end;
9.2.4 End drag operation
There are two ways to end the drag operation: either the user releases the mouse key or the program uses the EndDrag method.
Forced abort drag. There are two consequences of ending the drag operation: drop is accepted or drop is ignored.
After the drag operation is completed, the source control will receive a message to respond to the drag end event OnEndDrag.
9.3 Drag and drop application example: drag and drop support for file manager
Although the file manager application example developed in Chapter 6 has begun to take shape in function, it is operational
Compared with Windows' file manager, there are still many shortcomings. The biggest drawback is that it does not support drag and drop movement of files
and drag and drop copy. At the end of this chapter, we can make up for this flaw.
File drag and drop movement refers to the file when the user drags a file to a directory under the directory tree and drops it.
It will automatically move to this directory; drag-and-drop copy of a file refers to when the user drags a file to a drive label
When you put it on and drop it, the file will be automatically copied to the current directory of the drive. File list box as source control and
The directory tree and drive label of the target control can be located in different subwindows. The current directory of the drive is any sub
The latest operation result of the window, regardless of whether this sub-window has a relationship with the drag source and the drag target.
In order to implement the above functions, there are two problems that must be solved first:
1.How to record the current directory of each drive?
For this we define a global variable:
var CurrentDirList: Array[0...25] of string[70];
In the OnChange event of DirectoryOutline:
procedure TFMForm.DirectoryOutlineChange(Sender: TObject);
Begin
CreateCaption;
FileList.clear;
FileList.Directory := DirectoryOutline.Directory;
FileList.Update;
CurrentDirList[DriveTabSet.TabIndex] := DirectoryOutline.Directory;
FileManager.DirectoryPanel.Caption := DirectoryOutline.Directory;
end;
Because DriveTabSet responds to the OnClick event before responding to the OnDragDrop event, and is activated by the event
Send the Onchange event of DirectoryOutline, so it can be guaranteed to be used in the OnDragDrop event at any time
The currentDirList array item to be not an empty string.
2. How to ensure the irrelevance of movement and copying with sub-windows?
A key issue here is that when we judge the source control, we use the is operator to perform type checking:
If Source is TFileList then…
If we use the following statement:
If Source = FileList then
…
Then the movement and copy operations will be limited to the scope of this sub-window.
When we solved the above question, our work was just following the general development steps of drag and drop, and we completed it step by step.
1.FileList starts dragging operation
procedure TFMForm.FileListMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
Begin
if Button = mbLeft then
with Sender as TFileListBox do
Begin
if ItemAtPos(Point(X, Y), True) >= 0 then
BeginDrag(False);
end;
end;
ItemAtPos is used to check whether there is currently a file. The BeginDrag method passes the parameter False, allowing FileList to handle mouse events separately without starting to drag. In fact, this situation exists in large quantities.
2. DirectoryOutline and DriveTabSet decide whether to accept dragging and put it down on the spot.
procedure TFMForm.DirectoryOutlineDragOver(Sender, Source: TObject; X,
Y: Integer; State: TDragState; var Accept: Boolean);
Begin
If Source is TFileListBox then
Accept := True;
end;
procedure TFMForm.DriveTabSetDragOver(Sender, Source: TObject; X,
Y: Integer; State: TDragState; var Accept: Boolean);
var
PropPos: Integer;
Begin
If Source is TFileListBox then
with DriveTabSet do
Begin
PropPos := ItemAtPos(Point(X,Y));
Accept := (PropPos > -1) and (PropPos < Tabs.Count);
end;
end;
DirectoryOutline is unconditional acceptance, while DriveTabSet needs to check whether it is a legal tag.
3. Drag and drop response
DirectoryOutline drag and drop is used to implement file movement function. Calling ConfirmChange event in the program
During the processing process, the target path is obtained by DirectoryOutline.Items[GetItem(X,Y)].FullPath.
procedure TFMForm.DirectoryOutlineDragDrop(Sender, Source: TObject; X,
Y: Integer);
Begin
If Source is TFileListBox then
with DirectoryOutline do
Begin
ConfirmChange('Move',FileList.FileName, Items[GetItem(X, Y)].FullPath);
end;
end;
DriveTabSet drag and drop is used to implement file copying function. Convert the current position into the corresponding driver in the program
The actuator letter, the target path is obtained by CurrentDirList [DriveTabSet.TabIndex].
procedure TFMForm.DriveTabSetDragDrop(Sender, Source: TObject; X,Y: Integer);
var
APoint: TPoint;
Begin
APoint.X := X; APoint.Y := Y;
DriveTabSet.TabIndex := DriveTabSet.ItemAtPos(APoint);
If Source is TFileListBox then
with DriveTabSet do
Begin
if CurrentDirList[TabIndex] <> '' then
ConfirmChange('Copy',TheFilename,CurrentDirList[TabIndex]);
end;
end;
4.FileList response to dragging ends and updates the file list
procedure TFMForm.FileListEndDrag(Sender, Target: TObject; X, Y: Integer);
Begin
if Target <> nil then FileList.Update;
end;