通过TFireMonkeyContainer在VCL应用程序中的FMX表单-应用程序冻结 [英] FMX form in VCL app via TFireMonkeyContainer - application freezing

查看:165
本文介绍了通过TFireMonkeyContainer在VCL应用程序中的FMX表单-应用程序冻结的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 TFireMonkeyContainer 控件将Firemonkey表单嵌入VCL应用程序中.最初,一切正常.但是,每当我执行触发TChangeTabAction的操作(在TTabControl中的选项卡之间来回滑动)时,整个应用程序就会冻结并停止响应.甚至Windows也无法检测到它没有响应-标题栏也被冻结了,我必须从IDE或任务管理器中终止该过程.当完全在Firemonkey应用程序中运行时,相同的形式也可以很好地工作.

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.

  1. TFireMonkeyContainer控件安装到IDE中(或动态使用)
  2. 创建新的VCL表单应用程序
  3. 仅在VCL主窗体上拖放一个TFireMonkeyContainer控件
  4. 在同一应用程序中创建新的FMX表单
  5. 将FMX表单分配给容器
  6. 在FMX表单中,放置TTabControl并添加一些标签页
  7. 在FMX表单中,放置一个新的TActionList
  8. 在操作列表中添加多个TChangeTabAction,每个选项卡一个
  9. 将每个标签分配给相应的操作之一
  10. 在FMX表单中,放置一个新按钮
  11. TChangeTabAction之一分配给按钮
  12. 运行应用程序
  13. 请注意,当您将鼠标移到按钮上时,UI会很好地响应
  14. 注意如何在没有问题的情况下手动切换选项卡
  15. 单击FMX表单上的按钮
  16. 请注意,UI如何不再响应,应用程序将继续运行
  1. Install TFireMonkeyContainer control into IDE (or use dynamically)
  2. Create new VCL Forms Application
  3. Drop only one TFireMonkeyContainer control on VCL main form
  4. Create new FMX Form within same application
  5. Assign the FMX form to the Container
  6. In the FMX form, drop a TTabControl and add a few tabs
  7. In the FMX form, drop a new TActionList
  8. Add multiple TChangeTabActions into the Action List, one for each tab
  9. Assign each tab to one of the corresponding actions
  10. In the FMX form, drop a new button
  11. Assign one of the TChangeTabActions to the Button
  12. Run the application
  13. Note how when you move the mouse over the button, the UI responds well
  14. Note how you can switch between tabs manually with no problem
  15. Click the button on the FMX form
  16. Note how the UI no longer responds and the application seizes to continue

将表单嵌入到此容器中时,如何使FMX TChangeTabAction正常工作?

How can I make the FMX TChangeTabAction work as expected while embedding my form in this container?

编辑

仅因为上面的解释可能还不够,下面是这两种形式的表单设计:

Just because the above explanation may not be enough for some, here's the form design of both forms:

VCL表格:

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表格:

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阻止FMX应用程序消息循环运行,从而推迟到VCL应用程序消息循环.替换的Windows应用程序服务对方法HandleMessage(并返回false)或WaitMessage没有任何作用,错误地假设由于FMX消息循环从未运行,因此它们将永远不会被调用.

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.

但是,当然可以手动调用FMX的Application.ProcessMessages方法,并且该方法调用Windows应用程序服务方法,并运行while循环,该循环立即结束.选项卡转换代码将调用ProcessMessages直到转换完成,并且由于HandleMessage不执行任何操作但也未处理任何消息,因此转换从未继续进行,从而导致无限循环,直到它完成为止.

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.

Github中的最新提交可以解决此问题,并修复了一些相关的应用程序服务行为类似于默认的FMX应用程序服务.

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.

这篇关于通过TFireMonkeyContainer在VCL应用程序中的FMX表单-应用程序冻结的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆