Data Accepting as Target

<< Click to Display Table of Contents >>

Navigation:  »No topics above this level«

Data Accepting as Target

Previous pageReturn to chapter overviewNext page

Accepting data

 

TNGDropTarget component allows to accept dragging data. the component provides Control property, which should be set to link to some TWinControl placed on the form. After that, this control become registered as a drag&drop target, and can accept data when the data dragged over this control.

TNGDropTarget component provides a lot of events for controlling current drag&drop operation:

 

OnDragEnter event is fired when the mouse cursor enter the control area.

OnDragOver event is fires when the mouse cursor moves over the control area.

OnDragLeave event is fired when the mouse cursor leaves the control area.

OnDrop event is fired when the user drops dragging data (e.g. when he release mouse button).

 

All these events declares "C" parameter of type TNGTargetContext, which contains all information about current drag&drop operation state, and provides methods and properties to accept or reject dragging data. The following members can be used to query current drag&drop operation state:

 

C.Action property determines current drag action: daEnter, daOver, daLeave or daDrop.

C.KeyState property allows to determine, which mouse buttons are currently down and whether Shift, Ctrl or Alt keys are pressed.

C.CursorPos property allows to determine current mouse cursor position in screen coordinates.

C.Allowed property provides access to allowed drop effects, which has been specified by the operation source side. In daDrop action this property specifies currently accepted drop effect; please read below. To learn more about drop effects please read Drop Effects section.

C.Data property provides access to TNGTargetData object, which can be used to query currently dragging data. The data contains a lot of properties and methods, like: HasFormat, HasAny, Formats, FormatName, AsFormat, AsText, AsUnicodeText, AsBitmap, ect.

 

Based on information, provided by the properties described above, the code in event handlers should decide, whether to accept data or not. If dragging data should be accepted by current drop target, C.Accepted context property should be set to preferred drop effect. the following rules apply to C.Accepted and C.Allowed properties in different drag&drop events:

 

daEnter (OnDragEnter) - C.Allowed is set to allowed by the source drop effects. C.Accepted is set to deNone initially, and can be changed inside event handler; however, its value is not really used, because, for simplicity, OnDragOver event is fired immediately after OnDragEnter.

daOver (OnDragOver) - C.Allowed is set to allowed by the source drop effects. C.Accepted is set to deNone initially, and can be changed inside event handler; this value is used to setup mouse cursor to indicate current accept state.

daLeave (OnDragLeave) - C.Allowed is set to allowed by the source drop effects. C.Accepted is set to deNone, and cannot be changed inside event handler. C.Data is also not accessible in this event.

daDrop (OnDrop) - C.Allowed is set to previously chosen in the OnDragOver event drop effect. C.Accepted is also set to this drop effect initially and cannot be changed.

 

These rules implies the following: C.Accepted should be really set only in daOver (OnDragOver) event. daDrop (OnDrop) - will not be fired is the data is not accepted, e.g. C.Accepted = deNone.

 

Since C.Accepted property cannot be set to value not included in C.Allowed property, its tricky to specify value for it manually. So, TNGTargetContext class provides a set of overloaded Accept methods, which takes different parameters and can be used to simplify code. In simplest form Accept method can take no parameters, which means that it accept data without any condition choosing from allowed drop effects automatically, based on currently pressed keys (Shift, Ctrl, Alt). To learn more about drop effects please read Drop Effects section.

 

TNGDropTarget component also provides OnDragAction event, which can be used instead of previously described events, and allows to simlify source code by having whole drag&drop related code inside a single event.

 

Lets now show an example of data accepting using OnDragAction event. The simplest case will look like:

 

procedure TForm1.NGDropTarget1DragAction(Sender: TObject; C: TNGTargetContext);
begin
  case C.Action of
    daOver: if C.Data.HasFormat(CF.TEXT) then
              C.Accept;
    daDrop: Edit1.Text := C.Data.AsText;
  end;
end;

 

Accept Helper Methods

 

TNGTargetContext object provides a set of overloaded Accept helper methods. The simplest case without any parameters was discussed above. All of these methods was specifically designed to allow very easy implementation of drop target event handlers. To get the impression of how they simplify code, lets write another example:

 

procedure TForm1.NGDropTarget1DragAction(Sender: TObject; C: TNGTargetContext);
var
  s: AnsiString;
begin
  if C.AcceptText(s) then
    Edit1.Text := s;
end;

 

That's all. No even "case C.Action of" is really required. The following rules are applied to C.Accept helper methods to allow such a simple code writing:

 

All these methods has Accepted parameter, which specifies possible accepted drop effects, but can be omitted, since it has a default value, indicating that all possible drop effects can be accepted. To learn more about drop effects please read Drop Effects section.

If the data should be accepted, all these methods sets C.Accepted to appropriate value, which is determined automatically, based on C.KeyState, C.Allowed and method's Accepted parameter value.

In actions other than daDrop, all these methods returns False, independently of whether the data can be accepted or not; and return True only if the data has been really accepted (in daDrop event only). They has been specially implemented in this way to support the following usage scenario:
 

procedure TForm1.NGDropTarget1DragAction(Sender: TObject; C: TNGTargetContext);
var
  s:  AnsiString;
  us: string;
begin
  if C.AcceptUnicodeText(us) then
    Edit1.Text := s
  else if C.AcceptText(s) then
    Edit1.Text := s
end;

 

That is:

in daOver event both formats (CF.TEXT and CF.UNICODETEXT) have a chance to be accepted.

In daDrop event, Unicode text (if available in dragging data) will be preferred to ANSI text.

 

Please note, that C.Accept helper methods has been designed to simplify code in simple cases. In more advances cases, all other methods, described below can be used explicitly.

 

Fluent Interface

 

Dragging data acceptance can be tiny as well as drag&drop operations execution. For such cases NG Drag&Drop provides special API for configuring drop targets even without placing the component on the form.  The API is provided by NGDropTarget global function, which returns special TNGDropTarget.TBuilder object and can be used like this:

 

procedure TForm6.FormCreate(Sender: TObject);
begin
  NGDropTarget.Register(MyTargetPanel, procedure(C: TNGTargetContext)
  var
    s: AnsiString;
  begin
    if C.AcceptText(s) then
      Edit1.Text := s;
  end);
end;
 
procedure TForm6.FormDestroy(Sender: TObject);
begin
  NGDropTarget.Unregister(MyTargetPanel);
end;

 

NGDropTarget.Register method can be used to register some TWinControl as a drop tasrget, and its usually called from OnFormCreate event handler. Do not forget to unregister drop target calling NGDropTarget.Unregister method eventually.