Form1にImage1を置き、マウスでクリックした位置にImage1を移動させたくて、
次のように書いたのですが、Image1の外(Form1上)では、動いてくれません。
TForm1MouseDownでは、肝心なImage1の上で動いてくれません。
こんな場合は、どうしたら良いものでしょう。?
また、下の「var I:Integer」は、procedure TForm1.Image1MouseDownの中に書くと、
認識しない(使えない)ようです。何故でしょう?
よろしくお願いします。delphi6pro+xp
var
Pxy:array[0..1] of TPoint;
Tx,Ty:Integer;
I:Integer;
procedure TForm1.FormCreate(Sender: TObject);
begin
Image1.Width:=200;
Image1.Height:=200;
with Image1.Canvas do
begin
Rectangle(0,0,200,200);
Rectangle(50,50,150,150);
MoveTo(0,100);
LineTo(200,100);
MoveTo(100,0);
LineTo(100,200);
end;
end;
procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Pxy[I].x:=x; Pxy[I].y:=y;
//座標確認用
Label1.Caption:='座標 : '+IntToStr(I)+': '+IntToStr(Pxy[I].x)+' , '+IntToStr(Pxy[I].y) ;
I:=I+1;
If I>1 then Begin
Tx:=Pxy[1].x-Pxy[0].x;
Ty:= Pxy[1].y-Pxy[0].y;
//座標確認用
Label2.Caption:='Top,Left : '+ IntToStr(Image1.Top)+' , '+IntToStr(Image1.Left);
Image1.Top:=Image1.Top+ Ty;
Image1.Left:=Image1.Left+Tx;
I:=0;
end;
end;
end.
TForm1MouseDownに書いて、Image1.Enableをfalseにしてやるってのはどうでしょうか?
>Image1の外(Form1上)では、動いてくれません。
>TForm1MouseDownでは、肝心なImage1の上で動いてくれません。
Image1MouseDown は Image1でクリックすると実行されるので
Form1でクリックしても実行されない
TForm1MouseDown は Form1上でクリックすると実行されるので
Image1でクリックしても実行されない
という事は・・・・・両方設定すればいいんだけど?
ほかにコンポーネント等が増えると全てのコンポーネントに
設定しなくてはいけなくなるので
procedure TForm1.ApplicationMessage(var Message: TMSG; var Handled: Boolean);
var
PT: TPoint;
begin
inherited;
if Message.message = WM_LBUTTONDOWN then
begin
PT := ScreenToClient(Message.pt);
Image1.Left := PT.x;
Image1.Top := PT.y;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Application.OnMessage := ApplicationMessage;
end;
こんな感じにするといい感じ?
表裏未里さん、KHE00221さん いつもありがとうございます。
>TForm1MouseDownに書いて、Image1.Enableをfalse
>という事は・・・・・両方設定
>procedure TForm1.ApplicationMessage
どれも望みの動きをしてくれました。
Enableをfalseにすることで画像を表示したままで、下のFormの座標を取得できる事など、思いもしませんでした。
Messageの方は、私にとってはブラックボックスで、新しい課題と成りましたが・・・。
いつも、あまりにも早く教えていただけて、簡単に解ったような気になり、解決ボタンを押した後で、同じことが聞き難くなり後悔しています。
最初の例で、変数「I」は、ここでしか使っていないので・・・
procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
I:Integer; ・・・・・・・・・・・宣言の位置を変更
begin
以下省略
とすると・・・
[ヒント] Unit1.pas(67): 'I' に代入された値は使われていません
[警告] Unit1.pas(55): 変数 'I' は初期化されない場合があります
[警告]は良いにしても、Imageは移動してくれません。何故でしょう?
タイトルの質問とは別の問題なような気もしますが「Image1MouseDown」つながりという事で、これも宜しくお願いします。
暇なので支援。
Panel1,Image1は画面上に貼り付けてやってください。
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls;
type
TForm1 = class(TForm)
Panel1: TPanel; //障害物として用意
Image1: TImage; //今回のターゲット
procedure FormCreate(Sender: TObject);
private
{ Private 宣言 }
procedure ApplicationMessage(var Message: TMSG; var Handled: Boolean);
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TForm1 }
procedure TForm1.ApplicationMessage(var Message: TMSG;
var Handled: Boolean);
var
PT: TPoint;
begin
//アプリケーションに来るメッセージをすべてチェック
inherited; //子コントロールにもメッセージを流す
//左マウスボタンを押した時の動作を記述
if Message.message = WM_LBUTTONDOWN then
begin
//messageの中にはメッセージにより様々なデータが格納されている
//今回はWM_LBUTTONDOWN
//中身はMSDNを調べてください。
PT := ScreenToClient(Message.pt);
Image1.Left := pt.X - (Image1.Width div 2);
Image1.Top := pt.Y - (Image1.Height div 2);
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
//アプリケーションに通るメッセージを閲覧
Application.OnMessage := ApplicationMessage;
//イメージの設定
Image1.Width:=200;
Image1.Height:=200;
with Image1.Canvas do
begin
Rectangle(0,0,200,200);
Rectangle(50,50,150,150);
MoveTo(0,100);
LineTo(200,100);
MoveTo(100,0);
LineTo(100,200);
end;
end;
end.
もにゃさん、お暇とはいえ、ご支援ありがとうございます。
しかも、詳細解説。
//中身はMSDNを調べてください。・・・はい。
障害物を2重3重に用意して見ましたが、教えていただいたどの例も、障害を物ともせず貫通しました。
後はvar I の疑問だけなのですが・・・
変数の宣言については、やはり入門書を読むことをお勧めします。
入門書が理解できていれば、この問題はすんなり解決するでしょう。
procedureの中でI:integerを宣言すること自体は全く問題ありません。
ためしに、新規プロジェクトを作って、MouseDownでIを参照させてみてください。
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
I:Integer;
begin
//以下二つの動作がないと警告、ヒントがでるはずです。
I:=10; //Iの初期化
caption:=IntToStr(I); //Iの参照
end;
>>[警告] Unit1.pas(55): 変数 'I' は初期化されない場合があります
Iの値が決められていない状態でIの値を参照しているのは大問題です。
>>[ヒント] Unit1.pas(67): 'I' に代入された値は使われていません
Iを一度も使用しないでいることです。
つまり、Iはあってもなくてもプログラムは同じ動作をすることを意味します。
先に、解決ボタンを押した後で、同じことが聞き難くなり後悔していると書いたばかりなのに、また、つい押してしまい後悔しています。
タイトルの問題は解決したものの、var I に付いて疑問を持ったのは、私にとっては正解で、もにゃさんがお暇だった事は、私に取って幸運でした。
>変数の宣言については、やはり入門書を読むことをお勧めします。
・・・と言われて、何冊もない手持ちの入門書を見てみましたが、すぐには解りません。
すいませんが、もにゃさん、もう少し教えてください。
>ためしに、新規プロジェクトを作って、MouseDownでIを参照させてみてください。
ここで、 caption:=IntToStr(I); は問題なく「10」が表示されましたが、
「Iを参照させてみて」が解りません。
ようやく仰る意味がわかりました。
「I:=10; //Iの初期化」をコメントアウトすると「1074822732」と意味不明な数値。
変数は初期化しないでは使えない、解っていたつもりが・・・
ブロックの中で I:Integer=0; とすると、
[エラー] Unit1.pas(52): ローカル変数は初期化できません
begin 以降でI:=Integer=0;としても、クリックのたびIが0になる、
それで、ブロックの外で var I:Integer を宣言したのですが、たまたま「I」が上手く機能してくれたのか、
ブロックの外で var I:Integer とした時は、I:=Integer=0;と理解してくれたのか、いずれにしても、
変数は初期化しないでは使えないものだと、改めて認識できました。
もにゃさん、皆さん本当に有難うございました。本当に解決です。
ツイート | ![]() |