Solved

Drag & Drop TDragObject

Posted on 2001-08-24
6
1,147 Views
Last Modified: 2012-08-14
Hi, just a little background! I have 3 types of controls

Tjob: an ancestor of Tstatictext
Tresource: an ancestor of Tpanel
TAdvStringGrid: an ancestor of tstringgrid (From RX suite)

Multiple instances of Tjobs can sit on multiple instances of TPanel.  TAdvStringGrid can also hold Tjobs in its objects array, and displays corresponding info on each row for each associated Tjob it has.  Basically I want to be able to drag Tjobs between the Tresource panels and the TAdvStringGrid.  Dragging a job to the grid isn't a problem, but I can't work out how I can drag the Tjob item corresponding to the row selection from the grid on to a TResource panel.  

TheTjob item I want to drag is given by:
AdvStringGrid.objects[0,AdvStringGrid.Row] as TJob;

The Tresource drag & drop handlers require a Tjob object, ie:

procedure TResource.ResourceDragOver(Sender, Source: TObject; X,
  Y: Integer; State: TDragState; var Accept: Boolean);
begin
If Source is TJob then
   Accept:=IsCanAcceptJob(Source as TJob)
   else
   Accept:=false;
end;

(& similar for DragDrop)

So this is fine when dragging a Tjob on a Tresource, but when dragging from the grid, the Source becomes TadvStringGrid. Basically need to change it so that
Source is a specific TJob within the grid.

So do I need to create a TDragObject to do this and if so how should/can I pass the selected Tjob information within the TDragObject?  Hope u can help, and sorry this is a little long winded, although I'm sure you're used to my protracted explanations by now!!! Many thanks, P.
0
Comment
Question by:Pandora
  • 3
  • 3
6 Comments
 
LVL 1

Author Comment

by:Pandora
ID: 6422411
p.s. I don't want to reference the TAdvStringGrid in the Tresource class unit, ie I want the resource to stay ignorant of the state of the TAdvStringGrid altogether, if that makes sense!
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 6422965
?maybe

why not supply an additional attribute, maybe DragJob : TJob,
on the onstartdrag-event of the tjob and
like

-- in the type-declartion of your form
...
  private
     DragJob : TJob  public
   public
...

- in the Start of the TJOB

procedure TForm1.Job1StartDrag(Sender: TObject;
  var DragObject: TDragObject);
begin
  DragJob := Self;
end;

- in the grid

procedure TForm1.AdvStringGrid1StartDrag(Sender: TObject;
  var DragObject: TDragObject);
begin
  DragJob := HoweverYouKnowWhichTJobThisCurrentIs;
end;

- in your dragOver

procedure TResource.ResourceDragOver(Sender, Source: TObject; X,
        Y: Integer; State: TDragState; var Accept: Boolean);
begin
    Accept:= Assigned(DragJob) and (IsCanAcceptJob(DragJob))
end;

- in your dragdrop
...
  //your stuff you will do with TJob=DragJob
  DragJob := Nil;
...

- you may also set it to nil, if the dragopoeration is canceled

meikl ;-)
0
 
LVL 1

Author Comment

by:Pandora
ID: 6424121
Thanks Meikl very cunning! - sometimes I wonder why I don't just address my questions to you personally!!  

Just for PAQ refs, Because the TResource is a seperate unit (not referencing the main form in the uses clause) I have put a global var that equates to the DragDrop var used above in the Tjob unit instead - this was already referenced by the Tresource unit and the main form (holding the TAdvStringGrid) and so the change doesn't require extra units to be added to the TResource unit uses clause.

Meikl, could I ask you a related quicky (I've increased points to 300 to compensate!).  I'm having problems with drag-drop generally (particularly on the TAdvStringGrid) because the OnStartDrag event fires before other events such as the OnSelectCell & OnRowChanging events.  As such when I try to reference the AdvStringGrid.row property in the OnStartDrag proc, the row being dragged is not the same as the 'selected' row.  How can I ensure that these are the same?  I think I effectively need to call the OnSelectCell event in/before the OnstartDrag.  Should I be cunningly alternating the drag mode between dmmanual to dmautomatic to stop the OnstartDrag happening when the row is just being selected? but then I still want to be able to drag & drop as well as select. Agggh! Hope you can help this poor bewildered soul, many thanks again, P.
0
DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

 
LVL 27

Accepted Solution

by:
kretzschmar earned 300 total points
ID: 6424503
hi,

i didn't have this grid,
but i guess there may a mousetocell-method,
then you could use soemthing like this
(sample with a tstringgrid, maybe applyable to the tadvstringgrid)

procedure TForm1.StringGrid1StartDrag(Sender: TObject;
  var DragObject: TDragObject);
var P : TPoint;
    ACol, ARow : Integer;
begin
  GetCursorPos(P);  //where is the mouse
  P := StringGrid1.ScreenToClient(P);  //transform to relative coords
  StringGrid1.MouseToCell(P.x,P.y,ACol,ARow); //transform to gridccoords
  StringGrid1.Col := ACol;    //select the cell
  StringGrid1.Row := ARow;
  SHowMessage('Starting Drag');  //not needed
  //assign your dragjob now
end;


meikl ;-)
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 6424572
o yeah,

you wrote it in your q
(AdvStringGrid.objects[0,AdvStringGrid.Row] as TJob;)

procedure TForm1.StringGrid1StartDrag(Sender: TObject;
var DragObject: TDragObject);
var P : TPoint;
     ACol, ARow : Integer;
begin
  GetCursorPos(P);  //where is the mouse
  P := StringGrid1.ScreenToClient(P);  //transform to relative coords
  StringGrid1.MouseToCell(P.x,P.y,ACol,ARow); //transform to gridccoords
  StringGrid1.Col := ACol;    //select the cell
  StringGrid1.Row := ARow;
  {
  //now you assign here
  DragJob := AdvStringGrid.objects[0,ARow] as TJob;
  }
end;

meikl ;-)
0
 
LVL 1

Author Comment

by:Pandora
ID: 6424869
Aha! Thanks Meikl, thats done the trick! Best wishes, P :)
0

Featured Post

Efficient way to get backups off site to Azure

This user guide provides instructions on how to deploy and configure both a StoneFly Scale Out NAS Enterprise Cloud Drive virtual machine and Veeam Cloud Connect in the Microsoft Azure Cloud.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
This Micro Tutorial will give you a basic overview how to record your screen with Microsoft Expression Encoder. This program is still free and open for the public to download. This will be demonstrated using Microsoft Expression Encoder 4.
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question