Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
 Уведомление формы о событии в других модулях  [new]
derwesh
Member

Откуда:
Сообщений: 4
Здравствуйте. Опишу сначала ситуацию. Имеется приложение (Delphi XE8) с главной формой Form1 и DataModule, также могут быть другие формы, которые обращаются к DataModule.
В DataModule находится компонент TFDConnection. Хочу реализовать отображение состояния TFDConnection на Form1. Прямое решение - мониторить состояние через таймер на Form1 мне кажется не очень верным, как и прямое обращение из DataModule в Form1.
Из того что нагуглил: можно использовать Events и API.Messages. Т.е. при изменении состояния TFDConnection, код в DataModule вызывает своё TMessage (Events) а код в Form1 отлавливает его, проверяет состояние TFDConnection и отображает в своих компонентах состояние подключения.
Можете посоветовать какой метод удобнее в данной ситуации и простенький примерчик или литературу?
P.S. Извините, если вышло немного сумбурно.
9 май 19, 19:20    [21881857]     Ответить | Цитировать Сообщить модератору
 Re: Уведомление формы о событии в других модулях  [new]
DesWind
Member

Откуда:
Сообщений: 106
derwesh,

Ну и отправь сообщение Form1
9 май 19, 19:25    [21881862]     Ответить | Цитировать Сообщить модератору
 Re: Уведомление формы о событии в других модулях  [new]
DesWind
Member

Откуда:
Сообщений: 106
DesWind,

RgisterMessage
Post|Sendmessge
If Messge=
9 май 19, 19:28    [21881865]     Ответить | Цитировать Сообщить модератору
 Re: Уведомление формы о событии в других модулях  [new]
derwesh
Member

Откуда:
Сообщений: 4
DesWind, т.е. в данном случае удобнее использовать TMessages? Как-то так: PostMessage(Screen.Forms[0].Handle, ...); Это то, что нарыл.
9 май 19, 19:31    [21881867]     Ответить | Цитировать Сообщить модератору
 Re: Уведомление формы о событии в других модулях  [new]
DesWind
Member

Откуда:
Сообщений: 106
derwesh,

Нет, это надо открывать WIN API
9 май 19, 19:32    [21881869]     Ответить | Цитировать Сообщить модератору
 Re: Уведомление формы о событии в других модулях  [new]
derwesh
Member

Откуда:
Сообщений: 4
DesWind, это имеете ввиду?
var
  FM_FINDPHOTO: Integer;

  // Для того, чтобы использовать hwnd_Broadcast нужно
  // сперва зарегистрировать уникальное сообщение.

initialization
  FM_FindPhoto := RegisterWindowMessage('MyMessageToAll');

  // Чтобы поймать это сообщение в другом приложении
  // (приемнике) нужно перекрыть DefaultHandler

procedure TForm1.DefaultHandler(var Message);
begin
  with TMessage(Message) do
  begin
    if Msg = Fm_FindPhoto then
      MyHandler(WPARAM, LPARAM)
    else
      inherited DefaultHandler(Message);
  end;
end;

// А теперь можно в приложении-передатчике
SendMessage(HWND_BROADCAST, FM_FINDPHOTO, 0, 0);

Насколько я понял это сообщение всем программам в системе, наверное так и придётся делать, а есть ли возможность делать то-же в пределах одного приложения?
9 май 19, 19:39    [21881873]     Ответить | Цитировать Сообщить модератору
 Re: Уведомление формы о событии в других модулях  [new]
X-Cite
Member

Откуда: Минск
Сообщений: 1434
Это называется шаблон "Наблюдатель"

Датамодуль Наблюдаемый он же observable
Остальные формы модули Наблюдатели они же observer

Получаем слабую связанность и удобное быстрое добавление наблюдателей

https://refactoring.guru/ru/design-patterns/observer
9 май 19, 19:43    [21881874]     Ответить | Цитировать Сообщить модератору
 Re: Уведомление формы о событии в других модулях  [new]
DesWind
Member

Откуда:
Сообщений: 106
DesWind,
Для одного приложения у формы есть WndProc, которую достаточно перекрыть
9 май 19, 20:42    [21881902]     Ответить | Цитировать Сообщить модератору
 Re: Уведомление формы о событии в других модулях  [new]
DesWind
Member

Откуда:
Сообщений: 106
DesWind,

Только для начала, надо разобраться в различии Send|Post
9 май 19, 20:53    [21881908]     Ответить | Цитировать Сообщить модератору
 Re: Уведомление формы о событии в других модулях  [new]
derwesh
Member

Откуда:
Сообщений: 4
DesWind, спасибо, буду рыть в этом направлении.
9 май 19, 21:36    [21881924]     Ответить | Цитировать Сообщить модератору
 Re: Уведомление формы о событии в других модулях  [new]
Vlad F
Member

Откуда:
Сообщений: 815
derwesh,

И посылай в параметрах сообщения сразу нужное состояние соединения, чтобы в форме уже не нужно было опрашивать датамодуль.
9 май 19, 22:58    [21881944]     Ответить | Цитировать Сообщить модератору
 Re: Уведомление формы о событии в других модулях  [new]
DimaBr
Member

Откуда:
Сообщений: 11128
const
  WM_MyConnect = WM_USER + 1;

TForm1 = class(TForm)

  procedure WMMyConnect(var Message: TMessage); message WM_MyConnect;
end;


procedure TDataModule.DoAfterConnect(Sender: TObject);
var i: integer;
begin
  for i := 0 to Screen.FormCount-1 do
    Screen.Forms[i].Perform(WM_MyConnect, integer(FDConnection1.Connected),0);
end;
10 май 19, 01:58    [21881976]     Ответить | Цитировать Сообщить модератору
 Re: Уведомление формы о событии в других модулях  [new]
Василий 2
Member

Откуда:
Сообщений: 605
DataModule.Connection.OnConnect := Form1.ConnectionConnect ?
13 май 19, 16:08    [21883545]     Ответить | Цитировать Сообщить модератору
 Re: Уведомление формы о событии в других модулях  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 10998
type
  TOnConnect = procedure(ASender: TObject; AConnect: Boolean) of object;

  TMyDataModule = class(TDataModule)
    ..........
  strict private
    FOnConnect: TOnConnect;
    procedure DoConnectChange(AConnect: Boolean);
  public
    property OnConnect: TOnConnect read FOnConnect write FOnConnect;
  end;

procedure TMyDataModule.DoConnectChange(AConnect: Boolean);
begin
  if Assigned(FOnConnect)
    FOnConnect(Self, AConnect);
end;

.................

procedure TMyForm.FormCreate(Sender: TObject);
begin
  ..........
  MyDataModule.OnConnect = DoConnect;
  ..........
end;

procedure TMyForm.FormDestroy(Sender: TObject);
begin
  ..........
  MyDataModule.OnConnect = nil;
  ..........
end;

procedure TMyForm.DoConnect(ASender: TObject; AConnect: Boolean);
begin
  ..........
end;
13 май 19, 17:19    [21883608]     Ответить | Цитировать Сообщить модератору
 Re: Уведомление формы о событии в других модулях  [new]
DimaBr
Member

Откуда:
Сообщений: 11128
_Vasilisk_
procedure TMyForm.FormCreate(Sender: TObject);
begin
  ..........
  MyDataModule.OnConnect = DoConnect;
  ..........
end;

Так будет уведомление лишь одной формы
13 май 19, 21:45    [21883818]     Ответить | Цитировать Сообщить модератору
 Re: Уведомление формы о событии в других модулях  [new]
энди
Member

Откуда: Киров, Россия
Сообщений: 983
ну по уму конечно надо реализовывать схему паблишер-сабскрайбер, варианты реализации могут быть просто различны, начиная от банального наследника листа в который занести формы подписчики, а потом при возникновении события по листу дернуть у всех форм что нужно.
Ну или смотреть в сторону mvc, биндингов и прочего
14 май 19, 10:12    [21884093]     Ответить | Цитировать Сообщить модератору
 Re: Уведомление формы о событии в других модулях  [new]
alekcvp
Member

Откуда:
Сообщений: 1417
энди,

Зачем городить велосипед, если вариант с перебором форм выше прекрасно будет работать?
Единственное, я бы заменил .Perform() на PostNotifyMessage().
14 май 19, 10:42    [21884125]     Ответить | Цитировать Сообщить модератору
 Re: Уведомление формы о событии в других модулях  [new]
Василий 2
Member

Откуда:
Сообщений: 605
DimaBr
Так будет уведомление лишь одной формы

ТС и не просил большего.
Если нужно уведомлять несколько получателей, то можно создать класс-список хэндлеров и повесить на Datamodule.OnConnect метод объекта этого класса. В самом объекте уже реализовать добавление/удаление хэндлера и вызов хэндлеров по списку. В этом случае сам Datamodule никак не будет затронут, а формы будут подписываться на события через объект-мультихэндлер. Только надо не забыть либо подписать объект на удаление формы, либо из формы на FormClose удалять свой метод из списка.
14 май 19, 10:42    [21884126]     Ответить | Цитировать Сообщить модератору
 Re: Уведомление формы о событии в других модулях  [new]
Василий 2
Member

Откуда:
Сообщений: 605
Вариант с сообщениями безопасней в том плане, что при удалении формы ничего страшного не случится, просто сообщение будет послано невалидному хэндлу. Зато сообщения завязаны на gui и winAPI, а добавить хэндлер можно от любого объекта, будь то другой датамодуль или вообще поток.
14 май 19, 10:50    [21884134]     Ответить | Цитировать Сообщить модератору
Все форумы / Delphi Ответить