Основная программа, над которой мы работаем, полностью разработана с использованием VCL, довольно большой и частично около 20 лет. В следующей версии он получит более современный пользовательский интерфейс с учетом рекомендаций UWP и сенсорного управления.
Поскольку мы уже начали разработку приложений, мы подумали о создании общей инфраструктуры с FMX, которую можно использовать на разных платформах. В версии для Windows мы хотим интегрировать большинство форм VCL, потому что переопределение их всех не стоит для нас. Также версия Windows будет иметь гораздо больше функциональности и поддержки для наших старых продуктов. Поэтому мы хотим переработать только те части приложения, которые также будут частью мобильной версии.
Сначала мы подумали о том, чтобы разделить приложение на два отдельных исполняемых файла для Windows. Но в нашем новом дизайне пользовательского интерфейса мы не хотим использовать модальные диалоги.
Поэтому мы хотели бы использовать контейнер FMX, в который могут быть встроены формы VCL.
Что я сделал
В моем проекте я создал приложение для нескольких устройств FMX с основной формой и библиотекой DLL, которая содержит форму VCL. DLL экспортирует функции для создания и уничтожения формы VCL и функцию, которая возвращает дескриптор созданной формы VCL.
В основной форме приложения FMX загружается DLL и создается форма VCL. После получения дескриптора формы VCL она встраивается в основную форму путем вызова функции SetParent()
API Win32:
HWND vclFormHandle = GetVclFormHandleFromDll();
HWND fmxFormHandle = WindowHandleToPlatform(Handle)->Wnd;
SetParent(vclFormHandle, fmxFormHandle);
Вопросы
Встроенной формой VCL можно управлять с помощью мыши. Также возможно редактирование текста с клавиатуры. Но переключение между элементами управления с помощью клавиши Tab или выполнение нажатия кнопки с помощью клавиши Return не работает. Чтобы это работало в VCL Form, я добавил хук, подобный этому:
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 Form в качестве родительского, используя те же механизмы, она работает нормально, не делая лишних вещей).
Я знаю, что смешивание VCL и FMX не рекомендуется Embarcadero, но похоже, что описанный дизайн может работать. Кто-нибудь может увидеть опасности или подводные камни в этом?