Author: Peter Below
I have a form with a TScrollBox on it. At runtime I dynamically add any number of a
custom control I created. These controls need to interact via Drag and Drop,
however, when I drag from one control and move to the edge of the TScrollBox it
doesn't automatically scroll to reveal the additional controls.
Answer:
Add a handler to the forms OnDragOver event so you get aware when the user drags
the mouse outside the scrollbox. You can the start a timer that fires scroll
messages at the scrollbox to get it to move. In the example below all edits are on
the scrollbox and share the edit drag handlers. The timer is set to 100 msecs and
initially disabled.
1 unit Unit1;
2
3 interface
4
5 uses
6 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
7 Buttons, ComCtrls, StdCtrls, ExtCtrls;
8
9 type
10 TForm1 = class(TForm)
11 ScrollBox1: TScrollBox;
12 Edit1: TEdit;
13 Edit2: TEdit;
14 Edit3: TEdit;
15 Edit4: TEdit;
16 Edit5: TEdit;
17 Edit6: TEdit;
18 Edit7: TEdit;
19 Edit8: TEdit;
20 Edit9: TEdit;
21 Edit10: TEdit;
22 Edit11: TEdit;
23 Edit12: TEdit;
24 Edit13: TEdit;
25 Label1: TLabel;
26 Timer1: TTimer;
27 procedure Edit1DragOver(Sender, Source: TObject; X, Y: Integer; State:
28 TDragState;
29 var Accept: Boolean);
30 procedure Edit1DragDrop(Sender, Source: TObject; X, Y: Integer);
31 procedure Timer1Timer(Sender: TObject);
32 procedure FormDragOver(Sender, Source: TObject; X, Y: Integer; State:
33 TDragState;
34 var Accept: Boolean);
35 private
36 public
37 { Public declarations }
38 end;
39
40 var
41 Form1: TForm1;
42
43 implementation
44
45 {$R *.DFM}
46
47 procedure TForm1.Edit1DragOver(Sender, Source: TObject; X, Y: Integer;
48 State: TDragState; var Accept: Boolean);
49 begin
50 Accept := Source is TEdit and (Sender <> Source);
51 end;
52
53 procedure TForm1.Edit1DragDrop(Sender, Source: TObject; X, Y: Integer);
54 begin
55 (Sender as TEdit).SelText := (Source as TEdit).Text;
56 end;
57
58 procedure TForm1.Timer1Timer(Sender: TObject);
59 var
60 pt: TPoint;
61 begin
62 {figure out where the mouse is}
63 GetCursorPos(pt);
64 pt := ScreenToClient(pt);
65 with scrollbox1.boundsrect, pt do
66 if (x > left) and (x < right) then
67 begin
68 if y < top then
69 scrollbox1.perform(WM_VSCROLL, SB_LINEUP, 0)
70 else if y > bottom then
71 scrollbox1.perform(WM_VSCROLL, SB_LINEDOWN, 0)
72 else
73 timer1.enabled := false;
74 end
75 else
76 timer1.enabled := false;
77 end;
78
79 procedure TForm1.FormDragOver(Sender, Source: TObject; X, Y: Integer;
80 State: TDragState; var Accept: Boolean);
81 begin
82 accept := false;
83 if State = dsDragLeave then
84 timer1.enabled := false
85 else if (source is TEdit) then
86 begin
87 {Figure if mouse is above or below the scrollbox, that determines
88 whether we enable the scroll timer.}
89 with scrollbox1.boundsrect do
90 timer1.enabled := (x > left) and (x < right) and ((y < top) or (y > bottom));
91 end;
92 end;
93
94 end.
|