Jump to content
Al T

FMX version of Vcl.Controls.TWinControl.CreateParented ?

Recommended Posts

I'm trying to convert VCL to FMX...

 

https://github.com/War3Evo/RMSVST3/blob/Delphi-11.0/AthenaVST3/VST3SDK/UVST3Controller.pas#L304-L311

 

function TVST3Controller.CreateForm(parent:pointer):TForm;
VAR FeditorFormClass:TFormClass;
begin
  FeditorFormClass:=GetEditorClass;
  if FeditorFormClass = NIL then FeditorFormClass:=GetPluginInfo.PluginDef.ecl;
  if FeditorFormClass = NIL then result:=NIL
  else result:=FeditorFormClass.CreateParented(HWND(parent));
end;

 

 

Is there a way to do this in FMX?

 

Thanks in advance!

Edited by Al T
actually not solved yet

Share this post


Link to post

class? function TVST3Controller.GetEditorClass:TForm;?
begin
  result:=NIL;
end;

function TVST3Controller.CreateForm(aParent: TForm):TForm;  //pass 
VAR FeditorForm:TclassedForm;//
..
  else result:=FeditorFormClass.CreateParented(aParent);//HWND(parent));  // HWND not in FMX 

FMX doesn't use windows handles AFAIK.   It's useful to know that FMX does not have a TWinControl. 

Not liking that these are not class methods. 

Pat     

 

 

Share this post


Link to post
19 hours ago, Pat Foley said:


class? function TVST3Controller.GetEditorClass:TForm;?
begin
  result:=NIL;
end;

function TVST3Controller.CreateForm(aParent: TForm):TForm;  //pass 
VAR FeditorForm:TclassedForm;//
..
  else result:=FeditorFormClass.CreateParented(aParent);//HWND(parent));  // HWND not in FMX 

FMX doesn't use windows handles AFAIK.   It's useful to know that FMX does not have a TWinControl. 

Not liking that these are not class methods. 

Pat     

 

 

The only problem is that this is a Plugin for a Windows DAW that would be passing the handle of the Window or View.   I need to be able to handle HWND.

 

It will also support Mac and Linux DAWs.

Edited by Al T

Share this post


Link to post
6 hours ago, Al T said:

The only problem is that this is a Plugin for a Windows DAW that would be passing the handle of the Window or View.   I need to be able to handle HWND.

The only HWND available in FMX comes from the TForm itself.  Child controls do not have their own HWNDs.  You can get the Form's HWND by using either WindowHandleToPlatform() or FormToHWND() in the FMX.Platform.Win unit.  Otherwise, if you want a child control that has an HWND, you will have to create it yourself using the Win32 API CreateWindow/Ex() API directly.

Edited by Remy Lebeau

Share this post


Link to post
On 11/16/2022 at 11:54 AM, Remy Lebeau said:

The only HWND available in FMX comes from the TForm itself.  Child controls do not have their own HWNDs.  You can get the Form's HWND by using either WindowHandleToPlatform() or FormToHWND() in the FMX.Platform.Win unit.  Otherwise, if you want a child control that has an HWND, you will have to create it yourself using the Win32 API CreateWindow/Ex() API directly.

I'm starting to get fed up with FMX... since the VCL version works just fine..

 

I was hoping to convert the VCL to FMX so that I can start using Skia4Delphi....

 

I've got the component running without errors... but since I used FeditorFormClass.Create(NIL); instead of being able to use FeditorFormClass.CreateParented(HWND(parent)); ........ It just shows a blank screen with no form on it!

 

I hate to have to figure out CreateWindowEx just so that I can create a parented FMX version 😞

 

It looks like I've got many more days of scratching my head and beating the walls.

 

I can only imagine a large project converting from VCL to FMX... the enormous feat that would be.

 

Share this post


Link to post
On 11/16/2022 at 11:54 AM, Remy Lebeau said:

The only HWND available in FMX comes from the TForm itself.  Child controls do not have their own HWNDs.  You can get the Form's HWND by using either WindowHandleToPlatform() or FormToHWND() in the FMX.Platform.Win unit.  Otherwise, if you want a child control that has an HWND, you will have to create it yourself using the Win32 API CreateWindow/Ex() API directly.

I did find FMX.Controls.Win which isn't in the online documentation.

 

Here is this:

 

  { TWinControl }
  /// <summary>
  ///  Wrapper for FMX.Controls.TControl for using native controls
  /// </summary>
  TWinControl = class(TControl)
  private
    FWindowProc: TWndMethod;
  private
    FParentWindow: HWND;
    FWinControls: TList;
    FDefWndProc: Pointer;
    FHandle: HWND;
    FObjectInstance: Pointer;
    function PrecedingWindow(const Control: TWinControl): HWND;
    procedure SetParentWindow(const Value: HWND);
    procedure UpdateShowing;
  protected
    /// <summary>
    ///   Return HWND handle to the component
    /// </summary>
    function GetHandle: HWND; virtual;
    /// <summary>
    ///   Set the FMX parent to the component
    /// </summary>
    procedure SetParent(const AParent: TFmxObject); reintroduce; virtual;
    /// <summary>
    ///   Return the parent
    /// </summary>
    function GetParent: TFmxObject; virtual;
    /// <summary>
    ///   WndProc procedure for this control
    /// </summary>
    procedure WndProc(var Message: TMessage); virtual;
    /// <summary>
    ///  Create native WindowHandle for control
    /// </summary>
    procedure CreateHandle; virtual;
    /// <summary>
    ///   Fill the structure using default parameters
    /// </summary>
    procedure CreateParams(var Params: TCreateParams); virtual;
    /// <summary>
    ///   Abstract method that would be call in CreateHandle method
    /// </summary>
    procedure CreateWnd; virtual; abstract;
    /// <summary>
    ///   Destroy the handle and all child handles if it exist
    /// </summary>
    procedure DestroyHandle; virtual;
    /// <summary>
    ///   Call Win API method for destroing handle from window
    /// </summary>
    procedure DestroyWindowHandle; virtual;
    /// <summary>
    ///   Return parents handle if exist. In other case return components handle
    /// </summary>
    function GetTopParentHandle: HWND;
    /// <summary>
    ///   Procedure for calling MakeObjectInstance
    /// </summary>
    procedure MainWndProc(var Message: TMessage);
    /// <summary>
    ///   Pointer to default WndProc
    /// </summary>
    property DefWndProc: Pointer read FDefWndProc write FDefWndProc;
    /// <summary>
    ///   Property for providing acceess to FHandle field
    /// </summary>
    property WindowHandle: HWND read FHandle write FHandle;
    /// <summary>
    ///   Method for sync Bounds between FMX and native control.
    /// </summary>
    procedure DoMatrixChanged(Sender: TObject); override;
    /// <summary>
    ///   Method for process of MouseActivate message
    /// </summary>
    procedure DoMouseActivate; virtual;
    /// <summary>
    ///   method for getting decision about focus setting
    /// </summary>
    procedure DoSetFocus; virtual;
  public
    constructor Create(AOwner: TComponent); overload; override;
    constructor CreateParented(ParentWindow: HWND);
    class function CreateParentedControl(ParentWindow: HWND): TWinControl;
    destructor Destroy; override;
    function HandleAllocated: Boolean;
    procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); reintroduce; virtual;
    procedure UpdateControlState;
    property Handle: HWND read GetHandle;
    property ParentWindow: HWND read FParentWindow write SetParentWindow;
    /// <summary>
    ///   Call Win API method update
    /// </summary>
    procedure Update; virtual;
    property WindowProc: TWndMethod read FWindowProc write FWindowProc;
    property Parent: TFmxObject read GetParent write SetParent;
  end;

Would this work and if so, how do incorporate this into my FMX project?

 

Edited by Al T

Share this post


Link to post
On 11/19/2022 at 2:42 PM, Al T said:

I'm starting to get fed up with FMX... since the VCL version works just fine..

FMX is not like VCL. It is close enough that a lot of code can be easily migrated over, but different enough that you can't just expect things will keep working as they have. I'd suggest doing some work in FMX before trying to convert a VCL project to FMX, so you know what to expect. In this case, it looks to me like you will need to create your own window to overlay over your fmx form so that you can use your DAW output there. This would be similar to how the web browser control works, so you may want to look at the source code for that.

  • 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

×