Panelを自由に動かすことは出来ますか?
Panelだけを動かしたいんですが、どうしてもウインドウ全部が動いてしまいます。
もし、Panelだけ動かすことが出来るようでしたら教えていただけますか?
> ウインドウ全部が動いてしまいます。
なんとなく、これでいいような推測回答
handle → Panel.Handle
というか、コードを記述せよ。
すいません。
よく分からなくてネット上にあったサンプルを使ってみたらそうなってしまいました。
↓がそのサンプルです。
//Panel1.BevelWidthを4〜8にセットしておくこと
procedure TForm1.Panel1MouseDown(Sender: TObject; Button:
TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
ReleaseCapture;
if X < Panel1.BevelWidth then
begin
if Y < Panel1.BevelWidth then
Perform(WM_SYSCOMMAND, SC_SIZE or 4, 0) //左上
else if Y > Panel1.Height - Panel1.BevelWidth then
Perform(WM_SYSCOMMAND, SC_SIZE or 7, 0) //左下
else
Perform(WM_SYSCOMMAND, SC_SIZE or 1, 0); //左
end else if X > Panel1.Width - Panel1.BevelWidth then
begin
if Y < Panel1.BevelWidth then
Perform(WM_SYSCOMMAND, SC_SIZE or 5, 0) //右上
else if Y > Panel1.Height - Panel1.BevelWidth then
Perform(WM_SYSCOMMAND, SC_SIZE or 8, 0) //右下
else
Perform(WM_SYSCOMMAND, SC_SIZE or 2, 0); //右
end else if Y < Panel1.BevelWidth then
Perform(WM_SYSCOMMAND, SC_SIZE or 3, 0) //上
else if Y > Panel1.Height - Panel1.BevelWidth then
Perform(WM_SYSCOMMAND, SC_SIZE or 6, 0) //下
else
Perform(WM_SYSCOMMAND, SC_MOVE or 2, 0); //移動
end;
フォームのバーと見せかけるならば・・・・
procedure TForm1.MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if ssLeft in Shift then
begin
if Sender is TWinControl then
begin
ReleaseCapture;
SendMessage(TWinControl(Sender).Handle, WM_NCLBUTTONDOWN, HTCAPTION,0);
end;
end;
end;
これでだけで良いんだよ?
ただドラック中のMouseDownとかマウスの放し時のMouseUpが発生しないので
処理したい場合には無理だけど
>ただドラック中のMouseDown
MouseMove
サンプルのやつは
Perform だけだと Self.Perform になるので Panel2.Perform にしないと駄目だね
Panel1MouseDown は Pane1 じゃなくて その Form で実行されているから
ありがとうございます。
最終的にはpanelの上にImageを貼り付けて、マウスで自由に移動できるようにしたいのですが、その場合のアドバイスも頂けると嬉しいです。
サンプルのほうは
TPanelの上に乗せたTImageのOnMouseDown に 記述すれば移動するよ?
Captionに見せかけるほうは無理だけど
あとサンプルはサイズ変更に対応させてるんだね
Captionに見せかけるのもこんな感じにすればできるのか
if ssLeft in Shift then
begin
if Sender is TWinControl then
begin
ReleaseCapture;
SendMessage(TWinControl(Sender).Handle, WM_NCLBUTTONDOWN, HTCAPTION,0);
end;
if Sender is TControl then
begin
if TControl(Sender).Parent is TWinControl then
begin
ReleaseCapture;
SendMessage(TControl(Sender).Parent.Handle, WM_NCLBUTTONDOWN, HTCAPTION,0);
end;
end;
end;
今やってみたんですけど、やっぱり最初と同じ状態になってしまいます。
↑キミのやり方が悪いからだよ。
Formに Image1 と Panel1 と Panel2 を配置します
procedure TForm1.FormCreate(Sender: TObject);
begin
Image1.Parent := Panel1;
Image1.Align := alClient;
Image1.OnMouseDown := MouseDown;
Panel2.OnMouseDown := MouseDown;
end;
procedure TForm1.MouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);
var
WinControl : TWinControl;
begin
if Sender is TWinControl then
begin
WinControl := TWinControl(Sender);
end
else
begin
if Sender is TControl then
begin
if TControl(Sender).Parent is TWinControl then
begin
WinControl := TWinControl(TControl(Sender).Parent);
end;
end;
end;
with WinControl do
begin
(* サンプルそのまま *)
ReleaseCapture;
if X < Panel1.BevelWidth then
begin
if Y < Panel1.BevelWidth then
Perform(WM_SYSCOMMAND, SC_SIZE or 4, 0) //左上
else if Y > Panel1.Height - Panel1.BevelWidth then
Perform(WM_SYSCOMMAND, SC_SIZE or 7, 0) //左下
else
Perform(WM_SYSCOMMAND, SC_SIZE or 1, 0); //左
end else if X > Panel1.Width - Panel1.BevelWidth then
begin
if Y < Panel1.BevelWidth then
Perform(WM_SYSCOMMAND, SC_SIZE or 5, 0) //右上
else if Y > Panel1.Height - Panel1.BevelWidth then
Perform(WM_SYSCOMMAND, SC_SIZE or 8, 0) //右下
else
Perform(WM_SYSCOMMAND, SC_SIZE or 2, 0); //右
end else if Y < Panel1.BevelWidth then
Perform(WM_SYSCOMMAND, SC_SIZE or 3, 0) //上
else if Y > Panel1.Height - Panel1.BevelWidth then
Perform(WM_SYSCOMMAND, SC_SIZE or 6, 0) //下
else
Perform(WM_SYSCOMMAND, SC_MOVE or 2, 0); //移動
(* サンプルそのまま *)
end;
end;
1つのMouseDownで
TImage を乗せていない TPanel(Panel2)
TImage を乗せた TPanel(Panel1)
ともに移動出来ます。
どこかで見ましたが
こんなのでいかが?
FormにPanelをひとつ、
その上にImageを乗せて、それぞれに下記のように・・・
もっといい方法があると思いますが・・・
それなりに動いています。
private
{ Private 宣言 }
bDrag :Boolean;
ptBegin:TPoint;
procedure TForm1.Panel1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
ptBegin := Point(X,Y);
bDrag := True;
end;
procedure TForm1.Panel1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
bDrag := False;
end;
procedure TForm1.Panel1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
var
pt:TPoint;
begin
if bDrag = True then
begin
pt := Form1.ScreenToClient(Panel1.ClientToScreen(Point(X,Y)));
Panel1.Left := pt.X - ptBegin.X;
Panel1.Top := pt.Y - ptBegin.Y;
end;
end;
procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
ptBegin := Point(X,Y);
bDrag := True;
end;
procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
var
pt:TPoint;
begin
if bDrag = True then
begin
pt := Form1.ScreenToClient(Panel1.ClientToScreen(Point(X,Y)));
Panel1.Left := pt.X - ptBegin.X;
Panel1.Top := pt.Y - ptBegin.Y;
end;
end;
procedure TForm1.Image1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
bDrag := False;
end;
KHE00221さん
教えていただいた通りにプログラムを作ってはみたんですがエラーが出てしまい実行できなかったです。
私の方で何か入力が足りないところとかがあるんですかね?
maru3さん
教えていただいたプログラムを試してみたところpanelは動きました。
しかし、imageは配置した場所から動かずpanelだけが動いてしまいます。
一緒に動かすにはどうしたらよいでしょうか?
お二方、教えていただいてよろしいですか?
何度も質問してしまいすみません。
どこでどんなエラーが?
Panelの上にImageを乗せていますか?
Panelとは別の場所にImageを作っていませんか?
Panelだけだと上記の上の部分
procedure TForm1.Panel1MouseDown(***);
procedure TForm1.Panel1MouseUp(***);
procedure TForm1.Panel1MouseMove(***);
の3つで動くことは確認できます。
Panelの上にImaageを乗せると
Imageを通してPanelのMouse***イベントが届きませんので、
ImageのMouse***イベントを同様に書きます・・が・・・
procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
var
pt:TPoint;
begin
if bDrag = True then
begin
pt := Form1.ScreenToClient(Panel1.ClientToScreen(Point(X,Y)));
Panel1.Left := pt.X - ptBegin.X;
Panel1.Top := pt.Y - ptBegin.Y;
end;
end;
の部分でImageではなくPanelの座標X・Yを変化させます。
KHE00221さん
procedure TForm1.FormCreate(Sender: TObject);
のところで
TForm1はFormCreateという名前のメンバーを含んでいません
と出ます。
これは何か入力忘れですか?
maru3さん
Panelの上にImageをちゃんと乗せてるんですけど動かないですね。
あとImageを読み込んでもpanelで画像が見えないです。
それでpanelだけが動き、画像が見える状態です。
その出てきた画像をクリックするとpanelが消えてしまいます。
これはどうしたらいいでしょうか?
PanelやImageのコンポーネントをどのように配置していますが。
アイコンのダブルクリックですか?
この場合ターゲットがForm1の場合、Form1に別々に配置されます。
これを動かして「上に乗せる」と上記のようなことになるでしょう。
まず、Panel1をクリックで選択し、そこでImageのアイコンをダブルクリックするか、
アイコンをシングルクリックして、Panelの上でクリックして配置してみてください。
maru3さん
すみません。
読み込んだ画像をクリックじゃなく動かそうとするとpanelが消えます。
maru3さん
出来ました!
本当にありがとうございました!
設計時に、Imageに画像を読み込んでいますか。
また、
設計時にPanelを移動させるとPanelと共にImageが動きますか???
新規アプリケーションでPanelをひとつとImaegeをひとつで
テストしてみてください。
今はボタンをクリックすると画像の選択になり決定すると画像が表示されるようになってます。画像はちゃんと動きます。
同様にボタンなども実行時に移動できますよ!
また、少し工夫すると右ドラッグなどでPanelのサイズ変更もできますよ!
maruさん
今imageを5つ置いて、やってみてるんですが同じようにプログラムを作ったのにimage1しか移動しないんですがどんなミスが考えられるか分かりますか?
すみません。
間違い見つかり解決しました。
たびたびすみません。
maru3、よかったらmaru3の教えてくれた「右ドラッグなどでPanelのサイズ変更」も教えていただいてよろしいですか?
画像サイズによってpanelのサイズを変えたいんですよね。
今画像読み込んでみたら、画像が小さすぎてpanelに空白が出来見栄えがよくないんです。
もしよろしかったらお願いします。
Panelの位置とサイズ変更ですが、下記のようにするとできます。
ただし、マウス位置がORGのサイズよりマイナスになるような場合のチックはしていませんので悪しからず。
新しいアプリケーション(テスト用)でまず確認してください。
PanelとImaegeはImaegeのAnchorsを指定するとOKでしょう。
private
{ Private 宣言 }
bDrag : boolean;
ptBegin : TPoint;
org_Wide,org_Height:Integer;
procedure TForm1.Panel1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
ptBegin := Point(X, Y);
bDrag := TRUE;
org_Wide := Panel1.Width;
org_Height:= Panel1.Height;
end;
procedure TForm1.Panel1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
bDrag := FALSE;
end;
procedure TForm1.Panel1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
var
pt:Tpoint;
begin
if bDrag = TRUE then
begin
pt := Form1.ScreenToClient(Panel1.ClientToScreen(Point(X, Y)));
if Shift = [ssLeft] then
begin
Panel1.Left := pt.X - ptBegin.X; //横方向
Panel1.Top := pt.Y - ptBegin.Y; //縦方向
end
else if Shift = [ssRight] then
begin
Panel1.Width := (org_Wide - (Panel1.Left - (pt.X - ptBegin.X))); //幅の変更
Panel1.Height:= (org_Height- (Panel1.Top - (pt.Y - ptBegin.Y))); //高さの変更
end;
end;
end;
KHE00221さん
procedure TForm1.FormCreate(Sender: TObject);
のところで
TForm1はFormCreateという名前のメンバーを含んでいません
と出ます。
これは何か入力忘れですか?
本気で言っているのなら・・・・・
Formをダブルクリックすると FormCreate って出来るから
そこに
Image1.Parent := Panel1;
Image1.Align := alClient;
Image1.OnMouseDown := MouseDown;
Panel2.OnMouseDown := MouseDown;
を記述して、(オブジェクトインスペクターで直接設定してもいいけど)
【謎】
FormCreateしらないで初期化処理はどこに書いていたんだろう・・・
DELPHIやり始めて1一週間とかなのか・・・
maru3さん
イメージの移動やパネルのサイズ変更は作ることが出来ました。
しかし、新たな問題が出てきてしまいました。
image1とimage2があった場合に画像が重なるとどうしてもimage2が上に来てしまいます。三つあった場合にはimage3が一番上に来てしまいます。
移動した画像が一番上にくるように出来ますか?
KHE00221さん
すみません。
まだ、全然わかってないです。
image1を最前面にしたければ、image1.BringToFrint で、いいような気がする
> まだ、全然わかってないです。
Delphiに対する勉強不足は否めないけども、
[何]に対して、[どこ]が[どう]わかんないのか書こうよ。
エラーになる理由なのか、KHE00221さんの言っている意味がわからないとか。
アプリを新規作成してFromCreateを実装したことが
ないのかもよ。
誰かの引き継ぎ仕事とかだと、こういうすごい理解度になったりするから
>>元投稿者さん
DelWiki - リンク/初心者
http://delwiki.info/?%A5%EA%A5%F3%A5%AF%2F%BD%E9%BF%B4%BC%D4
このあたりで勉強してみてください。
ofzさん
これからは気をつけます。
すみませんでした。
Fusaさん
勉強してみます。
ありがとうございます。
ツイート | ![]() |