Drag and Drop

This example shows how to use the InputPosFromPoint method to realise a simple Drag&Drop in a Text Control application.

Drag&Drop in a text editor enables the user to drag a piece of text and drop it in a new location of the document. So, the incoming mouse events have to be analyzed and handled.

The Sample Program

In the InputPosFromPoint method is used to get the character position the user has clicked on. The current input position and the length of the selection are stored in global variables, because they are needed in the MouseUp event. If the input position the user has clicked on, is inside of the current selection, dragging can be started. First a global variable named dragging is set to true and the MousePointer property is changed to indicate that dragging is in process. The text and format information of the current selection is copied to a memory buffer using the SaveToMemory method. Finally, the Text Control's EditMode property is set to 2 - read only.

procedure TForm1.TXTextControl1MouseDown(Sender: TObject;
   Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
   pos : LongInt;
begin
   //Get current input position and the current selection
   pos := TXTextControl1.InputPosFromPoint(toTwips(X),
            toTwips(Y));
   gblStart := TXTextControl1.SelStart;
   gblLength := TXTextControl1.SelLength;
   //Check if the click occured in the current selection
   If (gblStart <= pos) And (gblStart + gblLength > pos)
         Then begin
      //Start dragging
      data := TXTextControl1.SaveToMemory(3, True);
      dragging := true;
      Cursor := 2;
      TXTextControl1.EditMode := 2;
   End;
end;

In the MouseUp event procedure the InputPosFromPoint method is used again to get the character position where the user has left the mouse button. When dragging is in process and the input position is not inside the current selection, the drop operation can be performed. The previously saved text now is inserted with the LoadFromMemory method after setting the new input position with the SelStart property.

procedure TForm1.TXTextControl1MouseUp(Sender: TObject;
   Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
   pos : LongInt;
begin
   pos := TXTextControl1.InputPosFromPoint(toTwips(X),
            toTwips(Y));
   If dragging Then begin
      //Check if the new input position is outside of
      //the current selection. If it's not, do not
      //copy the text
      If Not ((gblStart <= pos)
            And (gblStart + gblLength > pos)) Then begin
         TXTextControl1.SelText := '';
         If pos < gblStart Then
            TXTextControl1.SelStart := pos
         Else
            TXTextControl1.SelStart := pos - gblLength;
         TXTextControl1.LoadFromMemory(data, 3, True);
      End;
      //End dragging
      dragging := False;
      Cursor := 0;
      TXTextControl1.EditMode := 0;
   End;
end;