[FMX]FMX 编写 Windows 平台下 DLL 需要解决的两个问题小结

1、在 FMX.Platform.Win 中,平台退出时,没有正确释放 FApplicationHWND 窗口,这样子造成模块释放后,窗口依然存在,所以这个需要修改 FMX.Platform.Win 的代码,以修正这一问题;

2、在 FMX.Forms.Win 中, 平台退出时,没有正确释放 FTimerActionHandle 这个定时器,造成模块释放后,试图执行这个定时器对应的代码,然后就出现了 AV 错误。而这个定时器的释放代码,官方竟然放到了 TApplication.Terminate 里,而我们 FreeLibrary 并不会调用它,结果就 Game Over 了。解决办法就是在释放这个DLL前调用下 Application.Terminate,不过这样子的结果是如果我们想解决双窗口的问题,就不能这么调用。问题就是这样子,先提出来吧。临时解决办法:

  • 找到 FMX.Platform.Win 单元,找到 TPlatformWin.Destroy 这个析构函数,在前面增加下面的代码:
      while FTimerData.Count>0 do
        DestroyTimer(FTimerData[FTimerData.Count-1].TimerHandle);

    通过循环干掉所有残留的定时器解决掉第二个问题。然后在这个函数的结尾,加入下面的代码:

    if FApplicationHWND<>0 then
        Winapi.Windows.DestroyWindow(FApplicationHWND);

    干掉应用程序窗口,解决前面提到的第一个问题。

当然,这个解决方案是临时的,等待官方的解决方案吧。

[更新]

1、对于第一处修正,我觉得更佳的解决方案是调用Terminate,然后修改 Terminate 函数中 FMultiTouchManager.Free 为  if Assigned(FMultiTouchManager) then
FreeAndNil(FMultiTouchManager);

2、对于 DLL,如果 FApplicationHWND 与主程序的不一致,也就是出现双任务的情况下,上面的代码没有问题,但如果是同一个窗口,那麻烦就大了,后一句会造成程序退出,所以实际上需要进行额外的处理,这个会在QPlugins的 QPlugins_FMX_FormService里处理,这种问题最终还需要交给官方去解决。

分享到: