【问题标题】:Delphi - move control in runtime alike on design modeDelphi - 在设计模式下在运行时移动控制
【发布时间】:2011-10-20 14:30:51
【问题描述】:

大家好,

我尝试在运行时模式下使用鼠标在设计模式下移动我自己的组件。

在没有释放鼠标按钮之前,组件不会移动,此时会显示一个空框架并提示显示左上角位置。

我做了很多尝试,但直到现在都没有成功。

任何帮助

【问题讨论】:

    标签: delphi


    【解决方案1】:

    好吧,我会在这里发布。以下代码使用未记录的 WM_SYSCOMMAND 常量 $F012 并与 TWinControl 后代一起使用。

    请注意,它未记录在案,并且可能无法在未来版本的 Windows 上运行(如果他们决定使用 Windows API 中的任何其他内容),但它可以运行(在多个 Windows 版本上测试),并且它是移动运行时的组件。

    procedure TForm.YourComponentMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    const
      SC_DRAGMOVE = $F012;
    begin
      ReleaseCapture;
      YourComponent.Perform(WM_SYSCOMMAND, SC_DRAGMOVE, 0);
    end;
    

    大小调整也存在类似的魔法,即命令$F008

    procedure TForm.YourComponentMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    const
      SC_DRAGSIZE = $F008;
    begin
      ReleaseCapture;
      YourComponent.Perform(WM_SYSCOMMAND, SC_DRAGSIZE, 0);
    end;
    

    【讨论】:

    • 请注意,此方法仅适用于 TWinControl 派生类!
    • 你的神奇SC_DRAGSIZE实际上是SC_SIZE + WMSZ_BOTTOMRIGHT。例如,要从左上角调整大小,您可以使用SC_SIZE + WMSZ_TOPLEFT
    • @Sertac - 比我想象的要神奇得多 :) 但我仍然不明白为什么 MS 不记录它。恕我直言,这将对未来的 Windows 版本保持活力,因为他们肯定会在某些产品中使用它。
    • 这是用于移动和调整顶级窗口大小的相同消息。在窗口的深处,这些东西都是一样的(一个窗口,natch),因此 WM_SYSCOMMAND 支持 SC_DRAGMOVE 并支持顶级窗口类(真正的 TForm)和任何其他带有 win32 窗口句柄的 Delphi 控件也就不足为奇了。
    【解决方案2】:

    在我的网站 (http://neftali.clubdelphi.com/?p=269) 上,您可以找到一个名为 TSelectOnRuntime 的组件。您可以查看源代码并进行研究。这是一种在运行时选择、调整大小和移动组件的简单方法。

    Download the demo 并评估它是否对您有效(包括组件源、演示源和编译的演示)。

    问候。

    【讨论】:

      【解决方案3】:

      如果我认为您正在尝试在运行时移动控件,那么这里有一些您可以根据需要使用(并且可能稍微修改)的代码:

      var
      MouseDownPos, LastPosition : TPoint;
      DragEnabled,Resizing : Boolean;
      
      
      procedure TForm1.ControlMouseDown(Sender: TObject;
        Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
      begin
           MouseDownPos.X := X;
           MouseDownPos.Y := Y;
           DragEnabled := True;
      end;
      
      //handle dragging of controls
      procedure TForm1.ControlMouseMove(Sender: TObject;
        Shift: TShiftState; X, Y: Integer);
      begin
           if DragEnabled then
           begin
                if Sender is TControl then
                begin
                      TControl(Sender).Left := TControl(Sender).Left + (X - MouseDownPos.X);
                      TControl(Sender).Top := TControl(Sender).Top + (Y - MouseDownPos.Y);
                end;
           end;
      end;
      

      要调整控件的大小,您可以使用以下内容:

      procedure TForm1.ControlMouseMove(Sender: TObject;
        Shift: TShiftState; X, Y: Integer);
      var cntrl : TControl;
      begin
          cntrl := Sender as TControl;
      if ((cntrl.Width - X) < 15) and ((cntrl.Height - Y) < 15) then
             cntrl.Cursor := crSizeNWSE
          else cntrl.Cursor := crDefault;
          if Resizing then
          begin
              cntrl.Width := cntrl.Width + (X - LastPosition.X);
              LastPosition.X := X;
              cntrl.Height := cntrl.Height + (Y - LastPosition.Y);
              LastPosition.Y := Y;
          end;
      end;
      
      procedure TForm1.ControlMouseDown(Sender: TObject;
        Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
      var cntrl : TControl;
      begin
          if ((cntrl.Width - X) < 15) and ((cntrl.Height - Y) < 15) then
          begin
              LastPosition.X := X;
              LastPosition.Y := Y;
              Resizing := True;
          end;
      end;
      

      对此的扩展可能会捕捉到网格。此代码可能需要稍作修改。

      【讨论】:

      • 释放捕获;最好从我的测试。但是我丢失了鼠标消息。例如不会得到 mouseup 消息。
      【解决方案4】:

      有一个名为TSizeCtrl 的组件可以让您在运行时移动控件。您可以在Torry's找到源代码here或下载组件。

      可以这样使用:

      SizeCtrl1 := TSizeCtrl.Create(MyForm);
      SizeCtrl1.GridSize := 20;
      SizeCtrl1.Enabled := True;
      SizeCtrl1.RegisterControl(MyControl);
      SizeCtrl1.AddTarget(MyControl);
      

      这将让您拖动MyControl 并调整其大小。它在拖动时绘制一个框架并提供调整大小的句柄。

      【讨论】:

      • 两个链接都坏了
      猜你喜欢
      • 1970-01-01
      • 2012-04-04
      • 1970-01-01
      • 1970-01-01
      • 2011-08-29
      • 2020-03-02
      • 1970-01-01
      • 2010-11-09
      • 2011-05-18
      相关资源
      最近更新 更多