如何让用户在表单上移动或拖动按钮?

3

我有一个表单,我已经通过编程方式创建了一个按钮,就像这样:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
  Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);        
  private
    FTableButton : TButton;       
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  if not Assigned(FTableButton) then begin
    FTableButton := TButton.Create(self);
    FTableButton.Parent := self;       
  end;
end;    

end.

如何让用户通过拖动在表单上移动 FTableButton


1
这不是一个编写代码或设计的服务。你需要自己付出一些努力。如果你遇到了特定的问题,可以向我们展示你的问题,我们会尽力帮助你。如果你不知道如何拖放,请搜索一下谷歌,那里有很多相关的资料。 - Dsm
1
这是一个编程项目,而不是一个关于编程问题的专门问题。 表面上看,这个问题很简单,但实现它的解决方案需要利用许多不同的工具。 这种类型的问题是离题的-你真正想要的似乎是教程或短期课程。 如果您想在这里提问,您需要将此问题分解为更小的部分-找出每个步骤达到最终目标,并询问您卡住的特定位置。 - J...
这可能是一个不错的起点 控件中的拖放 - J...
@J... 如果我要分解这个问题,那么第一个问题就是程序生成了一个可以在用户点击按钮时拖动的东西。 - user7262582
@Not_Lucas 我已经编辑了你的问题,将范围大大缩小到如何在表单上移动控件的一个问题。在 Stack Overflow 上的问题通常应该是这种类型 - 非常专注和具体的问题。在处理项目时,您真的应该尝试将其分解为微步骤 - 这将有助于您的开发,并使您考虑每个部分如何适合整体。 - J...
显示剩余12条评论
1个回答

4
通过实现控件的OnMouseDownOnMouseMoveOnMouseUp事件,您可以允许用户像这样移动它:
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);        
  private
    FTableButton : TButton;
    FTableButtonDragging : boolean;
    FMouseDownLocation : TPoint;
    FButtonStartingLocation : TPoint;
    procedure TableButtonMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure TableButtonMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure TableButtonMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  if not Assigned(FTableButton) then begin
    FTableButton := TButton.Create(self);
    FTableButton.Parent := self;
    FTableButton.Caption := 'I am New';
    FTableButton.OnMouseDown := TableButtonMouseDown;
    FTableButton.OnMouseMove := TableButtonMouseMove;
    FTableButton.OnMouseUp := TableButtonMouseUp;
  end;
end;

procedure TForm1.TableButtonMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  FTableButtonDragging := true;
  FMouseDownLocation := Mouse.CursorPos;
  FButtonStartingLocation := TPoint.Create(FTableButton.Left, FTableButton.Top);
end;

procedure TForm1.TableButtonMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  if FTableButtonDragging then begin
    FTableButton.Left := FButtonStartingLocation.X + (Mouse.CursorPos.X - FMouseDownLocation.X);
    FTableButton.Top := FButtonStartingLocation.Y + (Mouse.CursorPos.Y - FMouseDownLocation.Y);
    FTableButton.Invalidate;
  end;
end;

procedure TForm1.TableButtonMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  FTableButtonDragging := false;
end;

end.

这里我们向表单中添加了三个新程序:
 procedure TableButtonMouseDown(Sender: TObject; Button: TMouseButton;
                                Shift: TShiftState; X, Y: Integer);
 procedure TableButtonMouseMove(Sender: TObject; Shift: TShiftState; 
                                X, Y: Integer);
 procedure TableButtonMouseUp(Sender: TObject; Button: TMouseButton;
                              Shift: TShiftState; X, Y: Integer);

我们已将这些过程指定为新的FTableButton事件的处理程序:
FTableButton.OnMouseDown := TableButtonMouseDown;
FTableButton.OnMouseMove := TableButtonMouseMove;
FTableButton.OnMouseUp := TableButtonMouseUp;

单击按钮时,您需要存储控件的位置和鼠标放置单击时的鼠标位置,以及鼠标当前是否按下。为此,使用三个新字段:
FTableButtonDragging : boolean;
FMouseDownLocation : TPoint;
FButtonStartingLocation : TPoint;

当移动鼠标时,您可以根据控件的原始位置和当前鼠标位置与单击时的鼠标位置之间的差异来更新控件的位置。

你需要小心OnClick事件。这允许你移动按钮,但不能点击它(否则它总是会被点击 - 不太确定哪个)。在实践中,你可能需要额外的状态来指示已点击但尚未移动或者需要一个额外的按钮来启用移动。 - Dsm
当然。我这里不是在写教程 - 写实际代码时总有无数需要注意的事情。这只是一个最简示例,以帮助OP解决困境。 - J...
好的,所以我稍微修改了一下这段代码,使得表格的名称根据已经生成的表格数量来命名{Table(i),其中i每次递增},现在我正在尝试允许用户多次按按钮来生成更多的表格,但是我不确定应该使用什么循环,因为没有条件,例如点击一次后允许再次点击以生成另一个表格,我可以使用。在当前状态下,点击一次后就无法再次点击。 - user7262582
@Not_Lucas 听起来像是另一个问题的话题...然而,我建议你在这个阶段尝试学习一些基础知识。你仍然卡在基础上。花些时间通过教程来掌握对象创建、生命周期管理、值类型与引用类型等概念。你现在想要跑步,但你还没学会走路,这会让你陷入困境。 - J...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接