将VCL表单嵌入FMX表单

时间:2018-06-28 14:02:37

标签: delphi firemonkey c++builder vcl

我们正在处理的主程序是完全由VCL设计的,它相当大,大约已有20年的历史了。在下一版本中,考虑到UWP准则和触摸控制,它将获得更现代的UI。

由于我们已经开始进行应用程序开发,因此我们考虑使用FMX构建通用框架,该框架可以在不同平台上使用。在Windows版本中,我们希望集成大多数VCL表单,因为重新实现它们对于我们来说并不值得。 Windows版本还将对我们的较旧产品提供更多功能和支持。因此,我们只想重新设计应用程序的那些部分,这些部分也应该是移动版本的一部分。

首先,我们考虑将应用程序分成两个独立的Windows可执行文件。但是在我们新的UI设计中,我们不想使用模式对话框。 因此,我们想使用可以嵌入VCL表单的FMX容器。

我所做的

在我的项目中,我用主窗体和包含VCL窗体的DLL创建了FMX多设备应用程序。 DLL导出创建和销毁VCL表单的函数,以及返回创建的VCL表单的句柄的函数。

在FMX应用程序的主窗体中,将加载DLL,并创建VCL窗体。获取VCL表单的句柄后,通过调用Win32 API的SetParent()函数将其嵌入到主表单中:

HWND vclFormHandle = GetVclFormHandleFromDll();
HWND fmxFormHandle = WindowHandleToPlatform(Handle)->Wnd;
SetParent(vclFormHandle, fmxFormHandle);

问题

  1. 可以用鼠标控制嵌入式VCL表单。此外,还可以使用键盘编辑文本。但是,通过 Tab 键在控件之间进行切换,或者通过 Return 键执行按钮单击均不起作用。为了使它在VCL表单中起作用,我添加了一个如下所示的钩子:

    HHOOK hKeyBoardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyBoardProc, HInstance, NULL);
    
    RESULT CALLBACK KeyBoardProc (int nCode, WPARAM wParam, LPARAM lParam)
    {
        // key event -> vcl controls       
        return CallNextHookEx(hKeyBoardHoof, nCode, wParam, lParam);
    }
    

    在深入探讨这个问题之前,我想问一下是否有人有更好的主意来转发这些关键事件? (将VCL表单设置为父表单时,使用相同的机制,无需做其他工作即可正常工作)。

  2. 我知道Embarcadero不建议混合使用VCL和FMX,但是看来所描述的设计可以工作。有人可以看到这样做的危险或陷阱吗?

0 个答案:

没有答案