Board index » delphi » BUG/Problem with TDragObject - drag'n'drop does not end

BUG/Problem with TDragObject - drag'n'drop does not end

Hello,

I just found out why one of my applications does not end the dragging of an
item under some circumstances. The user can not even terminate the program
unless he uses the task manager.

It took me plenty of time to find out what's the problem and I finally
found the reason:

When you create a permanent TDragObject you will use for drag'n'drop
operations and you create another TDragObject within the OnDragDrop event
handler, then you can't use the "permanent" TDragObject instance for any
further drag'n'drop operations (it will never, never be "dropped").

I currently create a TDragObject in OnDragDrop because in some situations
it is necessary for my application to use it in OnDragDrop.

Is this a known problem?

Here is a sample application that demonstrates the problem (didn't put it
in the binary NG as it is not that large)...

--------- Main.pas ----------

unit Main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
Forms,
  Dialogs, StdCtrls, ExtCtrls, ComCtrls;

type

  TForm1 = class(TForm)
    Panel1: TPanel;
    Label1: TLabel;
    Panel2: TPanel;
    Label2: TLabel;
    procedure Label1StartDrag(Sender: TObject;
      var DragObject: TDragObject);
    procedure Label2DragOver(Sender, Source: TObject; X, Y: Integer;
      State: TDragState; var Accept: Boolean);
    procedure Label2DragDrop(Sender, Source: TObject; X, Y: Integer);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    MyObj : TDragObject;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Label1StartDrag(Sender: TObject;
  var DragObject: TDragObject);
begin
  DragObject := MyObj;
end;

procedure TForm1.Label2DragOver(Sender, Source: TObject; X, Y: Integer;
  State: TDragState; var Accept: Boolean);
begin
  Accept := TRUE;
end;

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

  // create a dummy TDragObject (this will create problems)
  // remove this line and everything is fine...
  TDragObject.Create;

  raise Exception.Create('This is a exception raised in OnDragDrop.'#13+
    'A dummy TDragObject has just been created.'#13+
    'Now try to drag again and you''ll see the problem...');
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  MyObj := TDragObject.Create;
end;

end.

---------- Main.DFM ------------

object Form1: TForm1
  Left = 508
  Top = 218
  Width = 295
  Height = 226
  Caption = 'Form1'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  OnCreate = FormCreate
  PixelsPerInch = 96
  TextHeight = 13
  object Panel1: TPanel
    Left = 16
    Top = 16
    Width = 105
    Height = 65
    TabOrder = 0
    object Label1: TLabel
      Left = 1
      Top = 1
      Width = 103
      Height = 63
      Align = alClient
      Alignment = taCenter
      AutoSize = False
      Caption = 'Click here and drag me to panel 2!'
      DragMode = dmAutomatic
      Layout = tlCenter
      WordWrap = True
      OnStartDrag = Label1StartDrag
    end
  end
  object Panel2: TPanel
    Left = 144
    Top = 128
    Width = 113
    Height = 57
    TabOrder = 1
    object Label2: TLabel
      Left = 1
      Top = 1
      Width = 111
      Height = 55
      Align = alClient
      Alignment = taCenter
      AutoSize = False
      Caption = 'Drag it here!'
      Layout = tlCenter
      WordWrap = True
      OnDragDrop = Label2DragDrop
      OnDragOver = Label2DragOver
    end
  end
end

--
To reply by e-mail, use following address:
  udonews AT nova-sys.net

 

Re:BUG/Problem with TDragObject - drag'n'drop does not end


Quote
> When you create a permanent TDragObject you will use for drag'n'drop
> operations and you create another TDragObject within the OnDragDrop event
> handler, then you can't use the "permanent" TDragObject instance for any
> further drag'n'drop operations (it will never, never be "dropped").

Have you tried looking/using TDragObjectEx and TDragControlObjectEx which
were designed to handle freeing the drag object.  These classes are in D6
and up.

--
-Steve
Delphi/C++ Builder R&D
Borland Software Corporation
Please, no private email unless requested in this message, thank you.
http://www.geocities.com/delphihelp (last updated December 2, 2002)
Save time search http://groups.google.com first.
ActionBand FAQ http://www.geocities.com/delphihelp/info/ABFAQ.htm
How to Ask Questions the Smart Way:
http://www.tuxedo.org/~esr/faqs/smart-questions.html

Re:BUG/Problem with TDragObject - drag'n'drop does not end


"Steve Trefethen \(Borland\)" <strefet...@non.spam.junk.borland.com> wrote
in news:3e380579$1@newsgroups.borland.com:

Quote
> Have you tried looking/using TDragObjectEx and TDragControlObjectEx which
> were designed to handle freeing the drag object.  These classes are in D6
> and up.

No, because I can't simulate the same behaviour with TDragObjectEx. In my
application (and in the sample program I posted) I don't want the
TDragObject to be freed at all. In fact, it is always present as long the
drag source exists.

To be more specific, I have in my application some ListViews where the user
can select an item and drag it elsewhere. Each ListView item has already a
TDragObject associated to it that contains detailed information of that
item. So when OnStartDrag is triggered I simply do:

DragObject := tMyDragObject(ListView.Selected.Data);

The component where the object is dropped on, simply takes this object,
extracts the information and does some database operation. It does not free
the object because it canbe used for successive dragging operations.

Maybe I do not use TDragObject exactly in the way it was meant to be but it
works and I can see no reason why it shouldn't work or why I could only
create the TDragObject in OnStartDrag.

It works fine as long as I don't create another TDragObject in OnDragDrop
(I do that to create a temporary container of the same type under some
situations).

You see, I could not use TDragObjectEx because the DragObject should NOT be
freed in OnDragDrop. In fact, in the sample program of the previous post
the TDragObject is never freed (not expicitely nor implicitely) - I've
chekced that.

In the meantime I redesigned my application a bit to avoid this problem.

The documentation says "Create the custom drag object in the OnStartDrag
event of the dragged control." - should I read this as "the custom drag
object MUST BE created in the OnStartDrag event" ?

Udo

PS: Noticed this problem in Delphi 6 and Delphi 7.

--
To reply by e-mail, use following address:
  udonews AT nova-sys.net

Other Threads