【问题标题】:How to drag a borderless FMX form on the screen through another object?如何通过另一个对象拖动屏幕上的无边框 FMX 表单?
【发布时间】:2013-10-05 11:09:35
【问题描述】:

我正在尝试制作一个可在屏幕上拖动的表单,即我可以抓住它并在屏幕上移动它。它是透明的并且没有边框,但是图像可以作为其他控件的背景。我想使用图像的事件来控制表单的拖动。我怎样才能做到这一点?

我发现有这个 TDragObject 参数的 DragEnter、DragLeave、DragStart 方法,我不知道。

有人可以帮忙吗?

【问题讨论】:

  • Perform 包含在哪个单元中,因为它不在 WinAPI.Windows、WinAPI.Messages 或 Windows 中。
  • Perform 是 TControl 的一个方法。与 SendMessage 类似,但它直接将消息传递给 WindowProc。
  • 好的,但我似乎无法在 FMX 中为它找到一个单元......我有这些在使用中; WinAPI.Windows,WinAPI.Messages,Windows,System.SysUtils,System.Types,System.Rtti,System.Classes,System.UITypes,System.Variants,System.Math,FMX.Types,FMX.Controls,FMX.Forms, FMX.Dialogs、FMX.Layouts、FMX.Objects、FMX.ListBox、FMX.Edit、FMX.Effects、FMX.TreeView、FMX.Grid、FMX.TabControl、FMX.Memo、Data.Bind.EngExt、Fmx.Bind。 DBEngExt、Data.Bind.Components、FMX.Ani;
  • 那是我的错,我没有注意到 firemonkey 标签。链接的问题适用于 Windows。 windows可以用winapi.windows中的SendMessage,其他的就不知道了。

标签: delphi user-interface firemonkey delphi-xe3


【解决方案1】:

基本上你必须手动完成。

这是一些来自表单的 delphi/windows 代码,上面有透明图像 (TransImage),没有边框等 事件在 Image 的形式中,所以 Top & Left 指的是 TMainScanForm.Top/Left。

这将使用图像事件来拖动您的表单以检测点击和移动

...

// Mouse Drag Control
MouseDown: Boolean;
TopLeft,
MouseStart: TPoint;

...

procedure TMainScanForm.TransImageMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  MouseDown := (Button = mbLeft);
  if MouseDown then
  begin
    MouseStart.X := X;
    MouseStart.Y := Y;
    TopLeft := ClientToScreen(MouseStart);
    TopLeft.X := TopLeft.X - X;
    TopLeft.Y := TopLeft.Y - Y;
    end;
end;

procedure TMainScanForm.TransImageMouseMove( Sender: TObject;
                                  Shift: TShiftState;
                                  X, Y: Integer);
var
  NewPoint: TPoint;
begin
  if MouseDown  then
  begin
    NewPoint.X := X;
    NewPoint.Y := Y;
    NewPoint := ClientToScreen(NewPoint);    // On Screen
    NewPoint.Y := NewPoint.Y - MouseStart.Y; // New Onscreen
    NewPoint.X := NewPoint.X - MouseStart.X;
    Top := NewPoint.Y;
    Left := NewPoint.X;
    Refresh;
  end;
end;

procedure TMainScanForm.TransImageMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  MouseDown := False;
end;

【讨论】:

  • 很聪明,我过几天试试看。
  • 为什么在更改表单位置后会有Refresh 调用?当他们的位置改变时,他们需要强制重新绘制 FMX 表格的某些特殊性吗?
  • 这段代码是为 VCL 编写的。这对 Firemonkey 来说不是一个好的解决方案。它在快速鼠标移动时失败,如果鼠标光标靠近表单边缘则失败。 Firemonkey 中的鼠标事件(向下/移动/向上)与 VCL 几乎不同。
  • @mh 我确实声明它是 windows - 这只是为了举例说明它是如何完成的。如果它需要适应 FM,那就错了。无论您单击何处,都适用于 Windows。至于刷新 TLama,此窗口/图像上还有很多其他控件,并且“表观窗口”不是矩形的。原来是5年前写的,只是复制粘贴作为例子,放在那里一定是有原因的!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多