Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Как создать универсальную функцию для отображения диалоговых окон с сообщениями в Delphi FMX: пример на Pascal с обработкой различных типов кнопок и иконок.

Delphi , Программа и Интерфейс , Диалоги и Фреймы

Универсальная функция для отображения диалоговых окон в Delphi FMX

В разработке кросс-платформенных приложений с использованием Delphi FireMonkey (FMX) часто возникает необходимость выводить диалоговые окна с сообщениями. Однако, в отличие от Windows, на мобильных платформах (Android/iOS) подход к обработке таких диалогов должен быть асинхронным, чтобы не блокировать основной поток приложения.

Проблема блокирующих диалогов

Как отмечают эксперты в комментариях к исходному вопросу, блокировка основного потока на Android приведёт к аварийному завершению приложения через несколько секунд. Это фундаментальное отличие мобильных платформ от Windows, где блокирующие диалоги работают корректно.

Рассмотрим решение, которое будет работать корректно на всех платформах, включая мобильные.

Универсальная функция для отображения сообщений

type
  TDialogCallback = procedure(Result: TModalResult) of object;

procedure ShowGenericMessage(const MessageText: string; 
                           Icon: Integer; 
                           Callback: TDialogCallback = nil);
var
  DialogType: TMsgDlgType;
  Buttons: TMsgDlgButtons;
  DefaultButton: TMsgDlgBtn;
begin
  if MessageText = '' then Exit;

  // Определяем тип диалога по значку
  DialogType := mtCustom;
  if (Icon and MB_ICONQUESTION) = MB_ICONQUESTION then
    DialogType := mtConfirmation
  else if (Icon and MB_ICONWARNING) = MB_ICONWARNING then
    DialogType := mtWarning
  else if (Icon and MB_ICONERROR) = MB_ICONERROR then
    DialogType := mtError
  else if (Icon and MB_ICONINFORMATION) = MB_ICONINFORMATION then
    DialogType := mtInformation;

  // Определяем кнопки
  if (Icon and MB_YESNO) = MB_YESNO then
  begin
    Buttons := [TMsgDlgBtn.mbYes, TMsgDlgBtn.mbNo];
    DefaultButton := TMsgDlgBtn.mbNo;
  end
  else if (Icon and MB_OKCANCEL) = MB_OKCANCEL then
  begin
    Buttons := [TMsgDlgBtn.mbOK, TMsgDlgBtn.mbCancel];
    DefaultButton := TMsgDlgBtn.mbCancel;
  end
  else
  begin
    Buttons := [TMsgDlgBtn.mbOK];
    DefaultButton := TMsgDlgBtn.mbOK;
  end;

  // Отображаем диалог
  TDialogService.MessageDialog(MessageText, DialogType, Buttons, DefaultButton, 0,
    procedure(const AResult: TModalResult)
    begin
      if Assigned(Callback) then
        Callback(AResult);
    end);
end;

Пример использования

procedure TForm1.Button1Click(Sender: TObject);
begin
  ShowGenericMessage('Вы уверены, что хотите удалить этот элемент?', 
                   MB_ICONQUESTION or MB_YESNO,
                   procedure(Result: TModalResult)
                   begin
                     if Result = mrYes then
                       DeleteItem;
                   end);
end;

Альтернативное решение с синхронным поведением на Windows

Если вам необходимо поддерживать синхронное поведение на Windows, можно создать гибридное решение:

function ShowGenericMessageSync(const MessageText: string; Icon: Integer): TModalResult;
{$IFDEF MSWINDOWS}
var
  Event: TEvent;
{$ENDIF}
begin
  {$IFDEF MSWINDOWS}
  Event := TEvent.Create;
  try
    ShowGenericMessage(MessageText, Icon,
      procedure(AResult: TModalResult)
      begin
        Result := AResult;
        Event.SetEvent;
      end);

    Event.WaitFor(INFINITE);
  finally
    Event.Free;
  end;
  {$ELSE}
  Result := mrNone;
  ShowGenericMessage(MessageText, Icon,
    procedure(AResult: TModalResult)
    begin
      Result := AResult;
      // Обработка результата должна быть в колбэке
    end);
  {$ENDIF}
end;

Рекомендации по архитектуре приложения

  1. Разделение логики: Для мобильных платформ перестройте архитектуру приложения так, чтобы вся обработка после диалога выполнялась в колбэке.

  2. Состояния приложения: Используйте механизм состояний для управления потоком выполнения после закрытия диалога.

  3. Унификация кода: По возможности используйте одинаковый подход для всех платформ (асинхронный), это упростит поддержку кода.

Заключение

При разработке кросс-платформенных приложений важно учитывать особенности каждой платформы. Представленное решение позволяет создавать универсальные диалоговые окна, которые корректно работают на всех платформах, поддерживаемых FireMonkey. Для Windows сохраняется возможность синхронного вызова, а для мобильных платформ используется асинхронный подход с колбэками.

Использование такой архитектуры не только решает проблему блокировки основного потока на мобильных устройствах, но и способствует созданию более чистого и поддерживаемого кода.

Создано по материалам из источника по ссылке.

Этот код предоставляет универсальную функцию для отображения диалоговых окон в Delphi FMX, учитывающую особенности мобильных платформ и обеспечивающую асинхронное выполнение для предотвращения блокировки основного потока.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Диалоги и Фреймы ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-05-01 10:09:21/0.0054969787597656/1