アプリケーションの実行状態でEditやButtonをドラッグ&ドロップで自由に配置して、
その位置を保存するようなプログラムを作ろうとしているのですが、
EditやButtonをドラッグで移動させることができません。
procedure TForm1.Edit1DragDrop(Sender, Source: TObject; X, Y: Integer);
begin
Edit1.Left := X;
Edit1.Top := Y;
end;
このように記述しているのですが、そもそもEditを掴むことができません。
イベントの使い方自体が間違っているのでしょうか?どなたかご教授お願いします。
>イベントの使い方自体が間違っているのでしょうか?どなたかご教授お願いします。
その通り。間違ってる。"ご教授"など大それたことを要求されて.....
そもそも、コモンコントロール自身に対してDrag/Dropする機能はありません。
なので自分自身のコードでそれっぽく見せる工夫が必要です。
で、サンプルですがコードが長くなりそうなので私はパスします。
頑張ってください。
TPanelにTEditを配置して、TPanelの部分をつかむようにするとか?
要はハンドルをつくるということで。
こんなのは?
タイトルバーのないフォームを移動させるコードを利用
procedure TForm1.Edit1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if (ssLeft in Shift) and (Sender is TWinControl) then begin
ReleaseCapture;
//こちらか
SendMessage(TWinControl(Sender).Handle, WM_SYSCOMMAND,
SC_MOVE or 2, MAKELONG(X,Y));
//こちら、好きにすればいい
//TWinControl(Sender).Perform(WM_NCLBUTTONDOWN, HTCAPTION, 0);
end;
end;
自由に移動するモードのときだけ有効にしないといけません。
常に移動もできて、入力とかも自由に行いときは、drtさんの言うとおり
Panelでも置いて、掴める場所を固定しないといけないね
DragDropイベントを使うのであれば以下のコードでも可能です。
他の方のレスの内容も考慮する必要があると思います。
また、以下のようなのもあります。参考まで
http://delphiholic.hopeseeds.com/?eid=264414
フォームにTEditとTButtonを配置して、以下のイベントを割り当てます。
そしてグローバル変数 Xp と Yp を定義します。
//ドラッグ開始位置のマウス座標
Xp : Integer;
Yp : Integer;
//====================================
// マウスをDownしたらドラッグ開始
//====================================
procedure TForm1.Edit1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Xp := X;
Yp := Y;
TControl(Sender).BeginDrag(True);
end;
//====================================
// ドラッグ中の処理
//====================================
procedure TForm1.Edit1DragOver(Sender, Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean);
begin
Accept := (Sender = Source);
if Accept then begin
with Sender as TControl do begin
Left := Left+X-Xp;
Top := Top+Y-Yp;
end;
end;
end;
//====================================
// ドラッグ終了
//====================================
procedure TForm1.Edit1DragDrop(Sender, Source: TObject; X, Y: Integer);
begin
if (Sender = Source) then begin
with Source as TControl do begin
Left := Left+X-Xp;
Top := Top+Y-Yp;
EndDrag(true);
end;
end;
end;
使ったことは無いけど、この中(↓)にコンポーネントも有るよ。
>http://www.kobira.co.jp/sakura/d_ETC.htm
コメントを読んだだけです。
Form上で、Alignが alNoneのものだけ移動可能。Tagで区別してもいいかな。
type
TControl = class(Controls.TControl);
var
IsMoveMode: boolean;
ptBegin: TPoint;
procedure TForm3.FormCreate(Sender: TObject);
var
i: Integer;
begin
for i:=0 to ComponentCount-1 do begin
if TControl(Components[i]).Align = alNone then
TControl(Components[i]).OnMouseDown := AControlMouseDown;
end;
end;
procedure TForm3.AControlMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
// シフトキー押しながら左ボタン押下で移動開始
if (Button = mbLeft{mbRight})and(ssShift in Shift) then begin
ptBegin := Point(X, Y);
IsMoveMode := True;
TControl(Sender).MouseCapture := True;
TControl(Sender).OnMouseMove := AControlMouseMove;
TControl(Sender).OnMouseUp := AControlMouseUp;
end else begin
IsMoveMode := False;
end;
end;
procedure TForm3.AControlMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
IsMoveMode := False;
TControl(Sender).MouseCapture := False;
end;
procedure TForm3.AControlMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
var
pt: TPoint;
begin
if IsMoveMode then
with TControl(Sender) do begin
pt := Parent.ScreenToClient(ClientToScreen(Point(X, Y)));
Left := pt.X - ptBegin.X;
Top := pt.Y - ptBegin.Y;
end;
end;
>>回答してくださった皆さん
たくさんの回答ありがとうございます。
実行していない画面でコンポーネントを掴んで動かせるのだから、実行しても動かすのは容易だろうと甘く考えていました。
非常に勉強になりました。ありがとうございました。
ツイート | ![]() |