Panelを自由に移動するには?


初心者  2008-01-25 22:04:40  No: 29475

Panelを自由に動かすことは出来ますか?
Panelだけを動かしたいんですが、どうしてもウインドウ全部が動いてしまいます。
もし、Panelだけ動かすことが出来るようでしたら教えていただけますか?


ofZ  2008-01-25 23:10:27  No: 29476

> ウインドウ全部が動いてしまいます。

なんとなく、これでいいような推測回答
handle → Panel.Handle

というか、コードを記述せよ。


初心者  2008-01-26 19:53:26  No: 29477

すいません。
よく分からなくてネット上にあったサンプルを使ってみたらそうなってしまいました。

↓がそのサンプルです。
//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;


KHE00221  2008-01-26 20:07:58  No: 29478

フォームのバーと見せかけるならば・・・・

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が発生しないので

処理したい場合には無理だけど


KHE00221  2008-01-26 20:08:25  No: 29479

>ただドラック中のMouseDown

MouseMove


KHE00221  2008-01-26 20:14:57  No: 29480

サンプルのやつは

Perform だけだと Self.Perform になるので Panel2.Perform にしないと駄目だね

Panel1MouseDown は Pane1 じゃなくて その Form で実行されているから


初心者  2008-01-26 20:22:12  No: 29481

ありがとうございます。

最終的にはpanelの上にImageを貼り付けて、マウスで自由に移動できるようにしたいのですが、その場合のアドバイスも頂けると嬉しいです。


KHE00221  2008-01-26 20:28:57  No: 29482

サンプルのほうは

TPanelの上に乗せたTImageのOnMouseDown に 記述すれば移動するよ?

Captionに見せかけるほうは無理だけど

あとサンプルはサイズ変更に対応させてるんだね


KHE00221  2008-01-26 20:41:24  No: 29483

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;


初心者  2008-01-26 21:05:54  No: 29484

今やってみたんですけど、やっぱり最初と同じ状態になってしまいます。


それはね  2008-01-26 21:16:00  No: 29485

↑キミのやり方が悪いからだよ。


KHE00221  2008-01-26 21:24:14  No: 29486

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;


KHE00221  2008-01-26 21:26:26  No: 29487

1つのMouseDownで

TImage を乗せていない TPanel(Panel2) 
TImage を乗せた TPanel(Panel1)

ともに移動出来ます。


maru3  2008-01-26 21:39:10  No: 29488

どこかで見ましたが
こんなのでいかが?

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;


初心者  2008-01-26 22:33:39  No: 29489

KHE00221さん
教えていただいた通りにプログラムを作ってはみたんですがエラーが出てしまい実行できなかったです。
私の方で何か入力が足りないところとかがあるんですかね?

maru3さん
教えていただいたプログラムを試してみたところpanelは動きました。
しかし、imageは配置した場所から動かずpanelだけが動いてしまいます。
一緒に動かすにはどうしたらよいでしょうか?

お二方、教えていただいてよろしいですか?
何度も質問してしまいすみません。


KHE00221  2008-01-26 22:41:33  No: 29490

どこでどんなエラーが?


maru3  2008-01-26 22:46:56  No: 29491

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を変化させます。


初心者  2008-01-26 22:49:43  No: 29492

KHE00221さん

procedure TForm1.FormCreate(Sender: TObject);

のところで

TForm1はFormCreateという名前のメンバーを含んでいません

と出ます。
これは何か入力忘れですか?


初心者  2008-01-26 22:58:12  No: 29493

maru3さん

Panelの上にImageをちゃんと乗せてるんですけど動かないですね。

あとImageを読み込んでもpanelで画像が見えないです。
それでpanelだけが動き、画像が見える状態です。
その出てきた画像をクリックするとpanelが消えてしまいます。

これはどうしたらいいでしょうか?


maru3  2008-01-26 23:08:54  No: 29494

PanelやImageのコンポーネントをどのように配置していますが。
アイコンのダブルクリックですか?

この場合ターゲットがForm1の場合、Form1に別々に配置されます。
これを動かして「上に乗せる」と上記のようなことになるでしょう。

まず、Panel1をクリックで選択し、そこでImageのアイコンをダブルクリックするか、
アイコンをシングルクリックして、Panelの上でクリックして配置してみてください。


初心者  2008-01-26 23:09:33  No: 29495

maru3さん

すみません。
読み込んだ画像をクリックじゃなく動かそうとするとpanelが消えます。


初心者  2008-01-26 23:14:42  No: 29496

maru3さん

出来ました!
本当にありがとうございました!


maru3  2008-01-26 23:18:07  No: 29497

設計時に、Imageに画像を読み込んでいますか。
また、
設計時にPanelを移動させるとPanelと共にImageが動きますか???

新規アプリケーションでPanelをひとつとImaegeをひとつで
テストしてみてください。


初心者  2008-01-26 23:38:04  No: 29498

今はボタンをクリックすると画像の選択になり決定すると画像が表示されるようになってます。画像はちゃんと動きます。


maru3  2008-01-26 23:51:35  No: 29499

同様にボタンなども実行時に移動できますよ!
また、少し工夫すると右ドラッグなどでPanelのサイズ変更もできますよ!


初心者  2008-01-27 00:19:31  No: 29500

maruさん

今imageを5つ置いて、やってみてるんですが同じようにプログラムを作ったのにimage1しか移動しないんですがどんなミスが考えられるか分かりますか?


初心者  2008-01-27 00:27:08  No: 29501

すみません。
間違い見つかり解決しました。


初心者  2008-01-27 00:31:52  No: 29502

たびたびすみません。

maru3、よかったらmaru3の教えてくれた「右ドラッグなどでPanelのサイズ変更」も教えていただいてよろしいですか?
画像サイズによってpanelのサイズを変えたいんですよね。

今画像読み込んでみたら、画像が小さすぎてpanelに空白が出来見栄えがよくないんです。

もしよろしかったらお願いします。


maru3  2008-01-27 01:13:12  No: 29503

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  2008-01-27 09:33:10  No: 29504

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一週間とかなのか・・・


初心者  2008-01-27 22:10:20  No: 29505

maru3さん

イメージの移動やパネルのサイズ変更は作ることが出来ました。
しかし、新たな問題が出てきてしまいました。
image1とimage2があった場合に画像が重なるとどうしてもimage2が上に来てしまいます。三つあった場合にはimage3が一番上に来てしまいます。
移動した画像が一番上にくるように出来ますか?

KHE00221さん

すみません。
まだ、全然わかってないです。


ofZ  2008-01-27 22:44:41  No: 29506

image1を最前面にしたければ、image1.BringToFrint で、いいような気がする

> まだ、全然わかってないです。
Delphiに対する勉強不足は否めないけども、
[何]に対して、[どこ]が[どう]わかんないのか書こうよ。
エラーになる理由なのか、KHE00221さんの言っている意味がわからないとか。


Fusa  2008-01-28 18:55:00  No: 29507

アプリを新規作成してFromCreateを実装したことが
ないのかもよ。

誰かの引き継ぎ仕事とかだと、こういうすごい理解度になったりするから

>>元投稿者さん
DelWiki - リンク/初心者
http://delwiki.info/?%A5%EA%A5%F3%A5%AF%2F%BD%E9%BF%B4%BC%D4
このあたりで勉強してみてください。


初心者  2008-01-28 22:06:15  No: 29508

ofzさん

これからは気をつけます。
すみませんでした。

Fusaさん
勉強してみます。
ありがとうございます。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加