Jump to content
Sign in to follow this  
CHackbart

Firemonkey draw over native elements

Recommended Posts

Hi,

 

since this is not working properly since the beginning I thought I try to do the following. A TLayout component which helds a transparent borderless TForm. All the layout children are rendered in the form on run time, while the native control behind stays behind. This works fine, but I got stuck in the issue that if I resize the main form, the position of the transparent form won't be updated. I could solve this by a timer which checks the position in the background but this is not the best idea I guess. I added a small example which plays a video stream and draws a icon over the stream. Maybe somebody has an idea how to achieve this without a timer.

 

Christian

example.zip

 

 

Edited by CHackbart

Share this post


Link to post

Thanks for the link, but this only works on windows. In this particular case I need it on almost all platforms, starting on a Mac. Frankly using a Timer is not the worst thing, but I hate the idea of polling on a high frequency as well as the fact that even a 1ms interval would have a delay while moving the main window and updating the content. 

Bildschirmfoto_2021-11-04_um_19_48.png

Share this post


Link to post

Did you consider OnIdle?

 

As I understand it, the issue is when dragging the main form by the title bar, then the location of the TImage is not updated; not while changing the position and not even after the drag operation has ended.

 

Using OnIdle can be a replacement for the missing OnResizeEnd event. It should work on a Mac but may not be good enough, as it is not called while dragging.
 

procedure TfrmMain.FormActivate(Sender: TObject);
begin
  OnActivate := nil;

  FOSD := TImageLayout.Create(self);
  FOSD.Parent := self;
  FOSD.Align := TAlignLayout.Contents;
  FOSD.Visible := true;

  imgPlay.Parent := FOSD;
  FOSD.Active := true;

  MediaPlayer.FileName := 'D:\...\TestGif.gif';
  MediaPlayer.Play;

  Application.OnIdle := DoOnIdle;
end;

procedure TfrmMain.DoOnIdle(Sender: TObject; var Handled: Boolean);
begin
  if (Left <> OldLeft) or (Top <> OldTop) then
  begin
    Inc(IdleCounter);
    OldLeft := Left;
    OldTop := Top;
    Caption := IntToStr(IdleCounter);
    FOSD.UpdateView;
  end;
  Handled := True;
end;

 

Update: Are we  in search of an event that is triggered when the form is repositioned?

procedure TfrmMain.FormActivate(Sender: TObject);
begin
  ...
{
OnTimer is the one to beat.
OnResize fails.
public property TControl.OnResized is not available in 10.1 Berlin (I cannot test).
OnResizeEnd is priate to myself.
OnIdle is not triggered while relocating.
OnCanResize does not exist in FMX (works in VCL).
}

  Timer.Interval := 1;
//  Self.OnResize := FormResize;
//  Self.OnResizeEnd := FormResizeEnd;
//  Application.OnIdle := DoOnIdle;
  Timer.OnTimer := FormResize;
end;

procedure TfrmMain.FormResize(Sender: TObject);
begin
  if FOSD <> nil then
    FOSD.UpdateView;
end;

 

Test result: I don't know.
 

Edited by Gustav Schubert
after testing out timer

Share this post


Link to post
18 hours ago, Gustav Schubert said:

Are we  in search of an event that is triggered when the form is repositioned?

If so the test app can be simplified: MediaPlayer not needed. This topic has potential to become an interesting question. I wanted to reduce the amount of updates. Here we want frequent updates as the form is relocated, not resized. Resizing is not the problem. Correct me if I am wrong.

 

Share this post


Link to post

Yes of course, I just added the player to explain why I need this in particular. By reading the platform implementation for MacOS I found a solution which should work fine on all platforms:

 

The public SetBoundsF function which is part of the TCommonCustomForm is executed every time the window moved. 

procedure SetBoundsF(const ALeft, ATop, AWidth, AHeight: Single); override;

 

Christian

 

Edited by CHackbart
  • Thanks 1

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×