Reputation: 491
I'm attempting to create a custom TToolbar at run-time that floats over the form (below the control it is associated with).
My issue is that the process of floating and positioning the toolbar at creation creates a hideous flicker where it is initially drawn at the top-left of the monitor before being moved to my desired position on the form.
I cannot find a way to avoid this. Is there a way?
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;
References: - Create TToolbutton runtime - toolbutton with action created at runtime - Delphi - Create a custom TToolBar component
Upvotes: 1
Views: 416
Reputation: 21033
I am a little puzzled with your solution, so I provide my two takes on the subject. Specifically I don't understand why you are using ManualFloat()
and few lines later set the parent of the toolbar, which makes it non-floating.
Here is a solution for a floating toolbar, using ManualFloat()
.
The toolbar is floating above the form in its own temporary TCustomDockForm
,
at the given location.
The record needed by ManualFloat()
is setup for the final location, thus no flicker in the wrong place, and the control
is immediately correctly positioned.
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;
However, since you actually seem to want a non-floating toolbar, that is just
located anywhere you like on the form (and not in the default top of the form),
a better solution is to skip the ManualFloat()
altogether and just set the
Align
property of the toolbar to alNone
. This enables it to be moved anywhere
on the parent form.
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;
This gives you the same appearance as your own code, but omits the ManualFloat()
.
Finally, an image to show the appearances:
The bottom toolbar is created with Button4Click()
Upvotes: 1
Reputation: 491
Thanks @TomBrunberg for your suggestion.
What was needed to make it position over the form without any pre-drawing:
Revised code:
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;
Upvotes: 0