Editをドラッグするには?

解決


river  2008-07-17 11:32:06  No: 31299  IP: 192.*.*.*

アプリケーションの実行状態でEditやButtonをドラッグ&ドロップで自由に配置して、
その位置を保存するようなプログラムを作ろうとしているのですが、
EditやButtonをドラッグで移動させることができません。

procedure TForm1.Edit1DragDrop(Sender, Source: TObject; X, Y: Integer);
begin
  Edit1.Left := X;
  Edit1.Top  := Y;
end;

このように記述しているのですが、そもそもEditを掴むことができません。
イベントの使い方自体が間違っているのでしょうか?どなたかご教授お願いします。

編集 削除
困る  2008-07-17 13:02:07  No: 31300  IP: 192.*.*.*

>イベントの使い方自体が間違っているのでしょうか?どなたかご教授お願いします。
その通り。間違ってる。"ご教授"など大それたことを要求されて.....

編集 削除
もにゃ  2008-07-17 14:17:20  No: 31301  IP: 192.*.*.*

そもそも、コモンコントロール自身に対してDrag/Dropする機能はありません。
なので自分自身のコードでそれっぽく見せる工夫が必要です。
で、サンプルですがコードが長くなりそうなので私はパスします。
頑張ってください。

編集 削除
drt  2008-07-17 14:38:12  No: 31302  IP: 192.*.*.*

TPanelにTEditを配置して、TPanelの部分をつかむようにするとか?
要はハンドルをつくるということで。

編集 削除
ofZ  2008-07-17 16:26:31  No: 31303  IP: 192.*.*.*

こんなのは?
タイトルバーのないフォームを移動させるコードを利用

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でも置いて、掴める場所を固定しないといけないね

編集 削除
Mr.XRAY  2008-07-17 21:28:03  No: 31304  IP: 192.*.*.*

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;

編集 削除
お名前  2008-07-18 08:57:16  No: 31305  IP: 192.*.*.*

使ったことは無いけど、この中(↓)にコンポーネントも有るよ。

>http://www.kobira.co.jp/sakura/d_ETC.htm

コメントを読んだだけです。

編集 削除
自前で  2008-07-18 12:56:20  No: 31306  IP: 192.*.*.*

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;

編集 削除
river  2008-07-21 11:03:59  No: 31307  IP: 192.*.*.*

>>回答してくださった皆さん

たくさんの回答ありがとうございます。
実行していない画面でコンポーネントを掴んで動かせるのだから、実行しても動かすのは容易だろうと甘く考えていました。
非常に勉強になりました。ありがとうございました。

編集 削除