Form1上でマウスボタンを押したままImage1にマウスを移動させ、
Image1でマウスボタンを離しても、
Image1のOnMouseUpイベントでは検出することが出来ないのですが、
この場合、Form1のOnMouseUpイベントからマウス座標を取得して
Image1の位置であるかを調べるしかないのでしょうか?
(最終的にはImage1〜Image2間でdrag&dropを実現したいと思っています。)
やりたいことは、Image1でマウスダウン、Image2でマウスアップではないのでしょうか。
Form1でマウスダウンしたときに、Image1をドラッグし始めたことにしたいと言うことでしょうか。
Form1でマウスダウンしたときに、Image1をドラッグし始めたことにしたいのであれば、
Image1.BeginDrag(True);
とすればドラッグが開始できますよ。
単に、Image1をImage2にドラッグしたいのであれば、Image1のDragModeをdmAutomaticにし、Image2のOnDragDropイベントを定義してやればよいかと思います。
将棋盤を再現しようと考えているのですが、
将棋盤や駒台は各々imageとして扱い、
その上に表示する駒はimagelistでまとめて扱うようにしています。
駒のドラッグドロップは下記のように考えています。
procedure TForm1.Image1MouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
imagelist1.SetDragImage($11,-image1.Left,-image1.Top);
imagelist1.BeginDrag(Form1.Handle,x,y);
end;
procedure TForm1.Image1MouseUp(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
imagelist1.EndDrag;
end;
ですがImage1(将棋盤)上でドラッグした場合、
Image1(将棋盤)の外でドロップしても呼ばれるのはImage1MouseUpになりますよね。
もしImage2(駒台)上にドロップしていた場合Image2(駒台)上であることを知りたい、ということです。
説明の仕方が悪くて、申し訳ありません。
Image1, Image2を区別せずに、内部ロジックで位置が解ればよいのでは?
作り方にもよるかと思いますが、私ならば、
初期処理
・9x9の二次元配列を用意。
・9x9の二次元配列内に、駒を設定。
ドラッグ処理
・Image1でのマウスダウンで、9x9のどこでマウスダウンしたかチェック。
・Image2のマウスアップで、9x9のどこでマウスアップしたかチェック。
というように。
そうすれば、Image1のマウスダウン・アップで処理できますし、表示ロジックと、駒の操作ロジックを切り分けられます。
Image1,Image2という関係を利用するならば、Image1のマウスアップの位置を、Formの位置に変換し、その位置と、Image2の位置を比較・・・とする必要があると思います。
訂正。
・Image2のマウスアップで、9x9のどこでマウスアップしたかチェック。
でなく、
・Image1のマウスアップで、9x9のどこでマウスアップしたかチェック。
でした。
こんな感じでどうでしょう?
升目の大きさは30x30、駒は面倒なので4つにしました。
コンポーネントは以下の通りです。
Image1(盤面): TImage Width,Height = 270
Image2(盤外) : TImage
Koma1〜4(駒) : TImage DragMode = dmAutomatic;
※.Image1はImage2より前面、Koma1〜4はImage1より前面に配置してください。
盤面、駒のグラフィックイメージは適当に設定してください。
内容が違うかもしれませんが、参考までに...
PS.レスが長くてすいません。
type
TForm1 = class(TForm)
Image1: TImage;
Image2: TImage;
Koma1: TImage;
Koma2: TImage;
Koma3: TImage;
Koma4: TImage;
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ EVENT : 駒(Koma1 〜 4) OnStartDrag 駒ドラッグ開始 }
{ ※.Koma1〜4共通のイベント }
procedure TForm1.Koma1StartDrag(Sender: TObject;
var DragObject: TDragObject);
begin
// DragOver,DragDropで駒を感知しないように全ての駒のEnabledをFalseにする。
Koma1.Enabled := False;
Koma2.Enabled := False;
Koma3.Enabled := False;
Koma4.Enabled := False;
end;
{ EVENT : 駒(Koma1 〜 4) OnStartDrag 駒ドラッグ終了 }
{ ※.Koma1〜4共通のイベント }
procedure TForm1.Koma1EndDrag(Sender, Target: TObject; X, Y: Integer);
var
AImg : TImage;
begin
// 全ての駒のEnabledをTrueに戻す。
Koma1.Enabled := True;
Koma2.Enabled := True;
Koma3.Enabled := True;
Koma4.Enabled := True;
end;
{ EVENT : 盤面(Image1) OnDragOver 駒のドラッグ移動中の処理 }
procedure TForm1.Image1DragOver(Sender, Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean);
var
AImg : TImage;
begin
if Source is TImage then
begin
AImg := Source As TImage;
// とりあえずコンポーネントの名前でドラッグ中のオブジェクトが
// 駒であることを判定しています。
if Copy(AImg.Name,1,4) = 'Koma' then
begin
// ドラッグを受け入れて...
Accept := True;
// マウス位置に駒を表示
AImg.Left := Image1.Left + X - (AImg.Width div 2);
AImg.Top := Image1.Top + Y - (AImg.Height div 2);
end;
end;
end;
{ EVENT : 盤面(Image1) OnDragDrop 駒のドロップ処理 }
procedure TForm1.Image1DragDrop(Sender, Source: TObject; X, Y: Integer);
var
AImg : TImage;
begin
if Source is TImage then
begin
AImg := Source As TImage;
// とりあえずコンポーネントの名前でドラッグ中のオブジェクトが
// 駒であることを判定しています。
if Copy(AImg.Name,1,4) = 'Koma' then
begin
// 駒の位置を升目に合わせる。
AImg.Left := Image1.Left + (X div 30) * 30;
AImg.Top := Image1.Top + (Y div 30) * 30;
end;
end;
end;
{ EVENT : 盤外(Image2) OnDragOver 駒のドラッグ移動中の処理 }
{ ※.盤外にドラッグしたくなければこの処理は不要です。}
procedure TForm1.Image2DragOver(Sender, Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean);
var
AImg : TImage;
begin
if Source is TImage then
begin
AImg := Source As TImage;
// とりあえずコンポーネントの名前でドラッグ中のオブジェクトが
// 駒であることを判定しています。
if Copy(AImg.Name,1,4) = 'Koma' then
begin
// ドラッグを受け入れて...
Accept := True;
// マウス位置に駒を表示
AImg.Left := Image2.Left + X - (AImg.Width div 2);
AImg.Top := Image2.Top + Y - (AImg.Height div 2);
end;
end;
end;
{ EVENT : 盤外(Image2) OnDragDrop 駒のドロップ処理 }
{ ※.盤外にドラッグしたくなければこの処理は不要です。}
procedure TForm1.Image2DragDrop(Sender, Source: TObject; X, Y: Integer);
var
AImg : TImage;
begin
if Source is TImage then
begin
AImg := Source As TImage;
// とりあえずコンポーネントの名前でドラッグ中のオブジェクトが
// 駒であることを判定しています。
if Copy(AImg.Name,1,4) = 'Koma' then
begin
ShowMessage('ここは、盤外です');
end;
end;
end;
end.
Panel1とPanel2をFormに貼り付けます。
Panel1にImage1を貼り付けます。
Panel2のDragOver,DragDropは
それぞれTForm1.Panel1DragOver,TForm1.Panel1DragDrop
を指定します。
procedure TForm1.Panel1DragDrop(Sender, Source: TObject; X, Y: Integer);
begin
Image1.Parent:=(Sender as TPanel);//駒の移動先(この場合はPanel2)を取得します
end;
procedure TForm1.Panel1DragOver(Sender, Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean);
begin
Accept:=true;
end;
上でImage1の
DragMode はdmAutomatic です。
にしのさん、masayanさん、karuさん、いろいろ有難うございます。
Image1(将棋盤)、Image2(後手番駒台)、Image3(先手番駒台)と
相互間のdrag&dropを考えていくと、かなり複雑になりそうですね...
試行錯誤しながら頑張って実現しようと思います。
ツイート | ![]() |