I'm using the TFireMonkeyContainer
control to embed a Firemonkey form inside a VCL application. Initially, everything works fine. However, whenever I do something which triggers a TChangeTabAction
(to slide back and forth between tabs in a TTabControl
), the entire application freezes up and stops responding. Even Windows is unable to detect that it's not responding - the title bar is even frozen as well, and I have to either terminate the process from the IDE or from the Task Manager. The same form works perfectly when run purely in a Firemonkey application.
There's not much to it to reproduce the issue, no code at all, just form design.
TFireMonkeyContainer
control into IDE (or use dynamically)TFireMonkeyContainer
control on VCL main formTTabControl
and add a few tabsTActionList
TChangeTabAction
s into the Action List, one for each tabTChangeTabAction
s to the ButtonHow can I make the FMX TChangeTabAction
work as expected while embedding my form in this container?
EDIT
Just because the above explanation may not be enough for some, here's the form design of both forms:
VCL Form:
object frmVcl: TfrmVcl
Left = 0
Top = 0
Caption = 'frmVcl'
ClientHeight = 405
ClientWidth = 666
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object FireMonkeyContainer1: TFireMonkeyContainer
Left = 40
Top = 40
Width = 577
Height = 305
FireMonkeyForm = frmFiremonkey.Owner
end
end
FMX Form:
object frmFiremonkey: TfrmFiremonkey
Left = 0
Top = 0
Caption = 'Form1'
ClientHeight = 480
ClientWidth = 640
FormFactor.Width = 320
FormFactor.Height = 480
FormFactor.Devices = [Desktop]
DesignerMasterStyle = 0
object TabControl1: TTabControl
Position.X = 24.000000000000000000
Position.Y = 72.000000000000000000
Size.Width = 585.000000000000000000
Size.Height = 289.000000000000000000
Size.PlatformDefault = False
TabIndex = 0
TabOrder = 0
TabPosition = PlatformDefault
object TabItem1: TTabItem
CustomIcon = <
item
end>
IsSelected = True
Size.Width = 67.000000000000000000
Size.Height = 26.000000000000000000
Size.PlatformDefault = False
StyleLookup = ''
TabOrder = 0
Text = 'TabItem1'
end
object TabItem2: TTabItem
CustomIcon = <
item
end>
IsSelected = False
Size.Width = 68.000000000000000000
Size.Height = 26.000000000000000000
Size.PlatformDefault = False
StyleLookup = ''
TabOrder = 0
Text = 'TabItem2'
end
object TabItem3: TTabItem
CustomIcon = <
item
end>
IsSelected = False
Size.Width = 68.000000000000000000
Size.Height = 26.000000000000000000
Size.PlatformDefault = False
StyleLookup = ''
TabOrder = 0
Text = 'TabItem3'
end
end
object Button1: TButton
Position.X = 32.000000000000000000
Position.Y = 16.000000000000000000
Size.Width = 105.000000000000000000
Size.Height = 41.000000000000000000
Size.PlatformDefault = False
TabOrder = 2
Text = 'Button1'
OnClick = Button1Click
end
object ActionList1: TActionList
Left = 512
Top = 24
object ChangeTabAction1: TChangeTabAction
Category = 'Tab'
Tab = TabItem1
end
object ChangeTabAction2: TChangeTabAction
Category = 'Tab'
Tab = TabItem2
end
object ChangeTabAction3: TChangeTabAction
Category = 'Tab'
Tab = TabItem3
end
end
end
TFireMonkeyContainer
prevents the FMX application message loop from running, deferring to the VCL application message loop. The replacement Windows app service did nothing for the methods HandleMessage
(and returned false) or WaitMessage
, incorrectly assuming that since the FMX message loop never ran, they would never be called.
However, FMX's Application.ProcessMessages
method can be manually called, of course, and that calls into the Windows app service methods, running a while loop, which ended instantly. The tab transition code calls ProcessMessages
until the transition is complete, and since HandleMessage
did nothing but also processed no messages, the transition never continued, causing an infinite loop while it waited until it was done.
The latest commit in Github fixes this, as well as fixes a couple of related app service methods to behave more like the default FMX application service.