Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: TNotifyList ?  (Прочитано 8183 раз)
0 Пользователей и 2 Гостей смотрят эту тему.
Temych1980
Гость
« : 13-04-2005 12:22 » 

Здравствуйте,
есть такая проблема.

Надо завязать между собой несколько компонентов: один является источником события (надо сигнализировать о некоторого рода изменениях в состоянии компонента), другие должны его отлавливать и обрабатывать.
Как я понял, TNotifyEvent сюда не подойдет, так как он уместен только в случае наличия одного "заинтересованного" компонента.

Нашел в хелпе упоминание о TNotifyList, но оно всего лишь упомнинание, реальной помощи от него нет.

Заранее спасибо.
Записан
Allex63
Участник

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 14-04-2005 14:19 » 

Я бы попробовал так (В предположении, что все компоненты "свои"):
 MyMessage:=RegisterWindowsMessage(Мое личное сообщение)

У компонента - "оповещателя" - SendMessage($FFFFFFFF,MyMessage,....)
 (или SendMessage(HWND_BROADCAST,MyMessage,....)) если обмен в пределах одного приложения)

У компонентов - "приемников" в WindowProc реализовать нужные реакции.

Записан

Мысли должны быть короткие и плоские.
Так их в ROM больше помещается.
Melquiades
Гость
« Ответ #2 : 15-04-2005 12:42 » 

Можно сделать что-нибудь в таком духе:

Код:
type
  TEventRetranslator = class(TComponent)
  private
    FEventHandlers: array of TNotifyEvent;
  public
    procedure Handler(Sender: TObject);
    procedure Add(AHandler: TNotifyEvent);
    //procedure Remove(AHandler: TNotifyEvent);
  end;

implementation

procedure TEventRetranslator.Handler(Sender: TObject);
var i: Integer;
begin
  for i := 0 to Length(FEventHandlers)-1 do
    FEventHandlers[i](Sender);
end;

procedure TEventRetranslator.Add(AHandler: TNotifyEvent);
begin
  // проверить на дубликаты
  SetLength(FEventHandlers, Length(FEventHandlers)+1);
  FEventHandlers[ Length(FEventHandlers)-1 ] := AHandler;
end;


//---------------использование----------

var ret: TEventRetranslator;

ret := TEventRetranslator.Create(self);
// я сделал его компонентом лишь для того, чтобы не нужно было беспокоиться об его удалении
X.OnSomeEvent := ret.Handler;

ret.Add(Y.SomeMethod);
ret.Add(Z.OtherMethod);
« Последнее редактирование: 03-12-2007 19:05 от Алексей1153++ » Записан
x77
Модератор

ro
Offline Offline
Пол: Мужской
меняю стакан шмали на обратный билет с Марса.


« Ответ #3 : 29-04-2005 17:52 » 

не надо изобретать велосипед, посмотри как работают db-aware компоненты. регистрируется класс TDataLink, который и отвечает за все изменения в исходном НД, оповещая о них многочисленные TDBEdit'ы, гриды и пр.
« Последнее редактирование: 20-12-2007 19:04 от Алексей1153++ » Записан

Temych1980
Гость
« Ответ #4 : 11-05-2005 05:38 » 

Я и не изобретаю. Просто с БД надо работать через свой (читай - только ее, специфический) интерфейс, а не через всякие ОДБЦ и проч. Поэтому приходится писать свои компоненты полностью.
Записан
x77
Модератор

ro
Offline Offline
Пол: Мужской
меняю стакан шмали на обратный билет с Марса.


« Ответ #5 : 15-05-2005 11:36 » new

правильно. я же не говорю, что надо их юзать просто откройте модуль DB.PAS и посмотрите, как организовано взаимодействие TTable c TDataSource через класс TDataLink. вот простой пример, объявление класса TDataSource:

Код:
  TDataSource = class(TComponent)
  private
    FDataSet: TDataSet;
    FDataLinks: TList;
    FEnabled: Boolean;
    FAutoEdit: Boolean;
    FState: TDataSetState;
    FOnStateChange: TNotifyEvent;
    FOnDataChange: TDataChangeEvent;
    FOnUpdateData: TNotifyEvent;
    procedure AddDataLink(DataLink: TDataLink);
    procedure DataEvent(Event: TDataEvent; Info: Longint);
    procedure NotifyDataLinks(Event: TDataEvent; Info: Longint);
    procedure NotifyLinkTypes(Event: TDataEvent; Info: Longint; LinkType: Boolean);
    procedure RemoveDataLink(DataLink: TDataLink);
    procedure SetDataSet(ADataSet: TDataSet);
    procedure SetEnabled(Value: Boolean);
    procedure SetState(Value: TDataSetState);
    procedure UpdateState;
  protected
    property DataLinks: TList read FDataLinks;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure Edit;
    function IsLinkedTo(DataSet: TDataSet): Boolean;
    property State: TDataSetState read FState;
  published
    property AutoEdit: Boolean read FAutoEdit write FAutoEdit default True;
    property DataSet: TDataSet read FDataSet write SetDataSet;
    property Enabled: Boolean read FEnabled write SetEnabled default True;
    property OnStateChange: TNotifyEvent read FOnStateChange write FOnStateChange;
    property OnDataChange: TDataChangeEvent read FOnDataChange write FOnDataChange;
    property OnUpdateData: TNotifyEvent read FOnUpdateData write FOnUpdateData;
  end;

т.е. у одного компонента TTable может быть несколько связанных с ним компонентов TDataSource,и все они будут "знать", об изменении состояния TTable. схожим образом организуется взаимодействие между db-aware контролами и источником данных, только там в качестве связующего класса используется класс TFieldDataLink. но принцип - тот же.
Записан

Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines