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

Уведомление всех открытых MDI форм в Delphi

Delphi , Программа и Интерфейс , Размеры и Положение

Как уведомить изменение между различными формами в Delphi?

Разработка на Delphi часто требует взаимодействия между разными пользовательскими интерфейсами, включая MDI (Multiple Document Interface) формы. Ситуации возникают, когда необходимо уведомлять другие открытые формы о каких-либо изменениях в одной из форм. Рассмотрим несколько подходов к решению этой задачи.

Использование собственных событий

Простейший способ – определить событие, которое передаёт необходимые данные об изменении. Форма, которая изменилась, производит вызов этого события, а форма, которой необходимо уведомление, реализует обработчик этого события. В методе OnCreate формы-инициатора можно назначить этот обработчик для формы-получателя.

type
  TFormChangeEvent = procedure(Sender: TObject; const AData: string); of object;

procedure TForm1.Form1Create(Sender: TObject);
begin
  // Предполагаем, что Form2 уже существует и мы хотим уведомить её об изменениях
  TForm2(Form2Handle).OnFormChange := @Form1OnDataChanged;
end;

procedure TForm1.Form1NotifyChange(const AData: string);
begin
  // Вызывается при изменении данных, например
  OnFormChange(Sender, 'Изменённые данные');
end;

procedure TForm1.Form1OnDataChanged(Sender: TObject; const AData: string);
begin
  // Обработка уведомления в Form2
end;

Применение паттерна "Наблюдатель" (Observer)

Этот шаблон проектирования позволяет объектам (называемым наблюдателями) подписываться на события объектов (называемых субъектами). Когда состояние субъекта изменяется, он автоматически уведомляет всех своих подписантов.

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

type
  TObserver = interface(IInterface)
    ['{01234567-89AB-CDEF-0123-456789ABCDEF}']
    procedure Update;
  end;

TForm1 = class(TForm, TSubject)
private
  FObservers: TList<TObserver>;
  // Остальной код формы
protected
  function GetObserverCount: Integer; virtual;
public
  constructor Create(AOwner: TComponent); override;
  destructor Destroy; override;
  procedure Attach(AnObserver: TObserver);
  procedure Detach(AnObserver: TObserver);
  procedure NotifyObservers;
end;

TForm1 = class helper for TForm1
public
  class function RegisterFormChangeSubject(aForm: TForm): Boolean; static; // Регистрация формы как субъекта для MDI
end;

constructor TForm1.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  RegisterFormChangeSubject(Self);
end;

procedure TForm1.Attach(AnObserver: TObserver);
begin
  FObservers := TList<TObserver>.Create(True);
  try
    FObservers.Add(AnObserver);
  except
    on E: Exception do
      // Обработка исключений, если необходимо
  end;
end;

procedure TForm1.Detach(AnObserver: TObserver);
var
  ObserverList: TList<TObserver>;
begin
  ObserverList := FObservers;
  if ObserverList <> nil then
    try
      ObserverList.Remove(AnObserver);
    finally
      ObserverList.Free;
    end;
end;

procedure TForm1.NotifyObservers;
var
  Observer: TObserver;
begin
  ObserverList := FObservers;
  if ObserverList <> nil then
  begin
    for Observer in ObserverList do
      Observer.Update;
  end;
end;

TObserver = class helper for TForm2 // Предположим, что это другая форма
public
  procedure Update; override;
end;

procedure TForm2.Update;
begin
  // Действия при обновлении
end;

// При изменении данных вызываем метод уведомления наблюдателей
procedure TForm1.FormDataChanged;
begin
  NotifyObservers;
end;

class function TForm1.RegisterFormChangeSubject(aForm: TForm): Boolean; static;
var
  MdiClient: TMdiClient;
begin
  Result := False;
  if aForm is TMdiChild then
    begin
      with TMdiChild(aForm) do
      begin
        MdiClient := Owner as TMdiClient;
        if Assigned(MdiClient) and (MdiClient.ActiveMDIChild = Self) then
          if not MdiClient.OnMDIActivate then
            MdiClient.OnMDIActivate := TNotifyEvent(@RegisterSubjects);
      end;
    end;

  Result := True;
end;

// Процедура для регистрации субъектов в клиенте MDI при активации формы
procedure RegisterSubjects(Sender: TObject; var Active: Boolean);
var
  MdiChild: TMdiChild;
begin
  if not Active then
    Exit;

  for MdiChild in Sender.Components do
    if (MdiChild is TMdiChild) and (not TForm1(MdiChild).IsSubjectRegistered) then
      TForm1(MdiChild).RegisterAsSubject;
end;

Использование оконных сообщений

В Delphi можно использовать оконные сообщения для уведомления форм. Однако стоит помнить, что механизмы оконных сообщений в Windows, Linux и macOS различаются.

Пример использования оконного сообщения на Windows:

const
  WM_FORM_CHANGED = WM_USER + 10;

procedure TForm1.FormDataChanged;
begin
  // Предполагаем, что у нас есть форма Form2 с идентификатором окна Form2Handle
  SendMessage(Form2Handle, WM_FORM_CHANGED, 0, 0);
end;

procedure TForm2.WMFormChanged(var Msg: TMessage);
begin
  // Обработка сообщения о том, что данные в Form1 изменились
  inherited;
end;

Для кроссплатформенных решений можно использовать специальные библиотеки или фреймворки, такие как LCLIntf и LMessages.

Выводы

Выбор метода зависит от конкретной задачи и требований проекта. Важно учитывать кросс-платформенность, если приложение должно работать на разных операционных системах. Паттерн "Наблюдатель" является универсальным решением, но может быть избыточным для простых задач. Оконные сообщения могут быть удобным способом взаимодействия между формами, но требуют более внимательного подхода при кросс-платформенной разработке.

Надеюсь, предоставленная информация поможет вам найти оптимальное решение для вашего проекта!

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

Вопрос касается методов уведомления различных форм в среде разработки Delphi о изменениях, происходящих в одной из форм, включая использование собственных событий, паттерна 'Наблюдатель' и оконных сообщений.


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

Получайте свежие новости и обновления по 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 13:56:42/0.0053310394287109/1