【问题标题】:Create floating TToolbar at run-time without flicker在运行时创建浮动 TToolbar 而不会闪烁
【发布时间】:2020-06-11 01:33:16
【问题描述】:

我正在尝试在运行时创建一个自定义 TToolbar,它浮动在表单上(在与之关联的控件下方)。

我的问题是,在创建时浮动和定位工具栏的过程会产生可怕的闪烁,它最初是在显示器的左上角绘制的,然后才被移动到表单上我想要的位置。

我找不到避免这种情况的方法。有什么办法吗?

procedure TMainForm.Button3Click(Sender: TObject);
var
  newToolbar : TToolbar;
  newButton : TToolButton;
begin
  newToolbar := TToolbar.Create(Self);

  newToolbar.Visible := False;

  newToolbar.ManualFloat( Rect( 0, 0, newToolbar.Width, newToolbar.Height ));

  newToolbar.Parent := Self;

  newToolbar.left := 100;
  newToolbar.Top  := 100;

  newToolbar.ShowCaptions := True;

  newButton := TToolButton.Create(Self);
  newButton.Parent := newToolbar;
  newButton.Caption := 'Test';

  newToolbar.Visible := True;
end;

参考资料: - Create TToolbutton runtime - toolbutton with action created at runtime - Delphi - Create a custom TToolBar component

【问题讨论】:

  • 你为什么要分配 ParentWindow?
  • 我还想看到minimal reproducible example。这样我们就可以轻松开始调试了。否则,我们很有可能尝试重新创建它并失败,浪费时间。例如,问题的出现可能只是因为您的程序中做出了其他选择。
  • @DavidHeffernan:该代码应该在任何应用程序中重现该问题
  • “应该”并不能说服我花时间制作应用程序。没关系。也许其他人会给你他们的时间。
  • @DavidHeffernan:我在三个应用程序中测试了它,包括一个完全空白的应用程序。所以它应该在任何应用程序中都可以工作(99% 的确定性),但我不能保证它会,也许我的 Delphi 设置中有一些问题......

标签: delphi


【解决方案1】:

我对您的解决方案有点困惑,因此我提供了我对这个主题的两个看法。具体来说,我不明白您为什么要使用 ManualFloat() 并且几行之后设置了工具栏的父级,这使得它不浮动。

这是一个浮动工具栏的解决方案,使用ManualFloat()。 工具栏以自己的临时TCustomDockForm 漂浮在表单上方, 在给定的位置。

ManualFloat()需要的记录是为最终位置设置的,因此不会在错误的地方闪烁,并且控制 立即正确定位。

procedure TForm1.Button3Click(Sender: TObject);
var
  newToolbar : TToolbar;
  newButton : TToolButton;
  p: TPoint;
begin
  newToolbar := TToolbar.Create(Self);

  // calculate position in screen coordinates for the floating toolbar
  p := ClientOrigin;
  p.Offset(100, 100);
  // and make it floating in final position
  newToolbar.ManualFloat( Rect(p.X, p.Y, p.X+NewToolbar.Width, p.Y+newToolbar.Height) );

  newToolbar.Visible := False; // really needed ?

  // Then create the toolbar buttons
  newToolbar.ShowCaptions := True;

  newButton := TToolButton.Create(self);
  newButton.Parent := newToolbar;
  newButton.Caption := 'Test';

  newToolbar.Visible := True;
end;

但是,由于您实际上似乎想要一个非浮动工具栏,那只是 位于表单上您喜欢的任何位置(而不是位于表单的默认顶部), 更好的解决方案是完全跳过 ManualFloat() 并设置 工具栏的Align 属性为alNone。这使它可以移动到任何地方 在父窗体上。

procedure TForm1.Button4Click(Sender: TObject);
var
  newToolbar : TToolbar;
  newButton : TToolButton;
begin
  newToolbar := TToolbar.Create(Self);
  newToolbar.Align := alNone; // constructor sets it to alTop

  newToolbar.Visible := False; // really needed ?

  newToolbar.Parent := Self;
  newToolbar.Left := 100;
  newToolbar.Top := 200;

  newToolbar.ShowCaptions := True;

  newButton := TToolButton.Create(self);
  newButton.Parent := newToolbar;
  newButton.Caption := 'Test';

  newToolbar.Visible := True; //
end;

这为您提供与您自己的代码相同的外观,但省略了ManualFloat()

最后,一张图片来展示外观:

底部工具栏是用Button4Click()创建的

【讨论】:

    【解决方案2】:

    感谢@TomBrunberg 的建议。

    在没有任何预绘图的情况下使其定位在表单上所需的条件:

    1. 在调用 ManualFloat 时将其置于屏幕外
    2. 在调用 ManualFloat 后将 Visible 设置为 false(因为 ManualFloat 将其设置为 true)

    修改后的代码:

    procedure TMainForm.Button3Click(Sender: TObject);
    var
      newToolbar : TToolbar;
      newButton : TToolButton;
    begin
      newToolbar := TToolbar.Create(Self);
    
      // Float with off-screen position
      newToolbar.ManualFloat( Rect( 0, -200, newToolbar.Width, newToolbar.Height - 200 ));
    
      // Must hide after ManualFloat call, as it resets Visible to true
      newToolbar.Visible := False;
    
      // Set parent so we can add buttons, sets props, etc.
      newToolbar.Parent := Self;
    
      // Move to desired position over form
      newToolbar.left := 100;
      newToolbar.Top  := 100;
    
      // Add our button content...
      newToolbar.ShowCaptions := True;
    
      newButton := TToolButton.Create(Self);
      newButton.Parent := newToolbar;
      newButton.Caption := 'Test';
    
      // Now we can show it
      newToolbar.Visible := True;
    end;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-16
      • 1970-01-01
      相关资源
      最近更新 更多